Base on primary/secondary communication channel, we add vdev action
to scan virtual devices in secondary processes.

Signed-off-by: Jianfeng Tan <jianfeng....@intel.com>
---
 drivers/bus/vdev/vdev.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 96 insertions(+)

diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index cde2a3c..c3e97fb 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -252,12 +252,105 @@ rte_vdev_uninit(const char *name)
        return 0;
 }
 
+struct vdev_action_params {
+#define VDEV_SCAN_REQUEST      1
+#define VDEV_SCAN_RESPONSE     2
+       int type;
+       char name[32];
+};
+
+static int vdev_plug(struct rte_device *dev);
+
+static int
+vdev_action(const char *params, int len,
+           int fds[] __rte_unused,
+           int fds_num __rte_unused)
+{
+       struct rte_vdev_device *dev;
+       struct rte_devargs *devargs;
+       const struct vdev_action_params *in_params;
+       struct vdev_action_params ou_params;
+
+       in_params = (const struct vdev_action_params *)params;
+       switch (in_params->type) {
+       case VDEV_SCAN_REQUEST:
+               ou_params.type = VDEV_SCAN_RESPONSE;
+               TAILQ_FOREACH(dev, &vdev_device_list, next) {
+                       strncpy(ou_params.name, dev->device.name, 32);
+                       rte_eal_primary_secondary_sendmsg("vdev", &ou_params,
+                                                         len, NULL, 0);
+               }
+               break;
+       case VDEV_SCAN_RESPONSE:
+               if (strlen(in_params->name) == 0) {
+                       VDEV_LOG(ERR, "invalid name was passed");
+                       break;
+               }
+
+               dev = find_vdev(in_params->name);
+               if (dev) {
+                       VDEV_LOG(ERR, "vdev already exists: %s",
+                                in_params->name);
+                       break;
+               }
+
+               devargs = alloc_devargs(in_params->name, NULL);
+               if (!devargs) {
+                       VDEV_LOG(ERR, "failed to allocate memory");
+                       break;
+               }
+
+               dev = calloc(1, sizeof(*dev));
+               if (!dev) {
+                       VDEV_LOG(ERR, "failed to allocate memory");
+                       free(devargs);
+                       break;
+               }
+
+               dev->device.devargs = devargs;
+               dev->device.numa_node = 0; /* to be corrected in probe() */
+               dev->device.name = devargs->name;
+
+               TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+               TAILQ_INSERT_TAIL(&vdev_device_list, dev, next);
+
+               if (vdev_plug(&dev->device) < 0) {
+                       VDEV_LOG(ERR, "failed to plug device");
+                       free(devargs);
+                       free(dev);
+               }
+
+               VDEV_LOG(INFO, "plug in device: %s", in_params->name);
+
+               break;
+       default:
+               VDEV_LOG(ERR, "vdev cannot recognize this message\n");
+       }
+
+       return 0;
+}
+
 static int
 vdev_scan(void)
 {
        struct rte_vdev_device *dev;
        struct rte_devargs *devargs;
 
+       if (rte_eal_primary_secondary_add_action("vdev", vdev_action) < 0) {
+               VDEV_LOG(ERR, "vdev fails to add action\n");
+               return -1;
+       }
+
+       if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+               struct vdev_action_params params;
+
+               params.type = VDEV_SCAN_REQUEST;
+               rte_eal_primary_secondary_sendmsg("vdev", &params,
+                                                 sizeof(params), NULL, 0);
+
+               return 0;
+       }
+
        /* for virtual devices we scan the devargs_list populated via cmdline */
        TAILQ_FOREACH(devargs, &devargs_list, next) {
 
@@ -287,6 +380,9 @@ vdev_probe(void)
 {
        struct rte_vdev_device *dev;
 
+       if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+               return 0;
+
        /* call the init function for each virtual device */
        TAILQ_FOREACH(dev, &vdev_device_list, next) {
 
-- 
2.7.4

Reply via email to