From 8ffe738651240c3814bf1ef4c29d0e06c0f793c6 Mon Sep 17 00:00:00 2001 From: Jeff Guo Date: Thu, 15 Nov 2018 17:18:23 +0800 Subject: [PATCH] vfio: add lock for hot-unplug failure handler When the sigbus handler be enabled for hot-unplug, whatever hot-unplug sigbus or origin sigbus occur, the sigbus handler will be invoked and it will access the bus and device. While in the control path, the vfio req handler also will process the bus and device, so a protection of the resources in vfio req handler should be need. This patch add a lock in vfio req handler when process bus and device resource, to avoid the synchronization issue when device be hot-unplugged. Fixes: c115fd000c32 ("vfio: handle hotplug request notifier") Signed-off-by: Jeff Guo --- drivers/bus/pci/linux/pci_vfio.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/bus/pci/linux/pci_vfio.c b/drivers/bus/pci/linux/pci_vfio.c index 305cc0601d..d2c84106fc 100644 --- a/drivers/bus/pci/linux/pci_vfio.c +++ b/drivers/bus/pci/linux/pci_vfio.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "eal_filesystem.h" @@ -35,6 +36,14 @@ * This file is only compiled if CONFIG_RTE_EAL_VFIO is set to "y". */ +/* + * spinlock for device hot-unplug failure handling. If it try to access bus or + * device, such as handle sigbus on bus or handle memory failure for device + * just need to use this lock. It could protect the bus and the device to avoid + * race condition. + */ +static rte_spinlock_t failure_handle_lock = RTE_SPINLOCK_INITIALIZER; + #ifdef VFIO_PRESENT #ifndef PAGE_SIZE @@ -289,11 +298,12 @@ pci_vfio_req_handler(void *param) int ret; struct rte_device *device = (struct rte_device *)param; + rte_spinlock_lock(&failure_handle_lock); bus = rte_bus_find_by_device(device); if (bus == NULL) { RTE_LOG(ERR, EAL, "Cannot find bus for device (%s)\n", device->name); - return; + goto handle_end; } /* @@ -306,6 +316,8 @@ pci_vfio_req_handler(void *param) RTE_LOG(ERR, EAL, "Can not handle hot-unplug for device (%s)\n", device->name); +handle_end: + rte_spinlock_unlock(&failure_handle_lock); } /* enable notifier (only enable req now) */ -- 2.20.1