From patchwork Tue Jul 12 02:01:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Tootoonchian, Amin" X-Patchwork-Id: 14761 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 6286C2BD7; Tue, 12 Jul 2016 04:01:47 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 2116A2BBE for ; Tue, 12 Jul 2016 04:01:44 +0200 (CEST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP; 11 Jul 2016 19:01:18 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.28,349,1464678000"; d="scan'208";a="993270356" Received: from orsmsx109.amr.corp.intel.com ([10.22.240.7]) by orsmga001.jf.intel.com with ESMTP; 11 Jul 2016 19:01:17 -0700 Received: from orsmsx114.amr.corp.intel.com (10.22.240.10) by ORSMSX109.amr.corp.intel.com (10.22.240.7) with Microsoft SMTP Server (TLS) id 14.3.248.2; Mon, 11 Jul 2016 19:01:17 -0700 Received: from orsmsx109.amr.corp.intel.com ([169.254.11.206]) by ORSMSX114.amr.corp.intel.com ([169.254.8.151]) with mapi id 14.03.0248.002; Mon, 11 Jul 2016 19:01:17 -0700 From: "Tootoonchian, Amin" To: "thomas.monjalon@6wind.com" CC: "dev@dpdk.org" Thread-Topic: [PATCH] ethdev: ensure consistent port id assignment Thread-Index: AdHb4OxXvCXtsLkTSc+EWpRn1GpjVg== Date: Tue, 12 Jul 2016 02:01:17 +0000 Message-ID: <5905C8E33883CA46A8878E2D7724E21516DF5D@ORSMSX109.amr.corp.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.22.254.139] MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH] ethdev: ensure consistent port id assignment X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The rte_eth_dev_allocate() code has an implicit assumption that the port id assignment in the secondary process is consistent with that of the primary. The current code breaks if the enumeration of ethdevs in primary and secondary processes are not identical (e.g., when the black/whitelist and vdev args of the primary and secondary do not match, or when the primary dynamically adds/removes ethdevs). To fix this problem, rte_eth_dev_allocate() now looks up port id by name in a secondary process (making it explicit that ethdevs can only be created and initialized by the primary process). Upon releasing a port, the primary process zeros out eth_dev->data to avoid false positives in port id lookup by rte_eth_dev_get_port_by_name(). Signed-off-by: Amin Tootoonchian --- lib/librte_ether/rte_ethdev.c | 44 +++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index 0a6e3f1..1801f57 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -195,25 +195,37 @@ rte_eth_dev_allocate(const char *name, enum rte_eth_dev_type type) uint8_t port_id; struct rte_eth_dev *eth_dev; - port_id = rte_eth_dev_find_free_port(); - if (port_id == RTE_MAX_ETHPORTS) { - RTE_PMD_DEBUG_TRACE("Reached maximum number of Ethernet ports\n"); - return NULL; - } - if (rte_eth_dev_data == NULL) rte_eth_dev_data_alloc(); - if (rte_eth_dev_allocated(name) != NULL) { - RTE_PMD_DEBUG_TRACE("Ethernet Device with name %s already allocated!\n", - name); - return NULL; + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + port_id = rte_eth_dev_find_free_port(); + if (port_id == RTE_MAX_ETHPORTS) { + RTE_PMD_DEBUG_TRACE("Reached maximum number of Ethernet ports\n"); + return NULL; + } + + if (rte_eth_dev_allocated(name) != NULL) { + RTE_PMD_DEBUG_TRACE("Ethernet Device with name %s already allocated!\n", + name); + return NULL; + } + } else { + if (rte_eth_dev_get_port_by_name(name, &port_id) != 0) { + RTE_PMD_DEBUG_TRACE("Ethernet Device with name %s could not be found!\n", + name); + return NULL; + } } eth_dev = &rte_eth_devices[port_id]; eth_dev->data = &rte_eth_dev_data[port_id]; - snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name); - eth_dev->data->port_id = port_id; + + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name); + eth_dev->data->port_id = port_id; + } + eth_dev->attached = DEV_ATTACHED; eth_dev->dev_type = type; nb_ports++; @@ -293,8 +305,10 @@ rte_eth_dev_init(struct rte_pci_driver *pci_drv, pci_drv->name, (unsigned) pci_dev->id.vendor_id, (unsigned) pci_dev->id.device_id); - if (rte_eal_process_type() == RTE_PROC_PRIMARY) + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { rte_free(eth_dev->data->dev_private); + memset(eth_dev->data, 0, sizeof(*rte_eth_dev_data)); + } rte_eth_dev_release_port(eth_dev); return diag; } @@ -330,8 +344,10 @@ rte_eth_dev_uninit(struct rte_pci_device *pci_dev) /* free ether device */ rte_eth_dev_release_port(eth_dev); - if (rte_eal_process_type() == RTE_PROC_PRIMARY) + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { rte_free(eth_dev->data->dev_private); + memset(eth_dev->data, 0, sizeof(*rte_eth_dev_data)); + } eth_dev->pci_dev = NULL; eth_dev->driver = NULL;