dpdk/lib/hash/rte_cuckoo_hash.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2016 Intel Corporation
   3 * Copyright(c) 2018 Arm Limited
   4 */
   5
   6/* rte_cuckoo_hash.h
   7 * This file hold Cuckoo Hash private data structures to allows include from
   8 * platform specific files like rte_cuckoo_hash_x86.h
   9 */
  10
  11#ifndef _RTE_CUCKOO_HASH_H_
  12#define _RTE_CUCKOO_HASH_H_
  13
  14#if defined(RTE_ARCH_X86)
  15#include "rte_cmp_x86.h"
  16#endif
  17
  18#if defined(RTE_ARCH_ARM64)
  19#include "rte_cmp_arm64.h"
  20#endif
  21
  22/* Macro to enable/disable run-time checking of function parameters */
  23#if defined(RTE_LIBRTE_HASH_DEBUG)
  24#define RETURN_IF_TRUE(cond, retval) do { \
  25        if (cond) \
  26                return retval; \
  27} while (0)
  28#else
  29#define RETURN_IF_TRUE(cond, retval)
  30#endif
  31
  32#if defined(RTE_LIBRTE_HASH_DEBUG)
  33#define ERR_IF_TRUE(cond, fmt, args...) do { \
  34        if (cond) { \
  35                RTE_LOG(ERR, HASH, fmt, ##args); \
  36                return; \
  37        } \
  38} while (0)
  39#else
  40#define ERR_IF_TRUE(cond, fmt, args...)
  41#endif
  42
  43#include <rte_hash_crc.h>
  44#include <rte_jhash.h>
  45
  46#if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64)
  47/*
  48 * All different options to select a key compare function,
  49 * based on the key size and custom function.
  50 */
  51enum cmp_jump_table_case {
  52        KEY_CUSTOM = 0,
  53        KEY_16_BYTES,
  54        KEY_32_BYTES,
  55        KEY_48_BYTES,
  56        KEY_64_BYTES,
  57        KEY_80_BYTES,
  58        KEY_96_BYTES,
  59        KEY_112_BYTES,
  60        KEY_128_BYTES,
  61        KEY_OTHER_BYTES,
  62        NUM_KEY_CMP_CASES,
  63};
  64
  65/*
  66 * Table storing all different key compare functions
  67 * (multi-process supported)
  68 */
  69const rte_hash_cmp_eq_t cmp_jump_table[NUM_KEY_CMP_CASES] = {
  70        NULL,
  71        rte_hash_k16_cmp_eq,
  72        rte_hash_k32_cmp_eq,
  73        rte_hash_k48_cmp_eq,
  74        rte_hash_k64_cmp_eq,
  75        rte_hash_k80_cmp_eq,
  76        rte_hash_k96_cmp_eq,
  77        rte_hash_k112_cmp_eq,
  78        rte_hash_k128_cmp_eq,
  79        memcmp
  80};
  81#else
  82/*
  83 * All different options to select a key compare function,
  84 * based on the key size and custom function.
  85 */
  86enum cmp_jump_table_case {
  87        KEY_CUSTOM = 0,
  88        KEY_OTHER_BYTES,
  89        NUM_KEY_CMP_CASES,
  90};
  91
  92/*
  93 * Table storing all different key compare functions
  94 * (multi-process supported)
  95 */
  96const rte_hash_cmp_eq_t cmp_jump_table[NUM_KEY_CMP_CASES] = {
  97        NULL,
  98        memcmp
  99};
 100
 101#endif
 102
 103
 104/** Number of items per bucket. */
 105#define RTE_HASH_BUCKET_ENTRIES         8
 106
 107#if !RTE_IS_POWER_OF_2(RTE_HASH_BUCKET_ENTRIES)
 108#error RTE_HASH_BUCKET_ENTRIES must be a power of 2
 109#endif
 110
 111#define NULL_SIGNATURE                  0
 112
 113#define EMPTY_SLOT                      0
 114
 115#define KEY_ALIGNMENT                   16
 116
 117#define LCORE_CACHE_SIZE                64
 118
 119#define RTE_HASH_BFS_QUEUE_MAX_LEN       1000
 120
 121#define RTE_XABORT_CUCKOO_PATH_INVALIDED 0x4
 122
 123#define RTE_HASH_TSX_MAX_RETRY  10
 124
 125struct lcore_cache {
 126        unsigned len; /**< Cache len */
 127        uint32_t objs[LCORE_CACHE_SIZE]; /**< Cache objects */
 128} __rte_cache_aligned;
 129
 130/* Structure that stores key-value pair */
 131struct rte_hash_key {
 132        union {
 133                uintptr_t idata;
 134                void *pdata;
 135        };
 136        /* Variable key size */
 137        char key[0];
 138};
 139
 140/* All different signature compare functions */
 141enum rte_hash_sig_compare_function {
 142        RTE_HASH_COMPARE_SCALAR = 0,
 143        RTE_HASH_COMPARE_SSE,
 144        RTE_HASH_COMPARE_NEON,
 145        RTE_HASH_COMPARE_NUM
 146};
 147
 148/** Bucket structure */
 149struct rte_hash_bucket {
 150        uint16_t sig_current[RTE_HASH_BUCKET_ENTRIES];
 151
 152        uint32_t key_idx[RTE_HASH_BUCKET_ENTRIES];
 153
 154        uint8_t flag[RTE_HASH_BUCKET_ENTRIES];
 155
 156        void *next;
 157} __rte_cache_aligned;
 158
 159/** A hash table structure. */
 160struct rte_hash {
 161        char name[RTE_HASH_NAMESIZE];   /**< Name of the hash. */
 162        uint32_t entries;               /**< Total table entries. */
 163        uint32_t num_buckets;           /**< Number of buckets in table. */
 164
 165        struct rte_ring *free_slots;
 166        /**< Ring that stores all indexes of the free slots in the key table */
 167
 168        struct lcore_cache *local_free_slots;
 169        /**< Local cache per lcore, storing some indexes of the free slots */
 170
 171        /* RCU config */
 172        struct rte_hash_rcu_config *hash_rcu_cfg;
 173        /**< HASH RCU QSBR configuration structure */
 174        struct rte_rcu_qsbr_dq *dq;     /**< RCU QSBR defer queue. */
 175
 176        /* Fields used in lookup */
 177
 178        uint32_t key_len __rte_cache_aligned;
 179        /**< Length of hash key. */
 180        uint8_t hw_trans_mem_support;
 181        /**< If hardware transactional memory is used. */
 182        uint8_t use_local_cache;
 183        /**< If multi-writer support is enabled, use local cache
 184         * to allocate key-store slots.
 185         */
 186        uint8_t readwrite_concur_support;
 187        /**< If read-write concurrency support is enabled */
 188        uint8_t ext_table_support;     /**< Enable extendable bucket table */
 189        uint8_t no_free_on_del;
 190        /**< If key index should be freed on calling rte_hash_del_xxx APIs.
 191         * If this is set, rte_hash_free_key_with_position must be called to
 192         * free the key index associated with the deleted entry.
 193         * This flag is enabled by default.
 194         */
 195        uint8_t readwrite_concur_lf_support;
 196        /**< If read-write concurrency lock free support is enabled */
 197        uint8_t writer_takes_lock;
 198        /**< Indicates if the writer threads need to take lock */
 199        rte_hash_function hash_func;    /**< Function used to calculate hash. */
 200        uint32_t hash_func_init_val;    /**< Init value used by hash_func. */
 201        rte_hash_cmp_eq_t rte_hash_custom_cmp_eq;
 202        /**< Custom function used to compare keys. */
 203        enum cmp_jump_table_case cmp_jump_table_idx;
 204        /**< Indicates which compare function to use. */
 205        enum rte_hash_sig_compare_function sig_cmp_fn;
 206        /**< Indicates which signature compare function to use. */
 207        uint32_t bucket_bitmask;
 208        /**< Bitmask for getting bucket index from hash signature. */
 209        uint32_t key_entry_size;         /**< Size of each key entry. */
 210
 211        void *key_store;                /**< Table storing all keys and data */
 212        struct rte_hash_bucket *buckets;
 213        /**< Table with buckets storing all the hash values and key indexes
 214         * to the key table.
 215         */
 216        rte_rwlock_t *readwrite_lock; /**< Read-write lock thread-safety. */
 217        struct rte_hash_bucket *buckets_ext; /**< Extra buckets array */
 218        struct rte_ring *free_ext_bkts; /**< Ring of indexes of free buckets */
 219        /* Stores index of an empty ext bkt to be recycled on calling
 220         * rte_hash_del_xxx APIs. When lock free read-write concurrency is
 221         * enabled, an empty ext bkt cannot be put into free list immediately
 222         * (as readers might be using it still). Hence freeing of the ext bkt
 223         * is piggy-backed to freeing of the key index.
 224         */
 225        uint32_t *ext_bkt_to_free;
 226        uint32_t *tbl_chng_cnt;
 227        /**< Indicates if the hash table changed from last read. */
 228} __rte_cache_aligned;
 229
 230struct queue_node {
 231        struct rte_hash_bucket *bkt; /* Current bucket on the bfs search */
 232        uint32_t cur_bkt_idx;
 233
 234        struct queue_node *prev;     /* Parent(bucket) in search path */
 235        int prev_slot;               /* Parent(slot) in search path */
 236};
 237
 238/** @internal Default RCU defer queue entries to reclaim in one go. */
 239#define RTE_HASH_RCU_DQ_RECLAIM_MAX     16
 240
 241#endif
 242