From 6aebb942907da015be55338a912e83e370b2e102 Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Wed, 29 Sep 2021 23:39:41 +0200 Subject: [PATCH] kvargs: add function to get from key and value A quite common scenario with kvargs is to lookup for a = in a kvlist. For instance, check if name=foo is present in name=toto,name=foo,name=bar. This is currently done in drivers/bus with rte_kvargs_process() + the rte_kvargs_strcmp() handler. This approach is not straightforward, and can be replaced by this new function. rte_kvargs_strcmp() is then removed. Signed-off-by: Olivier Matz Reviewed-by: Xueming Li Reviewed-by: David Marchand Acked-by: Ray Kinsella --- doc/guides/rel_notes/release_21_11.rst | 4 ++ drivers/bus/auxiliary/auxiliary_params.c | 9 ++-- drivers/bus/vdev/vdev_params.c | 13 +----- lib/kvargs/rte_kvargs.c | 32 ++++++++------ lib/kvargs/rte_kvargs.h | 55 ++++++++++++------------ lib/kvargs/version.map | 4 +- 6 files changed, 58 insertions(+), 59 deletions(-) diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst index 73e377a007..945a3d49d5 100644 --- a/doc/guides/rel_notes/release_21_11.rst +++ b/doc/guides/rel_notes/release_21_11.rst @@ -157,6 +157,10 @@ API Changes Also, make sure to start the actual text at the margin. ======================================================= +* kvargs: The experimental function ``rte_kvargs_strcmp()`` has been + removed. Its usages have been replaced by a new function + ``rte_kvargs_get_with_value()``. + * cryptodev: The API rte_cryptodev_pmd_is_valid_dev is modified to rte_cryptodev_is_valid_dev as it can be used by the application as well as PMD to check whether the device is valid or not. diff --git a/drivers/bus/auxiliary/auxiliary_params.c b/drivers/bus/auxiliary/auxiliary_params.c index cd3fa56cb4..a9c7853ed1 100644 --- a/drivers/bus/auxiliary/auxiliary_params.c +++ b/drivers/bus/auxiliary/auxiliary_params.c @@ -25,13 +25,12 @@ auxiliary_dev_match(const struct rte_device *dev, const void *_kvlist) { const struct rte_kvargs *kvlist = _kvlist; - int ret; + const char *key = auxiliary_params_keys[RTE_AUXILIARY_PARAM_NAME]; - ret = rte_kvargs_process(kvlist, - auxiliary_params_keys[RTE_AUXILIARY_PARAM_NAME], - rte_kvargs_strcmp, (void *)(uintptr_t)dev->name); + if (rte_kvargs_get_with_value(kvlist, key, dev->name) == NULL) + return -1; - return ret != 0 ? -1 : 0; + return 0; } void * diff --git a/drivers/bus/vdev/vdev_params.c b/drivers/bus/vdev/vdev_params.c index 6f74704d1c..37d95395e7 100644 --- a/drivers/bus/vdev/vdev_params.c +++ b/drivers/bus/vdev/vdev_params.c @@ -26,19 +26,10 @@ static int vdev_dev_match(const struct rte_device *dev, const void *_kvlist) { - int ret; const struct rte_kvargs *kvlist = _kvlist; - char *name; + const char *key = vdev_params_keys[RTE_VDEV_PARAM_NAME]; - /* cannot pass const dev->name to rte_kvargs_process() */ - name = strdup(dev->name); - if (name == NULL) - return -1; - ret = rte_kvargs_process(kvlist, - vdev_params_keys[RTE_VDEV_PARAM_NAME], - rte_kvargs_strcmp, name); - free(name); - if (ret != 0) + if (rte_kvargs_get_with_value(kvlist, key, dev->name) == NULL) return -1; return 0; diff --git a/lib/kvargs/rte_kvargs.c b/lib/kvargs/rte_kvargs.c index 38e9d5c1ca..11f624ef14 100644 --- a/lib/kvargs/rte_kvargs.c +++ b/lib/kvargs/rte_kvargs.c @@ -204,21 +204,34 @@ rte_kvargs_free(struct rte_kvargs *kvlist) free(kvlist); } -/* Lookup a value in an rte_kvargs list by its key. */ +/* Lookup a value in an rte_kvargs list by its key and value. */ const char * -rte_kvargs_get(const struct rte_kvargs *kvlist, const char *key) +rte_kvargs_get_with_value(const struct rte_kvargs *kvlist, const char *key, + const char *value) { unsigned int i; - if (kvlist == NULL || key == NULL) + if (kvlist == NULL) return NULL; for (i = 0; i < kvlist->count; ++i) { - if (strcmp(kvlist->pairs[i].key, key) == 0) - return kvlist->pairs[i].value; + if (key != NULL && strcmp(kvlist->pairs[i].key, key) != 0) + continue; + if (value != NULL && strcmp(kvlist->pairs[i].value, value) != 0) + continue; + return kvlist->pairs[i].value; } return NULL; } +/* Lookup a value in an rte_kvargs list by its key. */ +const char * +rte_kvargs_get(const struct rte_kvargs *kvlist, const char *key) +{ + if (kvlist == NULL || key == NULL) + return NULL; + return rte_kvargs_get_with_value(kvlist, key, NULL); +} + /* * Parse the arguments "key=value,key=value,..." string and return * an allocated structure that contains a key/value list. Also @@ -270,12 +283,3 @@ rte_kvargs_parse_delim(const char *args, const char * const valid_keys[], free(copy); return kvlist; } - -int -rte_kvargs_strcmp(const char *key __rte_unused, - const char *value, void *opaque) -{ - const char *str = opaque; - - return -abs(strcmp(str, value)); -} diff --git a/lib/kvargs/rte_kvargs.h b/lib/kvargs/rte_kvargs.h index 328f0d3cc6..3c1754c3d9 100644 --- a/lib/kvargs/rte_kvargs.h +++ b/lib/kvargs/rte_kvargs.h @@ -116,7 +116,7 @@ void rte_kvargs_free(struct rte_kvargs *kvlist); /** * Get the value associated with a given key. * - * If multiple key matches, the value of the first one is returned. + * If multiple keys match, the value of the first one is returned. * * The memory returned is allocated as part of the rte_kvargs structure, * it must never be modified. @@ -132,6 +132,33 @@ void rte_kvargs_free(struct rte_kvargs *kvlist); */ const char *rte_kvargs_get(const struct rte_kvargs *kvlist, const char *key); +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Get the value associated with a given key and value. + * + * Find the first entry in the kvlist whose key and value match the + * ones passed as argument. + * + * The memory returned is allocated as part of the rte_kvargs structure, + * it must never be modified. + * + * @param kvlist + * A list of rte_kvargs pair of 'key=value'. + * @param key + * The matching key. If NULL, any key will match. + * @param value + * The matching value. If NULL, any value will match. + * + * @return + * NULL if no key matches the input, + * a value associated with a matching key otherwise. + */ +__rte_experimental +const char *rte_kvargs_get_with_value(const struct rte_kvargs *kvlist, + const char *key, const char *value); + /** * Call a handler function for each key/value matching the key * @@ -170,32 +197,6 @@ int rte_kvargs_process(const struct rte_kvargs *kvlist, unsigned rte_kvargs_count(const struct rte_kvargs *kvlist, const char *key_match); -/** - * Generic kvarg handler for string comparison. - * - * This function can be used for a generic string comparison processing - * on a list of kvargs. - * - * @param key - * kvarg pair key. - * - * @param value - * kvarg pair value. - * - * @param opaque - * Opaque pointer to a string. - * - * @return - * 0 if the strings match. - * !0 otherwise or on error. - * - * Unlike strcmp, comparison ordering is not kept. - * In order for rte_kvargs_process to stop processing on match error, - * a negative value is returned even if strcmp had returned a positive one. - */ -__rte_experimental -int rte_kvargs_strcmp(const char *key, const char *value, void *opaque); - #ifdef __cplusplus } #endif diff --git a/lib/kvargs/version.map b/lib/kvargs/version.map index 236f35c02b..0d42cd58a8 100644 --- a/lib/kvargs/version.map +++ b/lib/kvargs/version.map @@ -14,6 +14,6 @@ DPDK_22 { EXPERIMENTAL { global: - rte_kvargs_strcmp; - + # added in 21.11 + rte_kvargs_get_with_value; }; -- 2.20.1