dpdk/lib/member/rte_member.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2017 Intel Corporation
   3 */
   4
   5#include <string.h>
   6
   7#include <rte_string_fns.h>
   8#include <rte_eal.h>
   9#include <rte_eal_memconfig.h>
  10#include <rte_memory.h>
  11#include <rte_malloc.h>
  12#include <rte_errno.h>
  13#include <rte_tailq.h>
  14
  15#include "rte_member.h"
  16#include "rte_member_ht.h"
  17#include "rte_member_vbf.h"
  18
  19TAILQ_HEAD(rte_member_list, rte_tailq_entry);
  20static struct rte_tailq_elem rte_member_tailq = {
  21        .name = "RTE_MEMBER",
  22};
  23EAL_REGISTER_TAILQ(rte_member_tailq)
  24
  25struct rte_member_setsum *
  26rte_member_find_existing(const char *name)
  27{
  28        struct rte_member_setsum *setsum = NULL;
  29        struct rte_tailq_entry *te;
  30        struct rte_member_list *member_list;
  31
  32        member_list = RTE_TAILQ_CAST(rte_member_tailq.head, rte_member_list);
  33
  34        rte_mcfg_tailq_read_lock();
  35        TAILQ_FOREACH(te, member_list, next) {
  36                setsum = (struct rte_member_setsum *) te->data;
  37                if (strncmp(name, setsum->name, RTE_MEMBER_NAMESIZE) == 0)
  38                        break;
  39        }
  40        rte_mcfg_tailq_read_unlock();
  41
  42        if (te == NULL) {
  43                rte_errno = ENOENT;
  44                return NULL;
  45        }
  46        return setsum;
  47}
  48
  49void
  50rte_member_free(struct rte_member_setsum *setsum)
  51{
  52        struct rte_member_list *member_list;
  53        struct rte_tailq_entry *te;
  54
  55        if (setsum == NULL)
  56                return;
  57        member_list = RTE_TAILQ_CAST(rte_member_tailq.head, rte_member_list);
  58        rte_mcfg_tailq_write_lock();
  59        TAILQ_FOREACH(te, member_list, next) {
  60                if (te->data == (void *)setsum)
  61                        break;
  62        }
  63        if (te == NULL) {
  64                rte_mcfg_tailq_write_unlock();
  65                return;
  66        }
  67        TAILQ_REMOVE(member_list, te, next);
  68        rte_mcfg_tailq_write_unlock();
  69
  70        switch (setsum->type) {
  71        case RTE_MEMBER_TYPE_HT:
  72                rte_member_free_ht(setsum);
  73                break;
  74        case RTE_MEMBER_TYPE_VBF:
  75                rte_member_free_vbf(setsum);
  76                break;
  77        default:
  78                break;
  79        }
  80        rte_free(setsum);
  81        rte_free(te);
  82}
  83
  84struct rte_member_setsum *
  85rte_member_create(const struct rte_member_parameters *params)
  86{
  87        struct rte_tailq_entry *te;
  88        struct rte_member_list *member_list;
  89        struct rte_member_setsum *setsum;
  90        int ret;
  91
  92        if (params == NULL) {
  93                rte_errno = EINVAL;
  94                return NULL;
  95        }
  96
  97        if (params->key_len == 0 ||
  98                        params->prim_hash_seed == params->sec_hash_seed) {
  99                rte_errno = EINVAL;
 100                RTE_MEMBER_LOG(ERR, "Create setsummary with "
 101                                        "invalid parameters\n");
 102                return NULL;
 103        }
 104
 105        member_list = RTE_TAILQ_CAST(rte_member_tailq.head, rte_member_list);
 106
 107        rte_mcfg_tailq_write_lock();
 108
 109        TAILQ_FOREACH(te, member_list, next) {
 110                setsum = te->data;
 111                if (strncmp(params->name, setsum->name,
 112                                RTE_MEMBER_NAMESIZE) == 0)
 113                        break;
 114        }
 115        setsum = NULL;
 116        if (te != NULL) {
 117                rte_errno = EEXIST;
 118                te = NULL;
 119                goto error_unlock_exit;
 120        }
 121        te = rte_zmalloc("MEMBER_TAILQ_ENTRY", sizeof(*te), 0);
 122        if (te == NULL) {
 123                RTE_MEMBER_LOG(ERR, "tailq entry allocation failed\n");
 124                goto error_unlock_exit;
 125        }
 126
 127        /* Create a new setsum structure */
 128        setsum = rte_zmalloc_socket(params->name,
 129                        sizeof(struct rte_member_setsum), RTE_CACHE_LINE_SIZE,
 130                        params->socket_id);
 131        if (setsum == NULL) {
 132                RTE_MEMBER_LOG(ERR, "Create setsummary failed\n");
 133                goto error_unlock_exit;
 134        }
 135        strlcpy(setsum->name, params->name, sizeof(setsum->name));
 136        setsum->type = params->type;
 137        setsum->socket_id = params->socket_id;
 138        setsum->key_len = params->key_len;
 139        setsum->num_set = params->num_set;
 140        setsum->prim_hash_seed = params->prim_hash_seed;
 141        setsum->sec_hash_seed = params->sec_hash_seed;
 142
 143        switch (setsum->type) {
 144        case RTE_MEMBER_TYPE_HT:
 145                ret = rte_member_create_ht(setsum, params);
 146                break;
 147        case RTE_MEMBER_TYPE_VBF:
 148                ret = rte_member_create_vbf(setsum, params);
 149                break;
 150        default:
 151                goto error_unlock_exit;
 152        }
 153        if (ret < 0)
 154                goto error_unlock_exit;
 155
 156        RTE_MEMBER_LOG(DEBUG, "Creating a setsummary table with "
 157                        "mode %u\n", setsum->type);
 158
 159        te->data = (void *)setsum;
 160        TAILQ_INSERT_TAIL(member_list, te, next);
 161        rte_mcfg_tailq_write_unlock();
 162        return setsum;
 163
 164error_unlock_exit:
 165        rte_free(te);
 166        rte_free(setsum);
 167        rte_mcfg_tailq_write_unlock();
 168        return NULL;
 169}
 170
 171int
 172rte_member_add(const struct rte_member_setsum *setsum, const void *key,
 173                        member_set_t set_id)
 174{
 175        if (setsum == NULL || key == NULL)
 176                return -EINVAL;
 177
 178        switch (setsum->type) {
 179        case RTE_MEMBER_TYPE_HT:
 180                return rte_member_add_ht(setsum, key, set_id);
 181        case RTE_MEMBER_TYPE_VBF:
 182                return rte_member_add_vbf(setsum, key, set_id);
 183        default:
 184                return -EINVAL;
 185        }
 186}
 187
 188int
 189rte_member_lookup(const struct rte_member_setsum *setsum, const void *key,
 190                        member_set_t *set_id)
 191{
 192        if (setsum == NULL || key == NULL || set_id == NULL)
 193                return -EINVAL;
 194
 195        switch (setsum->type) {
 196        case RTE_MEMBER_TYPE_HT:
 197                return rte_member_lookup_ht(setsum, key, set_id);
 198        case RTE_MEMBER_TYPE_VBF:
 199                return rte_member_lookup_vbf(setsum, key, set_id);
 200        default:
 201                return -EINVAL;
 202        }
 203}
 204
 205int
 206rte_member_lookup_bulk(const struct rte_member_setsum *setsum,
 207                                const void **keys, uint32_t num_keys,
 208                                member_set_t *set_ids)
 209{
 210        if (setsum == NULL || keys == NULL || set_ids == NULL)
 211                return -EINVAL;
 212
 213        switch (setsum->type) {
 214        case RTE_MEMBER_TYPE_HT:
 215                return rte_member_lookup_bulk_ht(setsum, keys, num_keys,
 216                                set_ids);
 217        case RTE_MEMBER_TYPE_VBF:
 218                return rte_member_lookup_bulk_vbf(setsum, keys, num_keys,
 219                                set_ids);
 220        default:
 221                return -EINVAL;
 222        }
 223}
 224
 225int
 226rte_member_lookup_multi(const struct rte_member_setsum *setsum, const void *key,
 227                                uint32_t match_per_key, member_set_t *set_id)
 228{
 229        if (setsum == NULL || key == NULL || set_id == NULL)
 230                return -EINVAL;
 231
 232        switch (setsum->type) {
 233        case RTE_MEMBER_TYPE_HT:
 234                return rte_member_lookup_multi_ht(setsum, key, match_per_key,
 235                                set_id);
 236        case RTE_MEMBER_TYPE_VBF:
 237                return rte_member_lookup_multi_vbf(setsum, key, match_per_key,
 238                                set_id);
 239        default:
 240                return -EINVAL;
 241        }
 242}
 243
 244int
 245rte_member_lookup_multi_bulk(const struct rte_member_setsum *setsum,
 246                        const void **keys, uint32_t num_keys,
 247                        uint32_t max_match_per_key, uint32_t *match_count,
 248                        member_set_t *set_ids)
 249{
 250        if (setsum == NULL || keys == NULL || set_ids == NULL ||
 251                        match_count == NULL)
 252                return -EINVAL;
 253
 254        switch (setsum->type) {
 255        case RTE_MEMBER_TYPE_HT:
 256                return rte_member_lookup_multi_bulk_ht(setsum, keys, num_keys,
 257                                max_match_per_key, match_count, set_ids);
 258        case RTE_MEMBER_TYPE_VBF:
 259                return rte_member_lookup_multi_bulk_vbf(setsum, keys, num_keys,
 260                                max_match_per_key, match_count, set_ids);
 261        default:
 262                return -EINVAL;
 263        }
 264}
 265
 266int
 267rte_member_delete(const struct rte_member_setsum *setsum, const void *key,
 268                        member_set_t set_id)
 269{
 270        if (setsum == NULL || key == NULL)
 271                return -EINVAL;
 272
 273        switch (setsum->type) {
 274        case RTE_MEMBER_TYPE_HT:
 275                return rte_member_delete_ht(setsum, key, set_id);
 276        /* current vBF implementation does not support delete function */
 277        case RTE_MEMBER_TYPE_VBF:
 278        default:
 279                return -EINVAL;
 280        }
 281}
 282
 283void
 284rte_member_reset(const struct rte_member_setsum *setsum)
 285{
 286        if (setsum == NULL)
 287                return;
 288        switch (setsum->type) {
 289        case RTE_MEMBER_TYPE_HT:
 290                rte_member_reset_ht(setsum);
 291                return;
 292        case RTE_MEMBER_TYPE_VBF:
 293                rte_member_reset_vbf(setsum);
 294                return;
 295        default:
 296                return;
 297        }
 298}
 299
 300RTE_LOG_REGISTER_DEFAULT(librte_member_logtype, DEBUG);
 301