17b4f1e6bSMatan Azrad /* SPDX-License-Identifier: BSD-3-Clause 27b4f1e6bSMatan Azrad * Copyright 2019 Mellanox Technologies, Ltd 37b4f1e6bSMatan Azrad */ 47b4f1e6bSMatan Azrad 57b4f1e6bSMatan Azrad #ifndef RTE_PMD_MLX5_COMMON_UTILS_H_ 67b4f1e6bSMatan Azrad #define RTE_PMD_MLX5_COMMON_UTILS_H_ 77b4f1e6bSMatan Azrad 87b4f1e6bSMatan Azrad #include "mlx5_common.h" 97b4f1e6bSMatan Azrad 10*25245d5dSShiri Kuzin #define MLX5_HLIST_DIRECT_KEY 0x0001 /* Use the key directly as hash index. */ 11*25245d5dSShiri Kuzin #define MLX5_HLIST_WRITE_MOST 0x0002 /* List mostly used for append new. */ 127b4f1e6bSMatan Azrad 13*25245d5dSShiri Kuzin /** Maximum size of string for naming the hlist table. */ 14*25245d5dSShiri Kuzin #define MLX5_HLIST_NAMESIZE 32 157b4f1e6bSMatan Azrad 16*25245d5dSShiri Kuzin struct mlx5_hlist; 17*25245d5dSShiri Kuzin 18*25245d5dSShiri Kuzin /** 19*25245d5dSShiri Kuzin * Structure of the entry in the hash list, user should define its own struct 20*25245d5dSShiri Kuzin * that contains this in order to store the data. The 'key' is 64-bits right 21*25245d5dSShiri Kuzin * now and its user's responsibility to guarantee there is no collision. 22*25245d5dSShiri Kuzin */ 23*25245d5dSShiri Kuzin struct mlx5_hlist_entry { 24*25245d5dSShiri Kuzin LIST_ENTRY(mlx5_hlist_entry) next; /* entry pointers in the list. */ 25*25245d5dSShiri Kuzin uint32_t idx; /* Bucket index the entry belongs to. */ 26*25245d5dSShiri Kuzin uint32_t ref_cnt; /* Reference count. */ 27*25245d5dSShiri Kuzin }; 28*25245d5dSShiri Kuzin 29*25245d5dSShiri Kuzin /** Structure for hash head. */ 30*25245d5dSShiri Kuzin LIST_HEAD(mlx5_hlist_head, mlx5_hlist_entry); 31*25245d5dSShiri Kuzin 32*25245d5dSShiri Kuzin /** 33*25245d5dSShiri Kuzin * Type of callback function for entry removal. 34*25245d5dSShiri Kuzin * 35*25245d5dSShiri Kuzin * @param list 36*25245d5dSShiri Kuzin * The hash list. 37*25245d5dSShiri Kuzin * @param entry 38*25245d5dSShiri Kuzin * The entry in the list. 39*25245d5dSShiri Kuzin */ 40*25245d5dSShiri Kuzin typedef void (*mlx5_hlist_remove_cb)(struct mlx5_hlist *list, 41*25245d5dSShiri Kuzin struct mlx5_hlist_entry *entry); 42*25245d5dSShiri Kuzin 43*25245d5dSShiri Kuzin /** 44*25245d5dSShiri Kuzin * Type of function for user defined matching. 45*25245d5dSShiri Kuzin * 46*25245d5dSShiri Kuzin * @param list 47*25245d5dSShiri Kuzin * The hash list. 48*25245d5dSShiri Kuzin * @param entry 49*25245d5dSShiri Kuzin * The entry in the list. 50*25245d5dSShiri Kuzin * @param key 51*25245d5dSShiri Kuzin * The new entry key. 52*25245d5dSShiri Kuzin * @param ctx 53*25245d5dSShiri Kuzin * The pointer to new entry context. 54*25245d5dSShiri Kuzin * 55*25245d5dSShiri Kuzin * @return 56*25245d5dSShiri Kuzin * 0 if matching, non-zero number otherwise. 57*25245d5dSShiri Kuzin */ 58*25245d5dSShiri Kuzin typedef int (*mlx5_hlist_match_cb)(struct mlx5_hlist *list, 59*25245d5dSShiri Kuzin struct mlx5_hlist_entry *entry, 60*25245d5dSShiri Kuzin uint64_t key, void *ctx); 61*25245d5dSShiri Kuzin 62*25245d5dSShiri Kuzin /** 63*25245d5dSShiri Kuzin * Type of function for user defined hash list entry creation. 64*25245d5dSShiri Kuzin * 65*25245d5dSShiri Kuzin * @param list 66*25245d5dSShiri Kuzin * The hash list. 67*25245d5dSShiri Kuzin * @param key 68*25245d5dSShiri Kuzin * The key of the new entry. 69*25245d5dSShiri Kuzin * @param ctx 70*25245d5dSShiri Kuzin * The pointer to new entry context. 71*25245d5dSShiri Kuzin * 72*25245d5dSShiri Kuzin * @return 73*25245d5dSShiri Kuzin * Pointer to allocated entry on success, NULL otherwise. 74*25245d5dSShiri Kuzin */ 75*25245d5dSShiri Kuzin typedef struct mlx5_hlist_entry *(*mlx5_hlist_create_cb) 76*25245d5dSShiri Kuzin (struct mlx5_hlist *list, 77*25245d5dSShiri Kuzin uint64_t key, void *ctx); 78*25245d5dSShiri Kuzin 79*25245d5dSShiri Kuzin /* Hash list bucket head. */ 80*25245d5dSShiri Kuzin struct mlx5_hlist_bucket { 81*25245d5dSShiri Kuzin struct mlx5_hlist_head head; /* List head. */ 82*25245d5dSShiri Kuzin rte_rwlock_t lock; /* Bucket lock. */ 83*25245d5dSShiri Kuzin uint32_t gen_cnt; /* List modification will update generation count. */ 84*25245d5dSShiri Kuzin } __rte_cache_aligned; 85*25245d5dSShiri Kuzin 86*25245d5dSShiri Kuzin /** 87*25245d5dSShiri Kuzin * Hash list table structure 88*25245d5dSShiri Kuzin * 89*25245d5dSShiri Kuzin * Entry in hash list could be reused if entry already exists, reference 90*25245d5dSShiri Kuzin * count will increase and the existing entry returns. 91*25245d5dSShiri Kuzin * 92*25245d5dSShiri Kuzin * When destroy an entry from list, decrease reference count and only 93*25245d5dSShiri Kuzin * destroy when no further reference. 94*25245d5dSShiri Kuzin */ 95*25245d5dSShiri Kuzin struct mlx5_hlist { 96*25245d5dSShiri Kuzin char name[MLX5_HLIST_NAMESIZE]; /**< Name of the hash list. */ 97*25245d5dSShiri Kuzin /**< number of heads, need to be power of 2. */ 98*25245d5dSShiri Kuzin uint32_t table_sz; 99*25245d5dSShiri Kuzin uint32_t entry_sz; /**< Size of entry, used to allocate entry. */ 100*25245d5dSShiri Kuzin /**< mask to get the index of the list heads. */ 101*25245d5dSShiri Kuzin uint32_t mask; 102*25245d5dSShiri Kuzin bool direct_key; /* Use the new entry key directly as hash index. */ 103*25245d5dSShiri Kuzin bool write_most; /* List mostly used for append new or destroy. */ 104*25245d5dSShiri Kuzin void *ctx; 105*25245d5dSShiri Kuzin mlx5_hlist_create_cb cb_create; /**< entry create callback. */ 106*25245d5dSShiri Kuzin mlx5_hlist_match_cb cb_match; /**< entry match callback. */ 107*25245d5dSShiri Kuzin mlx5_hlist_remove_cb cb_remove; /**< entry remove callback. */ 108*25245d5dSShiri Kuzin struct mlx5_hlist_bucket buckets[] __rte_cache_aligned; 109*25245d5dSShiri Kuzin /**< list bucket arrays. */ 110*25245d5dSShiri Kuzin }; 111*25245d5dSShiri Kuzin 112*25245d5dSShiri Kuzin /** 113*25245d5dSShiri Kuzin * Create a hash list table, the user can specify the list heads array size 114*25245d5dSShiri Kuzin * of the table, now the size should be a power of 2 in order to get better 115*25245d5dSShiri Kuzin * distribution for the entries. Each entry is a part of the whole data element 116*25245d5dSShiri Kuzin * and the caller should be responsible for the data element's allocation and 117*25245d5dSShiri Kuzin * cleanup / free. Key of each entry will be calculated with CRC in order to 118*25245d5dSShiri Kuzin * generate a little fairer distribution. 119*25245d5dSShiri Kuzin * 120*25245d5dSShiri Kuzin * @param name 121*25245d5dSShiri Kuzin * Name of the hash list(optional). 122*25245d5dSShiri Kuzin * @param size 123*25245d5dSShiri Kuzin * Heads array size of the hash list. 124*25245d5dSShiri Kuzin * @param entry_size 125*25245d5dSShiri Kuzin * Entry size to allocate if cb_create not specified. 126*25245d5dSShiri Kuzin * @param flags 127*25245d5dSShiri Kuzin * The hash list attribute flags. 128*25245d5dSShiri Kuzin * @param cb_create 129*25245d5dSShiri Kuzin * Callback function for entry create. 130*25245d5dSShiri Kuzin * @param cb_match 131*25245d5dSShiri Kuzin * Callback function for entry match. 132*25245d5dSShiri Kuzin * @param cb_destroy 133*25245d5dSShiri Kuzin * Callback function for entry destroy. 134*25245d5dSShiri Kuzin * @return 135*25245d5dSShiri Kuzin * Pointer of the hash list table created, NULL on failure. 136*25245d5dSShiri Kuzin */ 137*25245d5dSShiri Kuzin __rte_internal 138*25245d5dSShiri Kuzin struct mlx5_hlist *mlx5_hlist_create(const char *name, uint32_t size, 139*25245d5dSShiri Kuzin uint32_t entry_size, uint32_t flags, 140*25245d5dSShiri Kuzin mlx5_hlist_create_cb cb_create, 141*25245d5dSShiri Kuzin mlx5_hlist_match_cb cb_match, 142*25245d5dSShiri Kuzin mlx5_hlist_remove_cb cb_destroy); 143*25245d5dSShiri Kuzin 144*25245d5dSShiri Kuzin /** 145*25245d5dSShiri Kuzin * Search an entry matching the key. 146*25245d5dSShiri Kuzin * 147*25245d5dSShiri Kuzin * Result returned might be destroyed by other thread, must use 148*25245d5dSShiri Kuzin * this function only in main thread. 149*25245d5dSShiri Kuzin * 150*25245d5dSShiri Kuzin * @param h 151*25245d5dSShiri Kuzin * Pointer to the hast list table. 152*25245d5dSShiri Kuzin * @param key 153*25245d5dSShiri Kuzin * Key for the searching entry. 154*25245d5dSShiri Kuzin * @param ctx 155*25245d5dSShiri Kuzin * Common context parameter used by entry callback function. 156*25245d5dSShiri Kuzin * 157*25245d5dSShiri Kuzin * @return 158*25245d5dSShiri Kuzin * Pointer of the hlist entry if found, NULL otherwise. 159*25245d5dSShiri Kuzin */ 160*25245d5dSShiri Kuzin __rte_internal 161*25245d5dSShiri Kuzin struct mlx5_hlist_entry *mlx5_hlist_lookup(struct mlx5_hlist *h, uint64_t key, 162*25245d5dSShiri Kuzin void *ctx); 163*25245d5dSShiri Kuzin 164*25245d5dSShiri Kuzin /** 165*25245d5dSShiri Kuzin * Insert an entry to the hash list table, the entry is only part of whole data 166*25245d5dSShiri Kuzin * element and a 64B key is used for matching. User should construct the key or 167*25245d5dSShiri Kuzin * give a calculated hash signature and guarantee there is no collision. 168*25245d5dSShiri Kuzin * 169*25245d5dSShiri Kuzin * @param h 170*25245d5dSShiri Kuzin * Pointer to the hast list table. 171*25245d5dSShiri Kuzin * @param entry 172*25245d5dSShiri Kuzin * Entry to be inserted into the hash list table. 173*25245d5dSShiri Kuzin * @param ctx 174*25245d5dSShiri Kuzin * Common context parameter used by callback function. 175*25245d5dSShiri Kuzin * 176*25245d5dSShiri Kuzin * @return 177*25245d5dSShiri Kuzin * registered entry on success, NULL otherwise 178*25245d5dSShiri Kuzin */ 179*25245d5dSShiri Kuzin __rte_internal 180*25245d5dSShiri Kuzin struct mlx5_hlist_entry *mlx5_hlist_register(struct mlx5_hlist *h, uint64_t key, 181*25245d5dSShiri Kuzin void *ctx); 182*25245d5dSShiri Kuzin 183*25245d5dSShiri Kuzin /** 184*25245d5dSShiri Kuzin * Remove an entry from the hash list table. User should guarantee the validity 185*25245d5dSShiri Kuzin * of the entry. 186*25245d5dSShiri Kuzin * 187*25245d5dSShiri Kuzin * @param h 188*25245d5dSShiri Kuzin * Pointer to the hast list table. (not used) 189*25245d5dSShiri Kuzin * @param entry 190*25245d5dSShiri Kuzin * Entry to be removed from the hash list table. 191*25245d5dSShiri Kuzin * @return 192*25245d5dSShiri Kuzin * 0 on entry removed, 1 on entry still referenced. 193*25245d5dSShiri Kuzin */ 194*25245d5dSShiri Kuzin __rte_internal 195*25245d5dSShiri Kuzin int mlx5_hlist_unregister(struct mlx5_hlist *h, struct mlx5_hlist_entry *entry); 196*25245d5dSShiri Kuzin 197*25245d5dSShiri Kuzin /** 198*25245d5dSShiri Kuzin * Destroy the hash list table, all the entries already inserted into the lists 199*25245d5dSShiri Kuzin * will be handled by the callback function provided by the user (including 200*25245d5dSShiri Kuzin * free if needed) before the table is freed. 201*25245d5dSShiri Kuzin * 202*25245d5dSShiri Kuzin * @param h 203*25245d5dSShiri Kuzin * Pointer to the hast list table. 204*25245d5dSShiri Kuzin */ 205*25245d5dSShiri Kuzin __rte_internal 206*25245d5dSShiri Kuzin void mlx5_hlist_destroy(struct mlx5_hlist *h); 2077b4f1e6bSMatan Azrad 2087b4f1e6bSMatan Azrad #endif /* RTE_PMD_MLX5_COMMON_UTILS_H_ */ 209