]> git.droids-corp.org - dpdk.git/commitdiff
eal: fix deadlock in hot-unplug
authorJeff Guo <jia.guo@intel.com>
Thu, 15 Nov 2018 09:18:22 +0000 (17:18 +0800)
committerThomas Monjalon <thomas@monjalon.net>
Sun, 18 Nov 2018 16:16:40 +0000 (17:16 +0100)
When device be hot-unplugged, the hot-unplug handler will be invoked by uio
remove event and the device will be detached, then kernel will sent another
pci remove event. So if there is any unlock miss, it will cause a dead lock
issue. This patch will add this missing unlock for hot-unplug handler.

Fixes: 0fc54536b14a ("eal: add failure handling for hot-unplug")
Signed-off-by: Jeff Guo <jia.guo@intel.com>
lib/librte_eal/linuxapp/eal/eal_dev.c

index d589c692c170120ec0a5efb7d183a4967f4772ae..2830c8687d2c7a16b997bbe893f57fbc19ce0921 100644 (file)
@@ -258,7 +258,7 @@ dev_uev_handler(__rte_unused void *param)
                        if (bus == NULL) {
                                RTE_LOG(ERR, EAL, "Cannot find bus (%s)\n",
                                        busname);
-                               return;
+                               goto failure_handle_err;
                        }
 
                        dev = bus->find_device(NULL, cmp_dev_name,
@@ -266,19 +266,23 @@ dev_uev_handler(__rte_unused void *param)
                        if (dev == NULL) {
                                RTE_LOG(ERR, EAL, "Cannot find device (%s) on "
                                        "bus (%s)\n", uevent.devname, busname);
-                               return;
+                               goto failure_handle_err;
                        }
 
                        ret = bus->hot_unplug_handler(dev);
-                       rte_spinlock_unlock(&failure_handle_lock);
                        if (ret) {
                                RTE_LOG(ERR, EAL, "Can not handle hot-unplug "
                                        "for device (%s)\n", dev->name);
-                               return;
                        }
+                       rte_spinlock_unlock(&failure_handle_lock);
                }
                rte_dev_event_callback_process(uevent.devname, uevent.type);
        }
+
+       return;
+
+failure_handle_err:
+       rte_spinlock_unlock(&failure_handle_lock);
 }
 
 int __rte_experimental