diff --git a/MAINTAINERS b/MAINTAINERS index b1d4ded1b1..d785363c5c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -568,6 +568,7 @@ F: drivers/bus/pci/ VDEV bus driver F: drivers/bus/vdev/ +F: app/test/test_vdev.c VMBUS bus driver M: Stephen Hemminger diff --git a/app/test/meson.build b/app/test/meson.build index 961bebc5cb..2b480adfba 100644 --- a/app/test/meson.build +++ b/app/test/meson.build @@ -426,6 +426,11 @@ if dpdk_conf.has('RTE_NET_RING') fast_tests += [['pdump_autotest', true]] endif endif +if dpdk_conf.has('RTE_NET_NULL') + test_deps += 'net_null' + test_sources += 'test_vdev.c' + fast_tests += [['vdev_autotest', true]] +endif if dpdk_conf.has('RTE_HAS_LIBPCAP') ext_deps += pcap_dep diff --git a/app/test/test_vdev.c b/app/test/test_vdev.c new file mode 100644 index 0000000000..720722c363 --- /dev/null +++ b/app/test/test_vdev.c @@ -0,0 +1,168 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2021 6WIND S.A. + */ + +#include +#include +#include + +#include +#include +#include + +#include "test.h" + +#define TEST_VDEV_KEY_NAME "name" + +static const char * const valid_keys[] = { + TEST_VDEV_KEY_NAME, + NULL, +}; + +static int +cmp_dev_name(const struct rte_device *dev, const void *name) +{ + return strcmp(dev->name, name); +} + +static int +cmp_dev_match(const struct rte_device *dev, const void *_kvlist) +{ + const struct rte_kvargs *kvlist = _kvlist; + const char *key = TEST_VDEV_KEY_NAME; + const char *name; + + /* no kvlist arg, all devices match */ + if (kvlist == NULL) + return 0; + + /* if key is present in kvlist and does not match, filter device */ + name = rte_kvargs_get(kvlist, key); + if (name != NULL && strcmp(name, dev->name)) + return -1; + + return 0; +} + +static struct rte_device * +get_matching_vdev(const char *match_str) +{ + struct rte_bus *vdev_bus = rte_bus_find_by_name("vdev"); + struct rte_kvargs *kvargs = NULL; + struct rte_device *dev; + + if (match_str != NULL) { + kvargs = rte_kvargs_parse(match_str, valid_keys); + if (kvargs == NULL) { + printf("Failed to parse match string\n"); + return NULL; + } + } + + dev = vdev_bus->find_device(NULL, cmp_dev_match, kvargs); + rte_kvargs_free(kvargs); + + return dev; +} + +static int +test_vdev_bus(void) +{ + struct rte_bus *vdev_bus = rte_bus_find_by_name("vdev"); + struct rte_dev_iterator dev_iter = { 0 }; + struct rte_device *dev, *dev0, *dev1; + + /* not supported */ + if (vdev_bus == NULL) + return 0; + + /* create first vdev */ + if (rte_vdev_init("net_null_test0", "") < 0) { + printf("Failed to create vdev net_null_test0\n"); + goto fail; + } + dev0 = vdev_bus->find_device(NULL, cmp_dev_name, "net_null_test0"); + if (dev0 == NULL) { + printf("Cannot find net_null_test0 vdev\n"); + goto fail; + } + + /* create second vdev */ + if (rte_vdev_init("net_null_test1", "") < 0) { + printf("Failed to create vdev net_null_test1\n"); + goto fail; + } + dev1 = vdev_bus->find_device(NULL, cmp_dev_name, "net_null_test1"); + if (dev1 == NULL) { + printf("Cannot find net_null_test1 vdev\n"); + goto fail; + } + + /* try to match vdevs */ + dev = get_matching_vdev("name=net_null_test0"); + if (dev != dev0) { + printf("Cannot match net_null_test0 vdev\n"); + goto fail; + } + + dev = get_matching_vdev("name=net_null_test1"); + if (dev != dev1) { + printf("Cannot match net_null_test1 vdev\n"); + goto fail; + } + + dev = get_matching_vdev("name=unexistant"); + if (dev != NULL) { + printf("Unexistant vdev should not match\n"); + goto fail; + } + + dev = get_matching_vdev(""); + if (dev == NULL || dev == dev1) { + printf("Cannot match any vdev with empty match string\n"); + goto fail; + } + + dev = get_matching_vdev(NULL); + if (dev == NULL || dev == dev1) { + printf("Cannot match any vdev with NULL match string\n"); + goto fail; + } + + /* iterate all vdevs, and ensure we find vdev0 and vdev1 */ + RTE_DEV_FOREACH(dev, "bus=vdev", &dev_iter) { + if (dev == dev0) + dev0 = NULL; + else if (dev == dev1) + dev1 = NULL; + } + if (dev0 != NULL) { + printf("dev0 was not iterated\n"); + goto fail; + } + if (dev1 != NULL) { + printf("dev1 was not iterated\n"); + goto fail; + } + + rte_vdev_uninit("net_null_test0"); + rte_vdev_uninit("net_null_test1"); + + return 0; + +fail: + rte_vdev_uninit("net_null_test0"); + rte_vdev_uninit("net_null_test1"); + return -1; +} + +static int +test_vdev(void) +{ + printf("== test vdev bus ==\n"); + if (test_vdev_bus() < 0) + return -1; + return 0; +} + +REGISTER_TEST_COMMAND(vdev_autotest, test_vdev); diff --git a/drivers/bus/auxiliary/auxiliary_params.c b/drivers/bus/auxiliary/auxiliary_params.c index d115e11d32..9017118b36 100644 --- a/drivers/bus/auxiliary/auxiliary_params.c +++ b/drivers/bus/auxiliary/auxiliary_params.c @@ -27,8 +27,15 @@ auxiliary_dev_match(const struct rte_device *dev, { const struct rte_kvargs *kvlist = _kvlist; const char *key = auxiliary_params_keys[RTE_AUXILIARY_PARAM_NAME]; + const char *name; - if (rte_kvargs_get_with_value(kvlist, key, dev->name) == NULL) + /* no kvlist arg, all devices match */ + if (kvlist == NULL) + return 0; + + /* if key is present in kvlist and does not match, filter device */ + name = rte_kvargs_get(kvlist, key); + if (name != NULL && strcmp(name, dev->name)) return -1; return 0; diff --git a/drivers/bus/vdev/vdev_params.c b/drivers/bus/vdev/vdev_params.c index 37d95395e7..3969faf16d 100644 --- a/drivers/bus/vdev/vdev_params.c +++ b/drivers/bus/vdev/vdev_params.c @@ -28,8 +28,15 @@ vdev_dev_match(const struct rte_device *dev, { const struct rte_kvargs *kvlist = _kvlist; const char *key = vdev_params_keys[RTE_VDEV_PARAM_NAME]; + const char *name; - if (rte_kvargs_get_with_value(kvlist, key, dev->name) == NULL) + /* no kvlist arg, all devices match */ + if (kvlist == NULL) + return 0; + + /* if key is present in kvlist and does not match, filter device */ + name = rte_kvargs_get(kvlist, key); + if (name != NULL && strcmp(name, dev->name)) return -1; return 0;