From mboxrd@z Thu Jan 1 00:00:00 1970 From: Olivier Matz Subject: [PATCH 07/11] vdev: allow external registration of virtual device drivers Date: Fri, 28 Feb 2014 18:25:46 +0100 Message-ID: <1393608350-4431-8-git-send-email-olivier.matz@6wind.com> References: <1393608350-4431-1-git-send-email-olivier.matz@6wind.com> To: dev-VfR2kkLFssw@public.gmane.org Return-path: In-Reply-To: <1393608350-4431-1-git-send-email-olivier.matz-pdR9zngts4EAvxtiuMwx3w@public.gmane.org> List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces-VfR2kkLFssw@public.gmane.org Sender: "dev" Instead of having a list of virtual device drivers in EAL code, add an API to register drivers. Thanks to this change: - we don't need to reference pmd_ring, pmd_pcap and pmd_xenvirt in EAL code - it is now possible to provide a virtual device driver as a shared library. The registration is done in an init function flaged with __attribute__((constructor)). The new convention is to name this function rte_pmd_xyz_init(). The per-device init function is renamed rte_pmd_xyz_devinit(). By the way the internal PMDs are now also .so/standalone ready. Let's do it later on. It will be required to ease maintenance. Signed-off-by: Olivier Matz --- app/test/test_pmd_ring.c | 6 +-- lib/librte_eal/common/eal_common_vdev.c | 72 +++++++++++++++----------------- lib/librte_eal/linuxapp/eal/eal.c | 7 ++-- lib/librte_pmd_pcap/rte_eth_pcap.c | 16 ++++++- lib/librte_pmd_pcap/rte_eth_pcap.h | 8 ---- lib/librte_pmd_ring/rte_eth_ring.c | 15 ++++++- lib/librte_pmd_ring/rte_eth_ring.h | 6 +-- lib/librte_pmd_xenvirt/rte_eth_xenvirt.c | 14 ++++++- lib/librte_pmd_xenvirt/rte_eth_xenvirt.h | 4 +- 9 files changed, 85 insertions(+), 63 deletions(-) diff --git a/app/test/test_pmd_ring.c b/app/test/test_pmd_ring.c index c8242b3..4d9c2ba 100644 --- a/app/test/test_pmd_ring.c +++ b/app/test/test_pmd_ring.c @@ -315,12 +315,12 @@ test_pmd_ring_init(void) printf("Testing ring pmd init\n"); - if (rte_pmd_ring_init(name1, params_null) < 0) { + if (rte_pmd_ring_devinit(name1, params_null) < 0) { printf("Testing ring pmd init fail\n"); return -1; } - if (rte_pmd_ring_init(name2, params) < 0) { + if (rte_pmd_ring_devinit(name2, params) < 0) { printf("Testing ring pmd init fail\n"); return -1; } @@ -372,7 +372,7 @@ test_pmd_ring_init(void) rte_eth_dev_stop(RXTX_PORT2); /* Test init same name pmd ring */ - rte_pmd_ring_init(name1, params_null); + rte_pmd_ring_devinit(name1, params_null); return 0; } diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c index 02d3fd6..84547c7 100644 --- a/lib/librte_eal/common/eal_common_vdev.c +++ b/lib/librte_eal/common/eal_common_vdev.c @@ -34,7 +34,11 @@ #include #include -#include +#include + +#include +#include +#include #ifdef RTE_LIBRTE_PMD_RING #include #endif @@ -46,44 +50,37 @@ #endif #include #include + #include "eal_private.h" -struct device_init { - const char *dev_prefix; - int (*init_fn)(const char*, const char *); -}; +/** Global list of virtual device drivers. */ +static struct rte_vdev_driver_list vdev_driver_list = + TAILQ_HEAD_INITIALIZER(vdev_driver_list); -#define NUM_DEV_TYPES (sizeof(dev_types)/sizeof(dev_types[0])) -struct device_init dev_types[] = { -#ifdef RTE_LIBRTE_PMD_RING - { - .dev_prefix = RTE_ETH_RING_PARAM_NAME, - .init_fn = rte_pmd_ring_init - }, -#endif -#ifdef RTE_LIBRTE_PMD_PCAP - { - .dev_prefix = RTE_ETH_PCAP_PARAM_NAME, - .init_fn = rte_pmd_pcap_init - }, -#endif -#ifdef RTE_LIBRTE_PMD_XENVIRT - { - .dev_prefix = RTE_ETH_XENVIRT_PARAM_NAME, - .init_fn = rte_pmd_xenvirt_init - }, -#endif - { - .dev_prefix = "-nodev-", - .init_fn = NULL - } -}; +/* register a driver */ +void +rte_eal_vdev_driver_register(struct rte_vdev_driver *driver) +{ + TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next); +} + +/* unregister a driver */ +void +rte_eal_vdev_driver_unregister(struct rte_vdev_driver *driver) +{ + TAILQ_REMOVE(&vdev_driver_list, driver, next); +} int rte_eal_vdev_init(void) { struct rte_devargs *devargs; - uint8_t i; + struct rte_vdev_driver *driver; + + /* No need to register drivers that are embeded in DPDK + * (pmd_pcap, pmd_ring, ...). The initialization function have + * the ((constructor)) attribute so they will register at + * startup. */ /* call the init function for each virtual device */ TAILQ_FOREACH(devargs, &devargs_list, next) { @@ -91,18 +88,17 @@ rte_eal_vdev_init(void) if (devargs->type != RTE_DEVTYPE_VIRTUAL) continue; - for (i = 0; i < NUM_DEV_TYPES; i++) { + TAILQ_FOREACH(driver, &vdev_driver_list, next) { /* search a driver prefix in virtual device name */ - if (!strncmp(dev_types[i].dev_prefix, - devargs->virtual.drv_name, - sizeof(dev_types[i].dev_prefix) - 1)) { - dev_types[i].init_fn(devargs->virtual.drv_name, - devargs->args); + if (!strncmp(driver->name, devargs->virtual.drv_name, + strlen(driver->name))) { + driver->init(devargs->virtual.drv_name, + devargs->args); break; } } - if (i == NUM_DEV_TYPES) { + if (driver == NULL) { rte_panic("no driver found for %s\n", devargs->virtual.drv_name); } diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c index 2f3222d..6502755 100644 --- a/lib/librte_eal/linuxapp/eal/eal.c +++ b/lib/librte_eal/linuxapp/eal/eal.c @@ -1039,10 +1039,8 @@ rte_eal_init(int argc, char **argv) rte_eal_mcfg_complete(); - if (rte_eal_vdev_init() < 0) - rte_panic("Cannot init virtual devices\n"); - TAILQ_FOREACH(solib, &solib_list, next) { + RTE_LOG(INFO, EAL, "open shared lib %s\n", solib->name); solib->lib_handle = dlopen(solib->name, RTLD_NOW); if ((solib->lib_handle == NULL) && (solib->name[0] != '/')) { /* relative path: try again with "./" prefix */ @@ -1054,6 +1052,9 @@ rte_eal_init(int argc, char **argv) RTE_LOG(WARNING, EAL, "%s\n", dlerror()); } + if (rte_eal_vdev_init() < 0) + rte_panic("Cannot init virtual devices\n"); + RTE_LOG(DEBUG, EAL, "Master core %u is ready (tid=%x)\n", rte_config.master_lcore, (int)thread_id); diff --git a/lib/librte_pmd_pcap/rte_eth_pcap.c b/lib/librte_pmd_pcap/rte_eth_pcap.c index 03e6e6c..15f7469 100644 --- a/lib/librte_pmd_pcap/rte_eth_pcap.c +++ b/lib/librte_pmd_pcap/rte_eth_pcap.c @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -697,8 +698,8 @@ rte_eth_from_pcaps(pcap_t * const rx_queues[], } -int -rte_pmd_pcap_init(const char *name, const char *params) +static int +rte_pmd_pcap_devinit(const char *name, const char *params) { unsigned numa_node, using_dumpers = 0; int ret; @@ -777,3 +778,14 @@ rte_pmd_pcap_init(const char *name, const char *params) } +static struct rte_vdev_driver pmd_pcap_drv = { + .name = "eth_pcap", + .init = rte_pmd_pcap_devinit, +}; + +__attribute__((constructor)) +static void +rte_pmd_pcap_init(void) +{ + rte_eal_vdev_driver_register(&pmd_pcap_drv); +} diff --git a/lib/librte_pmd_pcap/rte_eth_pcap.h b/lib/librte_pmd_pcap/rte_eth_pcap.h index c0bc5d8..473b6cb 100644 --- a/lib/librte_pmd_pcap/rte_eth_pcap.h +++ b/lib/librte_pmd_pcap/rte_eth_pcap.h @@ -45,8 +45,6 @@ extern "C" { #undef PCAP_CAN_SEND #endif -#define RTE_ETH_PCAP_PARAM_NAME "eth_pcap" - /* struct args_dict is declared in rte_eth_pcap_args_parser.h */ struct args_dict; @@ -64,12 +62,6 @@ int rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[], const unsigned numa_node, struct args_dict *dict); -/** - * For use by the EAL only. Called as part of EAL init to set up any dummy NICs - * configured on command line. - */ -int rte_pmd_pcap_init(const char *name, const char *params); - #ifdef __cplusplus } #endif diff --git a/lib/librte_pmd_ring/rte_eth_ring.c b/lib/librte_pmd_ring/rte_eth_ring.c index 24635f3..cee3fff 100644 --- a/lib/librte_pmd_ring/rte_eth_ring.c +++ b/lib/librte_pmd_ring/rte_eth_ring.c @@ -37,6 +37,7 @@ #include #include #include +#include struct ring_queue { struct rte_ring *rng; @@ -382,7 +383,7 @@ rte_eth_ring_pair_attach(const char *name, const unsigned numa_node) } int -rte_pmd_ring_init(const char *name, const char *params) +rte_pmd_ring_devinit(const char *name, const char *params) { RTE_LOG(INFO, PMD, "Initializing pmd_ring for %s\n", name); @@ -395,3 +396,15 @@ rte_pmd_ring_init(const char *name, const char *params) } return 0; } + +static struct rte_vdev_driver pmd_ring_drv = { + .name = "eth_ring", + .init = rte_pmd_ring_devinit, +}; + +__attribute__((constructor)) +static void +rte_pmd_ring_init(void) +{ + rte_eal_vdev_driver_register(&pmd_ring_drv); +} diff --git a/lib/librte_pmd_ring/rte_eth_ring.h b/lib/librte_pmd_ring/rte_eth_ring.h index a222ecb..b84a29e 100644 --- a/lib/librte_pmd_ring/rte_eth_ring.h +++ b/lib/librte_pmd_ring/rte_eth_ring.h @@ -40,8 +40,6 @@ extern "C" { #include -#define RTE_ETH_RING_PARAM_NAME "eth_ring" - int rte_eth_from_rings(struct rte_ring * const rx_queues[], const unsigned nb_rx_queues, struct rte_ring *const tx_queues[], @@ -52,10 +50,10 @@ int rte_eth_ring_pair_create(const char *name, const unsigned numa_node); int rte_eth_ring_pair_attach(const char *name, const unsigned numa_node); /** - * For use by the EAL only. Called as part of EAL init to set up any dummy NICs + * For use by test apps only. Called as part of EAL init to set up any dummy NICs * configured on command line. */ -int rte_pmd_ring_init(const char *name, const char *params); +int rte_pmd_ring_devinit(const char *name, const char *params); #ifdef __cplusplus } diff --git a/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c b/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c index bad8dd4..d142973 100644 --- a/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c +++ b/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c @@ -689,7 +689,7 @@ err: /*TODO: Support multiple process model */ int -rte_pmd_xenvirt_init(const char *name, const char *params) +rte_pmd_xenvirt_devinit(const char *name, const char *params) { if (virtio_idx == 0) { if (xenstore_init() != 0) { @@ -704,3 +704,15 @@ rte_pmd_xenvirt_init(const char *name, const char *params) eth_dev_xenvirt_create(name, params, rte_socket_id(), DEV_CREATE); return 0; } + +static struct rte_vdev_driver pmd_xenvirt_drv = { + .name = "eth_xenvirt", + .init = rte_pmd_xenvirt_devinit, +}; + +__attribute__((constructor)) +static void +rte_pmd_xenvirt_init(void) +{ + rte_eal_vdev_driver_register(&pmd_xenvirt_drv); +} diff --git a/lib/librte_pmd_xenvirt/rte_eth_xenvirt.h b/lib/librte_pmd_xenvirt/rte_eth_xenvirt.h index cb1924a..f3f3220 100644 --- a/lib/librte_pmd_xenvirt/rte_eth_xenvirt.h +++ b/lib/librte_pmd_xenvirt/rte_eth_xenvirt.h @@ -41,13 +41,11 @@ extern "C" { #include #include -#define RTE_ETH_XENVIRT_PARAM_NAME "eth_xenvirt" - /** * For use by the EAL only. Called as part of EAL init to set up any dummy NICs * configured on command line. */ -int rte_pmd_xenvirt_init(const char *name, const char *params); +int rte_pmd_xenvirt_devinit(const char *name, const char *params); /** * Creates mempool for xen virtio PMD. -- 1.8.5.3