From patchwork Thu Mar 8 02:46:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "John Daley (johndale)" X-Patchwork-Id: 35771 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 729C55F71; Thu, 8 Mar 2018 03:50:24 +0100 (CET) Received: from alln-iport-4.cisco.com (alln-iport-4.cisco.com [173.37.142.91]) by dpdk.org (Postfix) with ESMTP id 228735F5D; Thu, 8 Mar 2018 03:50:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=4082; q=dns/txt; s=iport; t=1520477423; x=1521687023; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=h7wD9SburSF6IgnIo23z+CxNiVeikeu82N6YP0gKzGc=; b=NzLKiJ1w62QktL9OmoltQWOESoSMtZLLTRJUh6MM/8KHInHys5Unzqav 63KeYO5qw1+dy/BgbEwgG8AuPln7Hk4u7pb2Lbl6RH35MwVfi7XVJ2PgT 6Gf/KGvjn7W45BQZZbYVasongkXZZKZQvPFF4ZJamrCq816mDPeTWYzo3 A=; X-IronPort-AV: E=Sophos;i="5.47,438,1515456000"; d="scan'208";a="80882433" Received: from rcdn-core-7.cisco.com ([173.37.93.143]) by alln-iport-4.cisco.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Mar 2018 02:50:22 +0000 Received: from cisco.com (savbu-usnic-a.cisco.com [10.193.184.48]) by rcdn-core-7.cisco.com (8.14.5/8.14.5) with ESMTP id w282oLOs014172; Thu, 8 Mar 2018 02:50:22 GMT Received: by cisco.com (Postfix, from userid 392789) id C031020F2001; Wed, 7 Mar 2018 18:50:21 -0800 (PST) From: John Daley To: ferruh.yigit@intel.com Cc: dev@dpdk.org, Hyong Youb Kim , stable@dpdk.org Date: Wed, 7 Mar 2018 18:46:58 -0800 Message-Id: <20180308024702.25974-7-johndale@cisco.com> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180308024702.25974-1-johndale@cisco.com> References: <20180306014634.28398-2-johndale@cisco.com> <20180308024702.25974-1-johndale@cisco.com> Subject: [dpdk-dev] [PATCH v3 06/10] net/enic: allocate stats DMA buffer upfront during probe X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Hyong Youb Kim The driver provides a DMA buffer to the firmware when it requests port stats. The NIC then fills that buffer with latest stats. Currently, the driver allocates the DMA buffer the first time it requests stats and saves it for later use. This can lead to crashes when primary/secondary processes are involved. For example, the following sequence crashes the secondary process. 1. Start a primary app that does not call rte_eth_stats_get() 2. dpdk-procinfo -- --stats dpdk-procinfo crashes while trying to allocate the stats DMA buffer because the alloc function pointer (vdev.alloc_consistent) is valid only in the primary process, not in the secondary process. Overwriting the alloc function pointer in the secondary process is not an option, as it will simply make the pointer invalid in the primary process. Instead, allocate the DMA buffer during probe so that only the primary process does both allocate and free. This allows the secondary process to dump stats as well. Cc: stable@dpdk.org Fixes: 9913fbb91df0 ("enic/base: common code") Signed-off-by: Hyong Youb Kim Reviewed-by: John Daley --- drivers/net/enic/base/vnic_dev.c | 24 ++++++++++++++---------- drivers/net/enic/base/vnic_dev.h | 1 + drivers/net/enic/enic_main.c | 9 +++++++++ 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/drivers/net/enic/base/vnic_dev.c b/drivers/net/enic/base/vnic_dev.c index 05b595eb8..1f8d222fc 100644 --- a/drivers/net/enic/base/vnic_dev.c +++ b/drivers/net/enic/base/vnic_dev.c @@ -587,17 +587,9 @@ int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats) { u64 a0, a1; int wait = 1000; - static u32 instance; - char name[NAME_MAX]; - if (!vdev->stats) { - snprintf((char *)name, sizeof(name), - "vnic_stats-%u", instance++); - vdev->stats = vdev->alloc_consistent(vdev->priv, - sizeof(struct vnic_stats), &vdev->stats_pa, (u8 *)name); - if (!vdev->stats) - return -ENOMEM; - } + if (!vdev->stats) + return -ENOMEM; *stats = vdev->stats; a0 = vdev->stats_pa; @@ -922,6 +914,18 @@ u32 vnic_dev_get_intr_coal_timer_max(struct vnic_dev *vdev) return vdev->intr_coal_timer_info.max_usec; } +int vnic_dev_alloc_stats_mem(struct vnic_dev *vdev) +{ + char name[NAME_MAX]; + static u32 instance; + + snprintf((char *)name, sizeof(name), "vnic_stats-%u", instance++); + vdev->stats = vdev->alloc_consistent(vdev->priv, + sizeof(struct vnic_stats), + &vdev->stats_pa, (u8 *)name); + return vdev->stats == NULL ? -ENOMEM : 0; +} + void vnic_dev_unregister(struct vnic_dev *vdev) { if (vdev) { diff --git a/drivers/net/enic/base/vnic_dev.h b/drivers/net/enic/base/vnic_dev.h index 8c0992063..7e5736b4d 100644 --- a/drivers/net/enic/base/vnic_dev.h +++ b/drivers/net/enic/base/vnic_dev.h @@ -165,6 +165,7 @@ struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, void *priv, struct rte_pci_device *pdev, struct vnic_dev_bar *bar, unsigned int num_bars); struct rte_pci_device *vnic_dev_get_pdev(struct vnic_dev *vdev); +int vnic_dev_alloc_stats_mem(struct vnic_dev *vdev); int vnic_dev_cmd_init(struct vnic_dev *vdev, int fallback); int vnic_dev_get_size(void); int vnic_dev_int13(struct vnic_dev *vdev, u64 arg, u32 op); diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index d4f478b5e..bd4447f01 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1478,6 +1478,15 @@ int enic_probe(struct enic *enic) enic_alloc_consistent, enic_free_consistent); + /* + * Allocate the consistent memory for stats upfront so both primary and + * secondary processes can dump stats. + */ + err = vnic_dev_alloc_stats_mem(enic->vdev); + if (err) { + dev_err(enic, "Failed to allocate cmd memory, aborting\n"); + goto err_out_unregister; + } /* Issue device open to get device in known state */ err = enic_dev_open(enic); if (err) {