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

Reply via email to