DPDK patches and discussions
 help / color / mirror / Atom feed
From: Marcin Kerlin <marcinx.kerlin@intel.com>
To: dev@dpdk.org
Cc: pablo.de.lara.guarch@intel.com, thomas.monjalon@6wind.com,
	Marcin Kerlin <marcinx.kerlin@intel.com>
Subject: [dpdk-dev] [PATCH v5 1/2] librte_ether: add protection against overwrite device data
Date: Fri, 30 Sep 2016 16:00:54 +0200	[thread overview]
Message-ID: <1475244055-6309-2-git-send-email-marcinx.kerlin@intel.com> (raw)
In-Reply-To: <1475244055-6309-1-git-send-email-marcinx.kerlin@intel.com>

Added protection against overwrite device data in array rte_eth_dev_data[]
for the next secondary applications. Secondary process appends in the
first free place rather than at the beginning. This behavior prevents
overwriting devices data of primary process by secondary process.

Signed-off-by: Marcin Kerlin <marcinx.kerlin@intel.com>
---
 lib/librte_ether/rte_ethdev.c          | 89 +++++++++++++++++++++++++++++++---
 lib/librte_ether/rte_ethdev.h          | 12 +++++
 lib/librte_ether/rte_ether_version.map |  6 +++
 3 files changed, 100 insertions(+), 7 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 382c959..89a382c 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -176,6 +176,19 @@ rte_eth_dev_allocated(const char *name)
 	return NULL;
 }
 
+static struct rte_eth_dev_data *
+rte_eth_dev_get_dev_data_by_name(const char *name)
+{
+	unsigned int i;
+
+	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
+		if (strcmp(rte_eth_dev_data[i].name, name) == 0)
+			return &rte_eth_dev_data[i];
+	}
+
+	return NULL;
+}
+
 static uint8_t
 rte_eth_dev_find_free_port(void)
 {
@@ -188,10 +201,43 @@ rte_eth_dev_find_free_port(void)
 	return RTE_MAX_ETHPORTS;
 }
 
+static uint8_t
+rte_eth_dev_find_free_dev_data_id(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
+		if (!strlen(rte_eth_dev_data[i].name))
+			return i;
+	}
+	return RTE_MAX_ETHPORTS;
+}
+
+int
+rte_eth_dev_release_dev_data(uint8_t port_id)
+{
+	char device[RTE_ETH_NAME_MAX_LEN];
+	struct rte_eth_dev_data *eth_dev_data = NULL;
+
+	/* get device name by port id */
+	if (rte_eth_dev_get_name_by_port(port_id, device))
+		return -EINVAL;
+
+	/* look for an entry in the device data */
+	eth_dev_data = rte_eth_dev_get_dev_data_by_name(device);
+	if (eth_dev_data == NULL)
+		return -EINVAL;
+
+	/* clear an entry in the device data */
+	memset(eth_dev_data, 0, sizeof(struct rte_eth_dev_data));
+
+	return 0;
+}
+
 struct rte_eth_dev *
 rte_eth_dev_allocate(const char *name, enum rte_eth_dev_type type)
 {
-	uint8_t port_id;
+	uint8_t port_id, dev_data_id;
 	struct rte_eth_dev *eth_dev;
 
 	port_id = rte_eth_dev_find_free_port();
@@ -203,17 +249,35 @@ rte_eth_dev_allocate(const char *name, enum rte_eth_dev_type type)
 	if (rte_eth_dev_data == NULL)
 		rte_eth_dev_data_alloc();
 
+	do {
+		dev_data_id = rte_eth_dev_find_free_dev_data_id();
+	} while (!rte_spinlock_trylock(&rte_eth_dev_data[dev_data_id].lock)
+			&& dev_data_id < RTE_MAX_ETHPORTS);
+
+	if (dev_data_id == RTE_MAX_ETHPORTS) {
+		RTE_PMD_DEBUG_TRACE("Reached maximum number of Ethernet ports "
+				"by all the processes\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;
 	}
 
+	if (rte_eth_dev_get_dev_data_by_name(name) != NULL) {
+		RTE_PMD_DEBUG_TRACE("Ethernet Device with name %s already "
+				"allocated by another process!\n", name);
+		return NULL;
+	}
+
 	eth_dev = &rte_eth_devices[port_id];
-	eth_dev->data = &rte_eth_dev_data[port_id];
+	eth_dev->data = &rte_eth_dev_data[dev_data_id];
 	snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name);
 	eth_dev->data->port_id = port_id;
 	eth_dev->attached = DEV_ATTACHED;
+	rte_spinlock_unlock(&eth_dev->data->lock);
 	eth_dev->dev_type = type;
 	nb_ports++;
 	return eth_dev;
@@ -417,9 +481,7 @@ rte_eth_dev_get_name_by_port(uint8_t port_id, char *name)
 		return -EINVAL;
 	}
 
