Implemented the bus ops scan_one, besides this improve the scan efficiency in hotplug case, it aslo avoid sync IPC invoke (which happens in vdev->scan on secondary process). The benifit is it removes the potiential deadlock in the case when secondary process receive a request from primary process to attach a new device, since vdev->scan will be invoked on mp thread itself at this case.
Signed-off-by: Qi Zhang <qi.z.zh...@intel.com> --- drivers/bus/vdev/vdev.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c index 6139dd551..cdbd77df0 100644 --- a/drivers/bus/vdev/vdev.c +++ b/drivers/bus/vdev/vdev.c @@ -467,6 +467,35 @@ vdev_scan(void) return 0; } +static struct rte_device *vdev_scan_one(struct rte_devargs *devargs) +{ + struct rte_vdev_device *dev = NULL; + + dev = calloc(1, sizeof(*dev)); + if (!dev) { + VDEV_LOG(ERR, "failed to allocate memory for new device"); + return NULL; + } + + rte_spinlock_recursive_lock(&vdev_device_list_lock); + + if (find_vdev(devargs->name)) { + VDEV_LOG(ERR, "device %s already exist", devargs->name); + free(dev); + rte_spinlock_recursive_unlock(&vdev_device_list_lock); + return NULL; + } + + dev->device.devargs = devargs; + dev->device.numa_node = SOCKET_ID_ANY; + dev->device.name = devargs->name; + TAILQ_INSERT_TAIL(&vdev_device_list, dev, next); + + rte_spinlock_recursive_unlock(&vdev_device_list_lock); + + return &dev->device; +} + static int vdev_probe(void) { @@ -531,6 +560,7 @@ vdev_unplug(struct rte_device *dev) static struct rte_bus rte_vdev_bus = { .scan = vdev_scan, + .scan_one = vdev_scan_one, .probe = vdev_probe, .find_device = vdev_find_device, .plug = vdev_plug, -- 2.13.6