When the user specifies --create-uio-dev in dpdk eal start options, the DPDK will create the /dev/uioX instead of waiting that a program does it (which is usually hotplug).
This option is useful in embedded environments where there is no hotplug to do the work. Signed-off-by: Olivier Matz <olivier.matz at 6wind.com> --- lib/librte_eal/linuxapp/eal/eal.c | 6 +++ lib/librte_eal/linuxapp/eal/eal_pci.c | 47 +++++++++++++++++++++- .../linuxapp/eal/include/eal_internal_cfg.h | 1 + 3 files changed, 53 insertions(+), 1 deletion(-) Hi Thomas, Thanks for your comment, I moved the option help above. diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c index bd20331..e402fee 100644 --- a/lib/librte_eal/linuxapp/eal/eal.c +++ b/lib/librte_eal/linuxapp/eal/eal.c @@ -94,6 +94,7 @@ #define OPT_SOCKET_MEM "socket-mem" #define OPT_USE_DEVICE "use-device" #define OPT_SYSLOG "syslog" +#define OPT_CREATE_UIO_DEV "create-uio-dev" #define RTE_EAL_BLACKLIST_SIZE 0x100 @@ -352,6 +353,7 @@ eal_usage(const char *prgname) " [NOTE: Cannot be used with -b option]\n" " --"OPT_VMWARE_TSC_MAP": use VMware TSC map instead of " "native RDTSC\n" + " --"OPT_CREATE_UIO_DEV": create /dev/uioX (usually done by hotplug)\n" "\nEAL options for DEBUG use only:\n" " --"OPT_NO_HUGE" : use malloc instead of hugetlbfs\n" " --"OPT_NO_PCI" : disable pci\n" @@ -608,6 +610,7 @@ eal_parse_args(int argc, char **argv) {OPT_SOCKET_MEM, 1, 0, 0}, {OPT_USE_DEVICE, 1, 0, 0}, {OPT_SYSLOG, 1, NULL, 0}, + {OPT_CREATE_UIO_DEV, 1, NULL, 0}, {0, 0, 0, 0} }; struct shared_driver *solib; @@ -747,6 +750,9 @@ eal_parse_args(int argc, char **argv) return -1; } } + else if (!strcmp(lgopts[option_index].name, OPT_CREATE_UIO_DEV)) { + internal_config.create_uio_dev = 1; + } break; default: diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c index 1039777..af5a8b9 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c @@ -460,6 +460,47 @@ pci_uio_map_secondary(struct rte_pci_device *dev) return -1; } +static int pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned uio_num) +{ + FILE *f; + char filename[PATH_MAX]; + int ret; + unsigned major, minor; + dev_t dev; + + /* get the name of the sysfs file that contains the major and minor + * of the uio device and read its content */ + rte_snprintf(filename, sizeof(filename), "%s/dev", sysfs_uio_path); + + f = fopen(filename, "r"); + if (f == NULL) { + RTE_LOG(ERR, EAL, "%s(): cannot open sysfs to get major:minor\n", + __func__); + return -1; + } + + ret = fscanf(f, "%d:%d", &major, &minor); + if (ret != 2) { + RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs to get major:minor\n", + __func__); + fclose(f); + return -1; + } + fclose(f); + + /* create the char device "mknod /dev/uioX c major minor" */ + rte_snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num); + dev = makedev(major, minor); + ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev); + if (f == NULL) { + RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n", + __func__, strerror(errno)); + return -1; + } + + return ret; +} + /* * Return the uioX char device used for a pci device. On success, return * the UIO number and fill dstbuf string with the path of the device in @@ -529,7 +570,11 @@ static int pci_get_uio_dev(struct rte_pci_device *dev, char *dstbuf, if (e == NULL) return -1; - return 0; + /* create uio device if we've been asked to */ + if (internal_config.create_uio_dev && pci_mknod_uio_dev(dstbuf, uio_num) < 0) + RTE_LOG(WARNING, EAL, "Cannot create /dev/uio%u\n", uio_num); + + return uio_num; } /* map the PCI resource of a PCI device in virtual memory */ diff --git a/lib/librte_eal/linuxapp/eal/include/eal_internal_cfg.h b/lib/librte_eal/linuxapp/eal/include/eal_internal_cfg.h index 45ec058..649bd2b 100644 --- a/lib/librte_eal/linuxapp/eal/include/eal_internal_cfg.h +++ b/lib/librte_eal/linuxapp/eal/include/eal_internal_cfg.h @@ -68,6 +68,7 @@ struct internal_config { volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping * instead of native TSC */ volatile unsigned no_shconf; /**< true if there is no shared config */ + volatile unsigned create_uio_dev; /**< true to create /dev/uioX devices */ volatile enum rte_proc_type_t process_type; /**< multi-process proc type */ /** true to try allocating memory on specific sockets */ volatile unsigned force_sockets; -- 1.8.4.rc3