If hotplug add an already plugged PCI device, it will
cause rte_pci_device->device.name be corrupted due to unexpected
rte_devargs_remove. Also if try to hotplug remove an already
unplugged device, it will cause segment fault due to unexpected
bus->unplug on a rte_device whose driver is NULL.
The patch fix these issues.

Fixes: 7e8b26650146 ("eal: fix hotplug add / remove")
Cc: sta...@dpdk.org

Signed-off-by: Qi Zhang <qi.z.zh...@intel.com>
---
 lib/librte_eal/common/eal_common_dev.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c 
b/lib/librte_eal/common/eal_common_dev.c
index 61cb3b162..0fa8c815d 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -42,18 +42,6 @@ static struct dev_event_cb_list dev_event_cbs;
 /* spinlock for device callbacks */
 static rte_spinlock_t dev_event_lock = RTE_SPINLOCK_INITIALIZER;
 
-static int cmp_detached_dev_name(const struct rte_device *dev,
-       const void *_name)
-{
-       const char *name = _name;
-
-       /* skip attached devices */
-       if (dev->driver != NULL)
-               return 1;
-
-       return strcmp(dev->name, name);
-}
-
 static int cmp_dev_name(const struct rte_device *dev, const void *_name)
 {
        const char *name = _name;
@@ -151,14 +139,19 @@ int __rte_experimental rte_eal_hotplug_add(const char 
*busname, const char *devn
        if (ret)
                goto err_devarg;
 
-       dev = bus->find_device(NULL, cmp_detached_dev_name, devname);
+       dev = bus->find_device(NULL, cmp_dev_name, devname);
        if (dev == NULL) {
-               RTE_LOG(ERR, EAL, "Cannot find unplugged device (%s)\n",
+               RTE_LOG(ERR, EAL, "Cannot find device (%s)\n",
                        devname);
                ret = -ENODEV;
                goto err_devarg;
        }
 
+       if (dev->driver != NULL) {
+               RTE_LOG(ERR, EAL, "Device is already plugged\n");
+               return -EEXIST;
+       }
+
        ret = bus->plug(dev);
        if (ret) {
                RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
@@ -200,6 +193,11 @@ rte_eal_hotplug_remove(const char *busname, const char 
*devname)
                return -EINVAL;
        }
 
+       if (dev->driver == NULL) {
+               RTE_LOG(ERR, EAL, "Device is already unplugged\n");
+               return -ENOENT;
+       }
+
        ret = bus->unplug(dev);
        if (ret)
                RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n",
-- 
2.13.6

Reply via email to