-	/* shouldn't check 'rte_eth_devices[i].data',
-	 * because it might be overwritten by VDEV PMD */
-	tmp = rte_eth_dev_data[port_id].name;
+	tmp = rte_eth_devices[port_id].data->name;
 	strcpy(name, tmp);
 	return 0;
 }
@@ -439,8 +501,7 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id)
 	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
 
 		if (!strncmp(name,
-			rte_eth_dev_data[i].name, strlen(name))) {
-
+			rte_eth_devices[i].data->name, strlen(name))) {
 			*port_id = i;
 
 			return 0;
@@ -631,6 +692,8 @@ int
 rte_eth_dev_detach(uint8_t port_id, char *name)
 {
 	struct rte_pci_addr addr;
+	struct rte_eth_dev_data *eth_dev_data = NULL;
+	char device[RTE_ETH_NAME_MAX_LEN];
 	int ret = -1;
 
 	if (name == NULL) {
@@ -642,6 +705,15 @@ rte_eth_dev_detach(uint8_t port_id, char *name)
 	if (rte_eth_dev_is_detachable(port_id))
 		goto err;
 
+	/* get device name by port id */
+	if (rte_eth_dev_get_name_by_port(port_id, device))
+		goto err;
+
+	/* look for an entry in the shared device data */
+	eth_dev_data = rte_eth_dev_get_dev_data_by_name(device);
+	if (eth_dev_data == NULL)
+		goto err;
+
 	if (rte_eth_dev_get_device_type(port_id) == RTE_ETH_DEV_PCI) {
 		ret = rte_eth_dev_get_addr_by_port(port_id, &addr);
 		if (ret < 0)
@@ -661,6 +733,9 @@ rte_eth_dev_detach(uint8_t port_id, char *name)
 			goto err;
 	}
 
+	/* clear an entry in the shared device data */
+	memset(eth_dev_data, 0, sizeof(struct rte_eth_dev_data));
+
 	return 0;
 
 err:
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 96575e8..ae22469 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1708,6 +1708,7 @@ struct rte_eth_dev_data {
 	enum rte_kernel_driver kdrv;    /**< Kernel driver passthrough */
 	int numa_node;  /**< NUMA node connection */
 	const char *drv_name;   /**< Driver name */
+	rte_spinlock_t lock; /** Lock on allocate eth device */
 };
 
 /** Device supports hotplug detach */
@@ -1752,6 +1753,17 @@ struct rte_eth_dev *rte_eth_dev_allocated(const char *name);
 
 /**
  * @internal
+ * Release device data kept in shared memory for all processes.
+ *
+ * @param	port_id
+ *   The port identifier of the device to release device data.
+ * @return
+ *   - 0 on success, negative on error
+ */
+int rte_eth_dev_release_dev_data(uint8_t port_id);
+
+/**
+ * @internal
  * Allocates a new ethdev slot for an ethernet device and returns the pointer
  * to that slot for the driver to use.
  *
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index 45ddf44..c98ecd4 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -139,3 +139,9 @@ DPDK_16.07 {
 	rte_eth_dev_get_port_by_name;
 	rte_eth_xstats_get_names;
 } DPDK_16.04;
+
+DPDK_16.11 {
+	global:
+
+	rte_eth_dev_release_dev_data;
+} DPDK_16.07;
-- 
1.9.1

  reply	other threads:[~2016-09-30 14:09 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-02  8:58 [dpdk-dev] [PATCH 0/2] app/testpmd: improve multiprocess support Marcin Kerlin
2016-09-02  8:58 ` [dpdk-dev] [PATCH 1/2] librte_ether: ensure not overwrite device data in mp app Marcin Kerlin
2016-09-11 12:23   ` Yuanhan Liu
2016-09-20 14:06   ` [dpdk-dev] [PATCH v2 0/2] app/testpmd: improve multiprocess support Marcin Kerlin
2016-09-20 14:31   ` Marcin Kerlin
2016-09-20 14:31     ` [dpdk-dev] [PATCH v2 1/2] librte_ether: ensure not overwrite device data in mp app Marcin Kerlin
2016-09-20 16:14       ` Pattan, Reshma
2016-09-22 14:11         ` Kerlin, MarcinX
2016-09-23 14:12           ` Thomas Monjalon
2016-09-26 15:07             ` Kerlin, MarcinX
2016-09-20 16:48       ` Pattan, Reshma
2016-09-22 14:21         ` Kerlin, MarcinX
2016-09-26 14:53       ` [dpdk-dev] [PATCH v3 0/2] app/testpmd: improve multiprocess support Marcin Kerlin
2016-09-26 14:53         ` [dpdk-dev] [PATCH v3 1/2] librte_ether: ensure not overwrite device data in mp app Marcin Kerlin
2016-09-27  3:06           ` Yuanhan Liu
2016-09-27 10:01             ` Kerlin, MarcinX
2016-09-27 10:29           ` [dpdk-dev] [PATCH v4 0/2] app/testpmd: improve multiprocess support Marcin Kerlin
2016-09-27 11:13           ` Marcin Kerlin
2016-09-27 11:13             ` [dpdk-dev] [PATCH v4 1/2] librte_ether: add protection against overwrite device data Marcin Kerlin
2016-09-28 11:00               ` Pattan, Reshma
2016-09-28 14:03               ` Pattan, Reshma
2016-09-29 13:41                 ` Kerlin, MarcinX
2016-09-30 14:00               ` [dpdk-dev] [PATCH v5 0/2] app/testpmd: improve multiprocess support Marcin Kerlin
2016-09-30 14:00                 ` Marcin Kerlin [this message]
2016-09-30 15:00                   ` [dpdk-dev] [PATCH v5 1/2] librte_ether: add protection against overwrite device data Pattan, Reshma
2016-10-06  9:41                   ` Thomas Monjalon
2016-10-06 13:57                     ` Kerlin, MarcinX
2016-10-06 14:20                       ` Thomas Monjalon
2016-10-06 14:52                   ` Thomas Monjalon
2016-10-07 12:23                     ` Kerlin, MarcinX
2016-10-11  8:52                       ` Thomas Monjalon
2016-09-30 14:24                 ` [dpdk-dev] [PATCH v5 2/2] app/testpmd: improve handling of multiprocess Marcin Kerlin
2016-09-30 15:02                   ` Pattan, Reshma
2016-09-30 15:03                 ` [dpdk-dev] [PATCH v5 0/2] app/testpmd: improve multiprocess support Pattan, Reshma
2016-10-18  7:57                 ` Sergio Gonzalez Monroy
2016-09-27 11:13             ` [dpdk-dev] [PATCH v4 2/2] app/testpmd: improve handling of multiprocess Marcin Kerlin
2016-09-28 10:57               ` Pattan, Reshma
2016-09-28 11:34                 ` Kerlin, MarcinX
2016-09-28 12:08                   ` Pattan, Reshma
2016-09-26 14:53         ` [dpdk-dev] [PATCH v3 " Marcin Kerlin
2016-09-20 14:31     ` [dpdk-dev] [PATCH v2 " Marcin Kerlin
2016-09-02  8:58 ` [dpdk-dev] [PATCH " Marcin Kerlin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1475244055-6309-2-git-send-email-marcinx.kerlin@intel.com \
    --to=marcinx.kerlin@intel.com \
    --cc=dev@dpdk.org \
    --cc=pablo.de.lara.guarch@intel.com \
    --cc=thomas.monjalon@6wind.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).