[dpdk-dev,07/12] bus/vdev: scan and probe vdev in secondary processes
Checks
Commit Message
Base on primary/secondary communication channel, we add vdev action
to scan virtual devices in secondary processes.
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
drivers/bus/vdev/vdev.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 96 insertions(+)
@@ -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", ¶ms,
+ 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) {