ethdev: add lock to port allocation check
authorMatan Azrad <matan@mellanox.com>
Thu, 10 May 2018 23:58:32 +0000 (01:58 +0200)
committerFerruh Yigit <ferruh.yigit@intel.com>
Mon, 14 May 2018 21:31:53 +0000 (22:31 +0100)
When comparing the port name, there can be a race condition with
a thread allocating a new port and writing the name at the same time.
It can lead to match with a partial name by error.

The check of the port is now considered as a critical section
protected with locks.

This fix will be even more required for multi-process when the
port availability will rely only on the name, in a following patch.

Fixes: 84934303a17c ("ethdev: synchronize port allocation")
Cc: stable@dpdk.org
Signed-off-by: Matan Azrad <matan@mellanox.com>
Acked-by: Thomas Monjalon <thomas@monjalon.net>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
lib/librte_ethdev/rte_ethdev.c

index 3578b87..c33d51e 100644 (file)
@@ -234,8 +234,8 @@ is_allocated(const struct rte_eth_dev *ethdev)
        return ethdev->data->name[0] != '\0';
 }
 
-struct rte_eth_dev *
-rte_eth_dev_allocated(const char *name)
+static struct rte_eth_dev *
+_rte_eth_dev_allocated(const char *name)
 {
        unsigned i;
 
@@ -247,6 +247,22 @@ rte_eth_dev_allocated(const char *name)
        return NULL;
 }
 
+struct rte_eth_dev *
+rte_eth_dev_allocated(const char *name)
+{
+       struct rte_eth_dev *ethdev;
+
+       rte_eth_dev_shared_data_prepare();
+
+       rte_spinlock_lock(&rte_eth_dev_shared_data->ownership_lock);
+
+       ethdev = _rte_eth_dev_allocated(name);
+
+       rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock);
+
+       return ethdev;
+}
+
 static uint16_t
 rte_eth_dev_find_free_port(void)
 {
@@ -293,7 +309,7 @@ rte_eth_dev_allocate(const char *name)
                goto unlock;
        }
 
-       if (rte_eth_dev_allocated(name) != NULL) {
+       if (_rte_eth_dev_allocated(name) != NULL) {
                ethdev_log(ERR,
                        "Ethernet Device with name %s already allocated!",
                        name);