@@ -13,25 +13,21 @@
/********************* mlx5 list ************************/
-struct mlx5_list *
-mlx5_list_create(const char *name, void *ctx, bool lcores_share,
- mlx5_list_create_cb cb_create,
- mlx5_list_match_cb cb_match,
- mlx5_list_remove_cb cb_remove,
- mlx5_list_clone_cb cb_clone,
- mlx5_list_clone_free_cb cb_clone_free)
+static int
+mlx5_list_init(struct mlx5_list *list, const char *name, void *ctx,
+ bool lcores_share, mlx5_list_create_cb cb_create,
+ mlx5_list_match_cb cb_match,
+ mlx5_list_remove_cb cb_remove,
+ mlx5_list_clone_cb cb_clone,
+ mlx5_list_clone_free_cb cb_clone_free)
{
- struct mlx5_list *list;
int i;
if (!cb_match || !cb_create || !cb_remove || !cb_clone ||
!cb_clone_free) {
rte_errno = EINVAL;
- return NULL;
+ return -EINVAL;
}
- list = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*list), 0, SOCKET_ID_ANY);
- if (!list)
- return NULL;
if (name)
snprintf(list->name, sizeof(list->name), "%s", name);
list->ctx = ctx;
@@ -45,6 +41,28 @@ mlx5_list_create(const char *name, void *ctx, bool lcores_share,
DRV_LOG(DEBUG, "mlx5 list %s initialized.", list->name);
for (i = 0; i <= RTE_MAX_LCORE; i++)
LIST_INIT(&list->cache[i].h);
+ return 0;
+}
+
+struct mlx5_list *
+mlx5_list_create(const char *name, void *ctx, bool lcores_share,
+ mlx5_list_create_cb cb_create,
+ mlx5_list_match_cb cb_match,
+ mlx5_list_remove_cb cb_remove,
+ mlx5_list_clone_cb cb_clone,
+ mlx5_list_clone_free_cb cb_clone_free)
+{
+ struct mlx5_list *list;
+
+ list = mlx5_malloc(MLX5_MEM_ZERO, sizeof(*list), 0, SOCKET_ID_ANY);
+ if (!list)
+ return NULL;
+ if (mlx5_list_init(list, name, ctx, lcores_share,
+ cb_create, cb_match, cb_remove, cb_clone,
+ cb_clone_free) != 0) {
+ mlx5_free(list);
+ return NULL;
+ }
return list;
}
@@ -254,8 +272,8 @@ mlx5_list_unregister(struct mlx5_list *list,
return 1;
}
-void
-mlx5_list_destroy(struct mlx5_list *list)
+static void
+mlx5_list_uninit(struct mlx5_list *list)
{
struct mlx5_list_entry *entry;
int i;
@@ -266,15 +284,21 @@ mlx5_list_destroy(struct mlx5_list *list)
entry = LIST_FIRST(&list->cache[i].h);
LIST_REMOVE(entry, next);
if (i == RTE_MAX_LCORE) {
- list->cb_remove(list, entry);
+ list->cb_remove(list->ctx, entry);
DRV_LOG(DEBUG, "mlx5 list %s entry %p "
"destroyed.", list->name,
(void *)entry);
} else {
- list->cb_clone_free(list, entry);
+ list->cb_clone_free(list->ctx, entry);
}
}
}
+}
+
+void
+mlx5_list_destroy(struct mlx5_list *list)
+{
+ mlx5_list_uninit(list);
mlx5_free(list);
}
@@ -287,37 +311,24 @@ mlx5_list_get_entry_num(struct mlx5_list *list)
/********************* Hash List **********************/
-static struct mlx5_hlist_entry *
-mlx5_hlist_default_create_cb(struct mlx5_hlist *h, uint64_t key __rte_unused,
- void *ctx __rte_unused)
-{
- return mlx5_malloc(MLX5_MEM_ZERO, h->entry_sz, 0, SOCKET_ID_ANY);
-}
-
-static void
-mlx5_hlist_default_remove_cb(struct mlx5_hlist *h __rte_unused,
- struct mlx5_hlist_entry *entry)
-{
- mlx5_free(entry);
-}
-
struct mlx5_hlist *
-mlx5_hlist_create(const char *name, uint32_t size, uint32_t entry_size,
- uint32_t flags, mlx5_hlist_create_cb cb_create,
- mlx5_hlist_match_cb cb_match, mlx5_hlist_remove_cb cb_remove)
+mlx5_hlist_create(const char *name, uint32_t size, bool direct_key,
+ bool lcores_share, void *ctx, mlx5_list_create_cb cb_create,
+ mlx5_list_match_cb cb_match,
+ mlx5_list_remove_cb cb_remove,
+ mlx5_list_clone_cb cb_clone,
+ mlx5_list_clone_free_cb cb_clone_free)
{
struct mlx5_hlist *h;
uint32_t act_size;
uint32_t alloc_size;
uint32_t i;
- if (!size || !cb_match || (!cb_create ^ !cb_remove))
- return NULL;
/* Align to the next power of 2, 32bits integer is enough now. */
if (!rte_is_power_of_2(size)) {
act_size = rte_align32pow2(size);
- DRV_LOG(DEBUG, "Size 0x%" PRIX32 " is not power of 2, "
- "will be aligned to 0x%" PRIX32 ".", size, act_size);
+ DRV_LOG(WARNING, "Size 0x%" PRIX32 " is not power of 2, will "
+ "be aligned to 0x%" PRIX32 ".", size, act_size);
} else {
act_size = size;
}
@@ -331,61 +342,24 @@ mlx5_hlist_create(const char *name, uint32_t size, uint32_t entry_size,
name ? name : "None");
return NULL;
}
- if (name)
- snprintf(h->name, MLX5_HLIST_NAMESIZE, "%s", name);
- h->table_sz = act_size;
h->mask = act_size - 1;
- h->entry_sz = entry_size;
- h->direct_key = !!(flags & MLX5_HLIST_DIRECT_KEY);
- h->write_most = !!(flags & MLX5_HLIST_WRITE_MOST);
- h->cb_create = cb_create ? cb_create : mlx5_hlist_default_create_cb;
- h->cb_match = cb_match;
- h->cb_remove = cb_remove ? cb_remove : mlx5_hlist_default_remove_cb;
- for (i = 0; i < act_size; i++)
- rte_rwlock_init(&h->buckets[i].lock);
- DRV_LOG(DEBUG, "Hash list with %s size 0x%" PRIX32 " is created.",
- h->name, act_size);
- return h;
-}
-
-static struct mlx5_hlist_entry *
-__hlist_lookup(struct mlx5_hlist *h, uint64_t key, uint32_t idx,
- void *ctx, bool reuse)
-{
- struct mlx5_hlist_head *first;
- struct mlx5_hlist_entry *node;
-
- MLX5_ASSERT(h);
- first = &h->buckets[idx].head;
- LIST_FOREACH(node, first, next) {
- if (!h->cb_match(h, node, key, ctx)) {
- if (reuse) {
- __atomic_add_fetch(&node->ref_cnt, 1,
- __ATOMIC_RELAXED);
- DRV_LOG(DEBUG, "Hash list %s entry %p "
- "reuse: %u.",
- h->name, (void *)node, node->ref_cnt);
- }
- break;
+ h->lcores_share = lcores_share;
+ h->direct_key = direct_key;
+ for (i = 0; i < act_size; i++) {
+ if (mlx5_list_init(&h->buckets[i].l, name, ctx, lcores_share,
+ cb_create, cb_match, cb_remove, cb_clone,
+ cb_clone_free) != 0) {
+ mlx5_free(h);
+ return NULL;
}
}
- return node;
+ DRV_LOG(DEBUG, "Hash list %s with size 0x%" PRIX32 " was created.",
+ name, act_size);
+ return h;
}
-static struct mlx5_hlist_entry *
-hlist_lookup(struct mlx5_hlist *h, uint64_t key, uint32_t idx,
- void *ctx, bool reuse)
-{
- struct mlx5_hlist_entry *node;
-
- MLX5_ASSERT(h);
- rte_rwlock_read_lock(&h->buckets[idx].lock);
- node = __hlist_lookup(h, key, idx, ctx, reuse);
- rte_rwlock_read_unlock(&h->buckets[idx].lock);
- return node;
-}
-struct mlx5_hlist_entry *
+struct mlx5_list_entry *
mlx5_hlist_lookup(struct mlx5_hlist *h, uint64_t key, void *ctx)
{
uint32_t idx;
@@ -394,102 +368,44 @@ mlx5_hlist_lookup(struct mlx5_hlist *h, uint64_t key, void *ctx)
idx = (uint32_t)(key & h->mask);
else
idx = rte_hash_crc_8byte(key, 0) & h->mask;
- return hlist_lookup(h, key, idx, ctx, false);
+ return mlx5_list_lookup(&h->buckets[idx].l, ctx);
}
-struct mlx5_hlist_entry*
+struct mlx5_list_entry*
mlx5_hlist_register(struct mlx5_hlist *h, uint64_t key, void *ctx)
{
uint32_t idx;
- struct mlx5_hlist_head *first;
- struct mlx5_hlist_bucket *b;
- struct mlx5_hlist_entry *entry;
- uint32_t prev_gen_cnt = 0;
+ struct mlx5_list_entry *entry;
if (h->direct_key)
idx = (uint32_t)(key & h->mask);
else
idx = rte_hash_crc_8byte(key, 0) & h->mask;
- MLX5_ASSERT(h);
- b = &h->buckets[idx];
- /* Use write lock directly for write-most list. */
- if (!h->write_most) {
- prev_gen_cnt = __atomic_load_n(&b->gen_cnt, __ATOMIC_ACQUIRE);
- entry = hlist_lookup(h, key, idx, ctx, true);
- if (entry)
- return entry;
- }
- rte_rwlock_write_lock(&b->lock);
- /* Check if the list changed by other threads. */
- if (h->write_most ||
- prev_gen_cnt != __atomic_load_n(&b->gen_cnt, __ATOMIC_ACQUIRE)) {
- entry = __hlist_lookup(h, key, idx, ctx, true);
- if (entry)
- goto done;
- }
- first = &b->head;
- entry = h->cb_create(h, key, ctx);
- if (!entry) {
- rte_errno = ENOMEM;
- DRV_LOG(DEBUG, "Can't allocate hash list %s entry.", h->name);
- goto done;
+ entry = mlx5_list_register(&h->buckets[idx].l, ctx);
+ if (likely(entry)) {
+ if (h->lcores_share)
+ entry->gentry->bucket_idx = idx;
+ else
+ entry->bucket_idx = idx;
}
- entry->idx = idx;
- entry->ref_cnt = 1;
- LIST_INSERT_HEAD(first, entry, next);
- __atomic_add_fetch(&b->gen_cnt, 1, __ATOMIC_ACQ_REL);
- DRV_LOG(DEBUG, "Hash list %s entry %p new: %u.",
- h->name, (void *)entry, entry->ref_cnt);
-done:
- rte_rwlock_write_unlock(&b->lock);
return entry;
}
int
-mlx5_hlist_unregister(struct mlx5_hlist *h, struct mlx5_hlist_entry *entry)
+mlx5_hlist_unregister(struct mlx5_hlist *h, struct mlx5_list_entry *entry)
{
- uint32_t idx = entry->idx;
-
- rte_rwlock_write_lock(&h->buckets[idx].lock);
- MLX5_ASSERT(entry && entry->ref_cnt && entry->next.le_prev);
- DRV_LOG(DEBUG, "Hash list %s entry %p deref: %u.",
- h->name, (void *)entry, entry->ref_cnt);
- if (--entry->ref_cnt) {
- rte_rwlock_write_unlock(&h->buckets[idx].lock);
- return 1;
- }
- LIST_REMOVE(entry, next);
- /* Set to NULL to get rid of removing action for more than once. */
- entry->next.le_prev = NULL;
- h->cb_remove(h, entry);
- rte_rwlock_write_unlock(&h->buckets[idx].lock);
- DRV_LOG(DEBUG, "Hash list %s entry %p removed.",
- h->name, (void *)entry);
- return 0;
+ uint32_t idx = h->lcores_share ? entry->gentry->bucket_idx :
+ entry->bucket_idx;
+
+ return mlx5_list_unregister(&h->buckets[idx].l, entry);
}
void
mlx5_hlist_destroy(struct mlx5_hlist *h)
{
- uint32_t idx;
- struct mlx5_hlist_entry *entry;
+ uint32_t i;
- MLX5_ASSERT(h);
- for (idx = 0; idx < h->table_sz; ++idx) {
- /* No LIST_FOREACH_SAFE, using while instead. */
- while (!LIST_EMPTY(&h->buckets[idx].head)) {
- entry = LIST_FIRST(&h->buckets[idx].head);
- LIST_REMOVE(entry, next);
- /*
- * The owner of whole element which contains data entry
- * is the user, so it's the user's duty to do the clean
- * up and the free work because someone may not put the
- * hlist entry at the beginning(suggested to locate at
- * the beginning). Or else the default free function
- * will be used.
- */
- h->cb_remove(h, entry);
- }
- }
+ for (i = 0; i <= h->mask; i++)
+ mlx5_list_uninit(&h->buckets[i].l);
mlx5_free(h);
}
@@ -20,10 +20,13 @@ struct mlx5_list;
*/
struct mlx5_list_entry {
LIST_ENTRY(mlx5_list_entry) next; /* Entry pointers in the list. */
- uint32_t ref_cnt; /* 0 means, entry is invalid. */
+ uint32_t ref_cnt __rte_aligned(8); /* 0 means, entry is invalid. */
uint32_t lcore_idx;
- struct mlx5_list_entry *gentry;
-};
+ union {
+ struct mlx5_list_entry *gentry;
+ uint32_t bucket_idx;
+ };
+} __rte_packed;
struct mlx5_list_cache {
LIST_HEAD(mlx5_list_head, mlx5_list_entry) h;
@@ -212,108 +215,24 @@ __rte_internal
uint32_t
mlx5_list_get_entry_num(struct mlx5_list *list);
-/************************ Hash list *****************************/
-
-#define MLX5_HLIST_DIRECT_KEY 0x0001 /* Use the key directly as hash index. */
-#define MLX5_HLIST_WRITE_MOST 0x0002 /* List mostly used for append new. */
-
-/** Maximum size of string for naming the hlist table. */
-#define MLX5_HLIST_NAMESIZE 32
-
-struct mlx5_hlist;
-
-/**
- * Structure of the entry in the hash list, user should define its own struct
- * that contains this in order to store the data. The 'key' is 64-bits right
- * now and its user's responsibility to guarantee there is no collision.
- */
-struct mlx5_hlist_entry {
- LIST_ENTRY(mlx5_hlist_entry) next; /* entry pointers in the list. */
- uint32_t idx; /* Bucket index the entry belongs to. */
- uint32_t ref_cnt; /* Reference count. */
-};
-
-/** Structure for hash head. */
-LIST_HEAD(mlx5_hlist_head, mlx5_hlist_entry);
-
-/**
- * Type of callback function for entry removal.
- *
- * @param list
- * The hash list.
- * @param entry
- * The entry in the list.
- */
-typedef void (*mlx5_hlist_remove_cb)(struct mlx5_hlist *list,
- struct mlx5_hlist_entry *entry);
-
-/**
- * Type of function for user defined matching.
- *
- * @param list
- * The hash list.
- * @param entry
- * The entry in the list.
- * @param key
- * The new entry key.
- * @param ctx
- * The pointer to new entry context.
- *
- * @return
- * 0 if matching, non-zero number otherwise.
- */
-typedef int (*mlx5_hlist_match_cb)(struct mlx5_hlist *list,
- struct mlx5_hlist_entry *entry,
- uint64_t key, void *ctx);
-
-/**
- * Type of function for user defined hash list entry creation.
- *
- * @param list
- * The hash list.
- * @param key
- * The key of the new entry.
- * @param ctx
- * The pointer to new entry context.
- *
- * @return
- * Pointer to allocated entry on success, NULL otherwise.
- */
-typedef struct mlx5_hlist_entry *(*mlx5_hlist_create_cb)
- (struct mlx5_hlist *list,
- uint64_t key, void *ctx);
+/********************* Hash List **********************/
-/* Hash list bucket head. */
+/* Hash list bucket. */
struct mlx5_hlist_bucket {
- struct mlx5_hlist_head head; /* List head. */
- rte_rwlock_t lock; /* Bucket lock. */
- uint32_t gen_cnt; /* List modification will update generation count. */
+ struct mlx5_list l;
} __rte_cache_aligned;
/**
* Hash list table structure
*
- * Entry in hash list could be reused if entry already exists, reference
- * count will increase and the existing entry returns.
- *
- * When destroy an entry from list, decrease reference count and only
- * destroy when no further reference.
+ * The hash list bucket using the mlx5_list object for managing.
*/
struct mlx5_hlist {
- char name[MLX5_HLIST_NAMESIZE]; /**< Name of the hash list. */
- /**< number of heads, need to be power of 2. */
- uint32_t table_sz;
- uint32_t entry_sz; /**< Size of entry, used to allocate entry. */
- /**< mask to get the index of the list heads. */
- uint32_t mask;
- bool direct_key; /* Use the new entry key directly as hash index. */
- bool write_most; /* List mostly used for append new or destroy. */
- void *ctx;
- mlx5_hlist_create_cb cb_create; /**< entry create callback. */
- mlx5_hlist_match_cb cb_match; /**< entry match callback. */
- mlx5_hlist_remove_cb cb_remove; /**< entry remove callback. */
+ uint32_t mask; /* A mask for the bucket index range. */
+ uint8_t flags;
+ bool direct_key; /* Whether to use the key directly as hash index. */
+ bool lcores_share; /* Whether to share objects between the lcores. */
struct mlx5_hlist_bucket buckets[] __rte_cache_aligned;
- /**< list bucket arrays. */
};
/**
@@ -330,23 +249,33 @@ struct mlx5_hlist {
* Heads array size of the hash list.
* @param entry_size
* Entry size to allocate if cb_create not specified.
- * @param flags
- * The hash list attribute flags.
+ * @param direct key
+ * Whether to use the key directly as hash index.
+ * @param lcores_share
+ * Whether to share objects between the lcores.
+ * @param ctx
+ * The hlist instance context.
* @param cb_create
* Callback function for entry create.
* @param cb_match
* Callback function for entry match.
- * @param cb_destroy
- * Callback function for entry destroy.
+ * @param cb_remove
+ * Callback function for entry remove.
+ * @param cb_clone
+ * Callback function for entry clone.
+ * @param cb_clone_free
+ * Callback function for entry clone free.
* @return
* Pointer of the hash list table created, NULL on failure.
*/
__rte_internal
struct mlx5_hlist *mlx5_hlist_create(const char *name, uint32_t size,
- uint32_t entry_size, uint32_t flags,
- mlx5_hlist_create_cb cb_create,
- mlx5_hlist_match_cb cb_match,
- mlx5_hlist_remove_cb cb_destroy);
+ bool direct_key, bool lcores_share,
+ void *ctx, mlx5_list_create_cb cb_create,
+ mlx5_list_match_cb cb_match,
+ mlx5_list_remove_cb cb_remove,
+ mlx5_list_clone_cb cb_clone,
+ mlx5_list_clone_free_cb cb_clone_free);
/**
* Search an entry matching the key.
@@ -365,7 +294,7 @@ struct mlx5_hlist *mlx5_hlist_create(const char *name, uint32_t size,
* Pointer of the hlist entry if found, NULL otherwise.
*/
__rte_internal
-struct mlx5_hlist_entry *mlx5_hlist_lookup(struct mlx5_hlist *h, uint64_t key,
+struct mlx5_list_entry *mlx5_hlist_lookup(struct mlx5_hlist *h, uint64_t key,
void *ctx);
/**
@@ -384,7 +313,7 @@ struct mlx5_hlist_entry *mlx5_hlist_lookup(struct mlx5_hlist *h, uint64_t key,
* registered entry on success, NULL otherwise
*/
__rte_internal
-struct mlx5_hlist_entry *mlx5_hlist_register(struct mlx5_hlist *h, uint64_t key,
+struct mlx5_list_entry *mlx5_hlist_register(struct mlx5_hlist *h, uint64_t key,
void *ctx);
/**
@@ -399,7 +328,7 @@ struct mlx5_hlist_entry *mlx5_hlist_register(struct mlx5_hlist *h, uint64_t key,
* 0 on entry removed, 1 on entry still referenced.
*/
__rte_internal
-int mlx5_hlist_unregister(struct mlx5_hlist *h, struct mlx5_hlist_entry *entry);
+int mlx5_hlist_unregister(struct mlx5_hlist *h, struct mlx5_list_entry *entry);
/**
* Destroy the hash list table, all the entries already inserted into the lists
@@ -261,7 +261,7 @@ static int
mlx5_alloc_shared_dr(struct mlx5_priv *priv)
{
struct mlx5_dev_ctx_shared *sh = priv->sh;
- char s[MLX5_HLIST_NAMESIZE] __rte_unused;
+ char s[MLX5_NAME_SIZE] __rte_unused;
int err;
MLX5_ASSERT(sh && sh->refcnt);
@@ -314,44 +314,44 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv)
goto error;
/* Create tags hash list table. */
snprintf(s, sizeof(s), "%s_tags", sh->ibdev_name);
- sh->tag_table = mlx5_hlist_create(s, MLX5_TAGS_HLIST_ARRAY_SIZE, 0,
- MLX5_HLIST_WRITE_MOST,
- flow_dv_tag_create_cb,
+ sh->tag_table = mlx5_hlist_create(s, MLX5_TAGS_HLIST_ARRAY_SIZE, false,
+ false, sh, flow_dv_tag_create_cb,
flow_dv_tag_match_cb,
- flow_dv_tag_remove_cb);
+ flow_dv_tag_remove_cb,
+ flow_dv_tag_clone_cb,
+ flow_dv_tag_clone_free_cb);
if (!sh->tag_table) {
DRV_LOG(ERR, "tags with hash creation failed.");
err = ENOMEM;
goto error;
}
- sh->tag_table->ctx = sh;
snprintf(s, sizeof(s), "%s_hdr_modify", sh->ibdev_name);
sh->modify_cmds = mlx5_hlist_create(s, MLX5_FLOW_HDR_MODIFY_HTABLE_SZ,
- 0, MLX5_HLIST_WRITE_MOST |
- MLX5_HLIST_DIRECT_KEY,
+ true, false, sh,
flow_dv_modify_create_cb,
flow_dv_modify_match_cb,
- flow_dv_modify_remove_cb);
+ flow_dv_modify_remove_cb,
+ flow_dv_modify_clone_cb,
+ flow_dv_modify_clone_free_cb);
if (!sh->modify_cmds) {
DRV_LOG(ERR, "hdr modify hash creation failed");
err = ENOMEM;
goto error;
}
- sh->modify_cmds->ctx = sh;
snprintf(s, sizeof(s), "%s_encaps_decaps", sh->ibdev_name);
sh->encaps_decaps = mlx5_hlist_create(s,
MLX5_FLOW_ENCAP_DECAP_HTABLE_SZ,
- 0, MLX5_HLIST_DIRECT_KEY |
- MLX5_HLIST_WRITE_MOST,
+ true, true, sh,
flow_dv_encap_decap_create_cb,
flow_dv_encap_decap_match_cb,
- flow_dv_encap_decap_remove_cb);
+ flow_dv_encap_decap_remove_cb,
+ flow_dv_encap_decap_clone_cb,
+ flow_dv_encap_decap_clone_free_cb);
if (!sh->encaps_decaps) {
DRV_LOG(ERR, "encap decap hash creation failed");
err = ENOMEM;
goto error;
}
- sh->encaps_decaps->ctx = sh;
#endif
#ifdef HAVE_MLX5DV_DR
void *domain;
@@ -1783,15 +1783,16 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
priv->sh->dv_regc0_mask) {
priv->mreg_cp_tbl = mlx5_hlist_create(MLX5_FLOW_MREG_HNAME,
MLX5_FLOW_MREG_HTABLE_SZ,
- 0, 0,
+ false, true, eth_dev,
flow_dv_mreg_create_cb,
flow_dv_mreg_match_cb,
- flow_dv_mreg_remove_cb);
+ flow_dv_mreg_remove_cb,
+ flow_dv_mreg_clone_cb,
+ flow_dv_mreg_clone_free_cb);
if (!priv->mreg_cp_tbl) {
err = ENOMEM;
goto error;
}
- priv->mreg_cp_tbl->ctx = eth_dev;
}
rte_spinlock_init(&priv->shared_act_sl);
mlx5_flow_counter_mode_config(eth_dev);
@@ -1356,20 +1356,22 @@ mlx5_alloc_table_hash_list(struct mlx5_priv *priv __rte_unused)
/* Tables are only used in DV and DR modes. */
#if defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_INFINIBAND_VERBS_H)
struct mlx5_dev_ctx_shared *sh = priv->sh;
- char s[MLX5_HLIST_NAMESIZE];
+ char s[MLX5_NAME_SIZE];
MLX5_ASSERT(sh);
snprintf(s, sizeof(s), "%s_flow_table", priv->sh->ibdev_name);
sh->flow_tbls = mlx5_hlist_create(s, MLX5_FLOW_TABLE_HLIST_ARRAY_SIZE,
- 0, 0, flow_dv_tbl_create_cb,
+ false, true, sh,
+ flow_dv_tbl_create_cb,
flow_dv_tbl_match_cb,
- flow_dv_tbl_remove_cb);
+ flow_dv_tbl_remove_cb,
+ flow_dv_tbl_clone_cb,
+ flow_dv_tbl_clone_free_cb);
if (!sh->flow_tbls) {
DRV_LOG(ERR, "flow tables with hash creation failed.");
err = ENOMEM;
return err;
}
- sh->flow_tbls->ctx = sh;
#ifndef HAVE_MLX5DV_DR
struct rte_flow_error error;
struct rte_eth_dev *dev = &rte_eth_devices[priv->dev_data->port_id];
@@ -84,6 +84,7 @@ struct mlx5_flow_cb_ctx {
struct rte_eth_dev *dev;
struct rte_flow_error *error;
void *data;
+ void *data2;
};
/* Device attributes used in mlx5 PMD */
@@ -3983,28 +3983,27 @@ flow_list_destroy(struct rte_eth_dev *dev, enum mlx5_flow_type type,
uint32_t flow_idx);
int
-flow_dv_mreg_match_cb(struct mlx5_hlist *list __rte_unused,
- struct mlx5_hlist_entry *entry,
- uint64_t key, void *cb_ctx __rte_unused)
+flow_dv_mreg_match_cb(void *tool_ctx __rte_unused,
+ struct mlx5_list_entry *entry, void *cb_ctx)
{
+ struct mlx5_flow_cb_ctx *ctx = cb_ctx;
struct mlx5_flow_mreg_copy_resource *mcp_res =
- container_of(entry, typeof(*mcp_res), hlist_ent);
+ container_of(entry, typeof(*mcp_res), hlist_ent);
- return mcp_res->mark_id != key;
+ return mcp_res->mark_id != *(uint32_t *)(ctx->data);
}
-struct mlx5_hlist_entry *
-flow_dv_mreg_create_cb(struct mlx5_hlist *list, uint64_t key,
- void *cb_ctx)
+struct mlx5_list_entry *
+flow_dv_mreg_create_cb(void *tool_ctx, void *cb_ctx)
{
- struct rte_eth_dev *dev = list->ctx;
+ struct rte_eth_dev *dev = tool_ctx;
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_flow_cb_ctx *ctx = cb_ctx;
struct mlx5_flow_mreg_copy_resource *mcp_res;
struct rte_flow_error *error = ctx->error;
uint32_t idx = 0;
int ret;
- uint32_t mark_id = key;
+ uint32_t mark_id = *(uint32_t *)(ctx->data);
struct rte_flow_attr attr = {
.group = MLX5_FLOW_MREG_CP_TABLE_GROUP,
.ingress = 1,
@@ -4110,6 +4109,36 @@ flow_dv_mreg_create_cb(struct mlx5_hlist *list, uint64_t key,
return &mcp_res->hlist_ent;
}
+struct mlx5_list_entry *
+flow_dv_mreg_clone_cb(void *tool_ctx, struct mlx5_list_entry *oentry,
+ void *cb_ctx __rte_unused)
+{
+ struct rte_eth_dev *dev = tool_ctx;
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct mlx5_flow_mreg_copy_resource *mcp_res;
+ uint32_t idx = 0;
+
+ mcp_res = mlx5_ipool_malloc(priv->sh->ipool[MLX5_IPOOL_MCP], &idx);
+ if (!mcp_res) {
+ rte_errno = ENOMEM;
+ return NULL;
+ }
+ memcpy(mcp_res, oentry, sizeof(*mcp_res));
+ mcp_res->idx = idx;
+ return &mcp_res->hlist_ent;
+}
+
+void
+flow_dv_mreg_clone_free_cb(void *tool_ctx, struct mlx5_list_entry *entry)
+{
+ struct mlx5_flow_mreg_copy_resource *mcp_res =
+ container_of(entry, typeof(*mcp_res), hlist_ent);
+ struct rte_eth_dev *dev = tool_ctx;
+ struct mlx5_priv *priv = dev->data->dev_private;
+
+ mlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MCP], mcp_res->idx);
+}
+
/**
* Add a flow of copying flow metadata registers in RX_CP_TBL.
*
@@ -4140,10 +4169,11 @@ flow_mreg_add_copy_action(struct rte_eth_dev *dev, uint32_t mark_id,
struct rte_flow_error *error)
{
struct mlx5_priv *priv = dev->data->dev_private;
- struct mlx5_hlist_entry *entry;
+ struct mlx5_list_entry *entry;
struct mlx5_flow_cb_ctx ctx = {
.dev = dev,
.error = error,
+ .data = &mark_id,
};
/* Check if already registered. */
@@ -4156,11 +4186,11 @@ flow_mreg_add_copy_action(struct rte_eth_dev *dev, uint32_t mark_id,
}
void
-flow_dv_mreg_remove_cb(struct mlx5_hlist *list, struct mlx5_hlist_entry *entry)
+flow_dv_mreg_remove_cb(void *tool_ctx, struct mlx5_list_entry *entry)
{
struct mlx5_flow_mreg_copy_resource *mcp_res =
- container_of(entry, typeof(*mcp_res), hlist_ent);
- struct rte_eth_dev *dev = list->ctx;
+ container_of(entry, typeof(*mcp_res), hlist_ent);
+ struct rte_eth_dev *dev = tool_ctx;
struct mlx5_priv *priv = dev->data->dev_private;
MLX5_ASSERT(mcp_res->rix_flow);
@@ -4206,14 +4236,17 @@ flow_mreg_del_copy_action(struct rte_eth_dev *dev,
static void
flow_mreg_del_default_copy_action(struct rte_eth_dev *dev)
{
- struct mlx5_hlist_entry *entry;
+ struct mlx5_list_entry *entry;
struct mlx5_priv *priv = dev->data->dev_private;
+ struct mlx5_flow_cb_ctx ctx;
+ uint32_t mark_id;
/* Check if default flow is registered. */
if (!priv->mreg_cp_tbl)
return;
- entry = mlx5_hlist_lookup(priv->mreg_cp_tbl,
- MLX5_DEFAULT_COPY_ID, NULL);
+ mark_id = MLX5_DEFAULT_COPY_ID;
+ ctx.data = &mark_id;
+ entry = mlx5_hlist_lookup(priv->mreg_cp_tbl, mark_id, &ctx);
if (!entry)
return;
mlx5_hlist_unregister(priv->mreg_cp_tbl, entry);
@@ -4239,6 +4272,8 @@ flow_mreg_add_default_copy_action(struct rte_eth_dev *dev,
{
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_flow_mreg_copy_resource *mcp_res;
+ struct mlx5_flow_cb_ctx ctx;
+ uint32_t mark_id;
/* Check whether extensive metadata feature is engaged. */
if (!priv->config.dv_flow_en ||
@@ -4250,9 +4285,11 @@ flow_mreg_add_default_copy_action(struct rte_eth_dev *dev,
* Add default mreg copy flow may be called multiple time, but
* only be called once in stop. Avoid register it twice.
*/
- if (mlx5_hlist_lookup(priv->mreg_cp_tbl, MLX5_DEFAULT_COPY_ID, NULL))
+ mark_id = MLX5_DEFAULT_COPY_ID;
+ ctx.data = &mark_id;
+ if (mlx5_hlist_lookup(priv->mreg_cp_tbl, mark_id, &ctx))
return 0;
- mcp_res = flow_mreg_add_copy_action(dev, MLX5_DEFAULT_COPY_ID, error);
+ mcp_res = flow_mreg_add_copy_action(dev, mark_id, error);
if (!mcp_res)
return -rte_errno;
return 0;
@@ -8367,7 +8404,7 @@ tunnel_mark_decode(struct rte_eth_dev *dev, uint32_t mark)
{
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_dev_ctx_shared *sh = priv->sh;
- struct mlx5_hlist_entry *he;
+ struct mlx5_list_entry *he;
union tunnel_offload_mark mbits = { .val = mark };
union mlx5_flow_tbl_key table_key = {
{
@@ -8379,16 +8416,20 @@ tunnel_mark_decode(struct rte_eth_dev *dev, uint32_t mark)
.is_egress = 0,
}
};
- he = mlx5_hlist_lookup(sh->flow_tbls, table_key.v64, NULL);
+ struct mlx5_flow_cb_ctx ctx = {
+ .data = &table_key.v64,
+ };
+
+ he = mlx5_hlist_lookup(sh->flow_tbls, table_key.v64, &ctx);
return he ?
container_of(he, struct mlx5_flow_tbl_data_entry, entry) : NULL;
}
static void
-mlx5_flow_tunnel_grp2tbl_remove_cb(struct mlx5_hlist *list,
- struct mlx5_hlist_entry *entry)
+mlx5_flow_tunnel_grp2tbl_remove_cb(void *tool_ctx,
+ struct mlx5_list_entry *entry)
{
- struct mlx5_dev_ctx_shared *sh = list->ctx;
+ struct mlx5_dev_ctx_shared *sh = tool_ctx;
struct tunnel_tbl_entry *tte = container_of(entry, typeof(*tte), hash);
mlx5_ipool_free(sh->ipool[MLX5_IPOOL_TNL_TBL_ID],
@@ -8397,26 +8438,26 @@ mlx5_flow_tunnel_grp2tbl_remove_cb(struct mlx5_hlist *list,
}
static int
-mlx5_flow_tunnel_grp2tbl_match_cb(struct mlx5_hlist *list __rte_unused,
- struct mlx5_hlist_entry *entry,
- uint64_t key, void *cb_ctx __rte_unused)
+mlx5_flow_tunnel_grp2tbl_match_cb(void *tool_ctx __rte_unused,
+ struct mlx5_list_entry *entry, void *cb_ctx)
{
+ struct mlx5_flow_cb_ctx *ctx = cb_ctx;
union tunnel_tbl_key tbl = {
- .val = key,
+ .val = *(uint64_t *)(ctx->data),
};
struct tunnel_tbl_entry *tte = container_of(entry, typeof(*tte), hash);
return tbl.tunnel_id != tte->tunnel_id || tbl.group != tte->group;
}
-static struct mlx5_hlist_entry *
-mlx5_flow_tunnel_grp2tbl_create_cb(struct mlx5_hlist *list, uint64_t key,
- void *ctx __rte_unused)
+static struct mlx5_list_entry *
+mlx5_flow_tunnel_grp2tbl_create_cb(void *tool_ctx, void *cb_ctx)
{
- struct mlx5_dev_ctx_shared *sh = list->ctx;
+ struct mlx5_dev_ctx_shared *sh = tool_ctx;
+ struct mlx5_flow_cb_ctx *ctx = cb_ctx;
struct tunnel_tbl_entry *tte;
union tunnel_tbl_key tbl = {
- .val = key,
+ .val = *(uint64_t *)(ctx->data),
};
tte = mlx5_malloc(MLX5_MEM_SYS | MLX5_MEM_ZERO,
@@ -8445,13 +8486,36 @@ mlx5_flow_tunnel_grp2tbl_create_cb(struct mlx5_hlist *list, uint64_t key,
return NULL;
}
+static struct mlx5_list_entry *
+mlx5_flow_tunnel_grp2tbl_clone_cb(void *tool_ctx __rte_unused,
+ struct mlx5_list_entry *oentry,
+ void *cb_ctx __rte_unused)
+{
+ struct tunnel_tbl_entry *tte = mlx5_malloc(MLX5_MEM_SYS, sizeof(*tte),
+ 0, SOCKET_ID_ANY);
+
+ if (!tte)
+ return NULL;
+ memcpy(tte, oentry, sizeof(*tte));
+ return &tte->hash;
+}
+
+static void
+mlx5_flow_tunnel_grp2tbl_clone_free_cb(void *tool_ctx __rte_unused,
+ struct mlx5_list_entry *entry)
+{
+ struct tunnel_tbl_entry *tte = container_of(entry, typeof(*tte), hash);
+
+ mlx5_free(tte);
+}
+
static uint32_t
tunnel_flow_group_to_flow_table(struct rte_eth_dev *dev,
const struct mlx5_flow_tunnel *tunnel,
uint32_t group, uint32_t *table,
struct rte_flow_error *error)
{
- struct mlx5_hlist_entry *he;
+ struct mlx5_list_entry *he;
struct tunnel_tbl_entry *tte;
union tunnel_tbl_key key = {
.tunnel_id = tunnel ? tunnel->tunnel_id : 0,
@@ -8459,9 +8523,12 @@ tunnel_flow_group_to_flow_table(struct rte_eth_dev *dev,
};
struct mlx5_flow_tunnel_hub *thub = mlx5_tunnel_hub(dev);
struct mlx5_hlist *group_hash;
+ struct mlx5_flow_cb_ctx ctx = {
+ .data = &key.val,
+ };
group_hash = tunnel ? tunnel->groups : thub->groups;
- he = mlx5_hlist_register(group_hash, key.val, NULL);
+ he = mlx5_hlist_register(group_hash, key.val, &ctx);
if (!he)
return rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
@@ -8575,15 +8642,17 @@ mlx5_flow_tunnel_allocate(struct rte_eth_dev *dev,
DRV_LOG(ERR, "Tunnel ID %d exceed max limit.", id);
return NULL;
}
- tunnel->groups = mlx5_hlist_create("tunnel groups", 1024, 0, 0,
+ tunnel->groups = mlx5_hlist_create("tunnel groups", 1024, false, true,
+ priv->sh,
mlx5_flow_tunnel_grp2tbl_create_cb,
mlx5_flow_tunnel_grp2tbl_match_cb,
- mlx5_flow_tunnel_grp2tbl_remove_cb);
+ mlx5_flow_tunnel_grp2tbl_remove_cb,
+ mlx5_flow_tunnel_grp2tbl_clone_cb,
+ mlx5_flow_tunnel_grp2tbl_clone_free_cb);
if (!tunnel->groups) {
mlx5_ipool_free(ipool, id);
return NULL;
}
- tunnel->groups->ctx = priv->sh;
/* initiate new PMD tunnel */
memcpy(&tunnel->app_tunnel, app_tunnel, sizeof(*app_tunnel));
tunnel->tunnel_id = id;
@@ -8683,15 +8752,17 @@ int mlx5_alloc_tunnel_hub(struct mlx5_dev_ctx_shared *sh)
LIST_INIT(&thub->tunnels);
rte_spinlock_init(&thub->sl);
thub->groups = mlx5_hlist_create("flow groups",
- rte_align32pow2(MLX5_MAX_TABLES), 0,
- 0, mlx5_flow_tunnel_grp2tbl_create_cb,
+ rte_align32pow2(MLX5_MAX_TABLES),
+ false, true, sh,
+ mlx5_flow_tunnel_grp2tbl_create_cb,
mlx5_flow_tunnel_grp2tbl_match_cb,
- mlx5_flow_tunnel_grp2tbl_remove_cb);
+ mlx5_flow_tunnel_grp2tbl_remove_cb,
+ mlx5_flow_tunnel_grp2tbl_clone_cb,
+ mlx5_flow_tunnel_grp2tbl_clone_free_cb);
if (!thub->groups) {
err = -rte_errno;
goto err;
}
- thub->groups->ctx = sh;
sh->tunnel_hub = thub;
return 0;
@@ -480,7 +480,7 @@ struct mlx5_flow_dv_matcher {
/* Encap/decap resource structure. */
struct mlx5_flow_dv_encap_decap_resource {
- struct mlx5_hlist_entry entry;
+ struct mlx5_list_entry entry;
/* Pointer to next element. */
uint32_t refcnt; /**< Reference counter. */
void *action;
@@ -495,7 +495,7 @@ struct mlx5_flow_dv_encap_decap_resource {
/* Tag resource structure. */
struct mlx5_flow_dv_tag_resource {
- struct mlx5_hlist_entry entry;
+ struct mlx5_list_entry entry;
/**< hash list entry for tag resource, tag value as the key. */
void *action;
/**< Tag action object. */
@@ -519,7 +519,7 @@ struct mlx5_flow_dv_tag_resource {
/* Modify resource structure */
struct mlx5_flow_dv_modify_hdr_resource {
- struct mlx5_hlist_entry entry;
+ struct mlx5_list_entry entry;
void *action; /**< Modify header action object. */
/* Key area for hash list matching: */
uint8_t ft_type; /**< Flow table type, Rx or Tx. */
@@ -569,7 +569,7 @@ struct mlx5_flow_mreg_copy_resource {
* - Key is 32/64-bit MARK action ID.
* - MUST be the first entry.
*/
- struct mlx5_hlist_entry hlist_ent;
+ struct mlx5_list_entry hlist_ent;
LIST_ENTRY(mlx5_flow_mreg_copy_resource) next;
/* List entry for device flows. */
uint32_t idx;
@@ -586,7 +586,7 @@ struct mlx5_flow_tbl_tunnel_prm {
/* Table data structure of the hash organization. */
struct mlx5_flow_tbl_data_entry {
- struct mlx5_hlist_entry entry;
+ struct mlx5_list_entry entry;
/**< hash list entry, 64-bits key inside. */
struct mlx5_flow_tbl_resource tbl;
/**< flow table resource. */
@@ -926,7 +926,7 @@ struct mlx5_flow_tunnel_hub {
/* convert jump group to flow table ID in tunnel rules */
struct tunnel_tbl_entry {
- struct mlx5_hlist_entry hash;
+ struct mlx5_list_entry hash;
uint32_t flow_table;
uint32_t tunnel_id;
uint32_t group;
@@ -1573,51 +1573,59 @@ int mlx5_action_handle_flush(struct rte_eth_dev *dev);
void mlx5_release_tunnel_hub(struct mlx5_dev_ctx_shared *sh, uint16_t port_id);
int mlx5_alloc_tunnel_hub(struct mlx5_dev_ctx_shared *sh);
-/* Hash list callbacks for flow tables: */
-struct mlx5_hlist_entry *flow_dv_tbl_create_cb(struct mlx5_hlist *list,
- uint64_t key, void *entry_ctx);
-int flow_dv_tbl_match_cb(struct mlx5_hlist *list,
- struct mlx5_hlist_entry *entry, uint64_t key,
+struct mlx5_list_entry *flow_dv_tbl_create_cb(void *tool_ctx, void *entry_ctx);
+int flow_dv_tbl_match_cb(void *tool_ctx, struct mlx5_list_entry *entry,
void *cb_ctx);
-void flow_dv_tbl_remove_cb(struct mlx5_hlist *list,
- struct mlx5_hlist_entry *entry);
+void flow_dv_tbl_remove_cb(void *tool_ctx, struct mlx5_list_entry *entry);
+struct mlx5_list_entry *flow_dv_tbl_clone_cb(void *tool_ctx,
+ struct mlx5_list_entry *oentry,
+ void *entry_ctx);
+void flow_dv_tbl_clone_free_cb(void *tool_ctx, struct mlx5_list_entry *entry);
struct mlx5_flow_tbl_resource *flow_dv_tbl_resource_get(struct rte_eth_dev *dev,
uint32_t table_level, uint8_t egress, uint8_t transfer,
bool external, const struct mlx5_flow_tunnel *tunnel,
uint32_t group_id, uint8_t dummy,
uint32_t table_id, struct rte_flow_error *error);
-struct mlx5_hlist_entry *flow_dv_tag_create_cb(struct mlx5_hlist *list,
- uint64_t key, void *cb_ctx);
-int flow_dv_tag_match_cb(struct mlx5_hlist *list,
- struct mlx5_hlist_entry *entry, uint64_t key,
+struct mlx5_list_entry *flow_dv_tag_create_cb(void *tool_ctx, void *cb_ctx);
+int flow_dv_tag_match_cb(void *tool_ctx, struct mlx5_list_entry *entry,
void *cb_ctx);
-void flow_dv_tag_remove_cb(struct mlx5_hlist *list,
- struct mlx5_hlist_entry *entry);
-
-int flow_dv_modify_match_cb(struct mlx5_hlist *list,
- struct mlx5_hlist_entry *entry,
- uint64_t key, void *cb_ctx);
-struct mlx5_hlist_entry *flow_dv_modify_create_cb(struct mlx5_hlist *list,
- uint64_t key, void *ctx);
-void flow_dv_modify_remove_cb(struct mlx5_hlist *list,
- struct mlx5_hlist_entry *entry);
-
-struct mlx5_hlist_entry *flow_dv_mreg_create_cb(struct mlx5_hlist *list,
- uint64_t key, void *ctx);
-int flow_dv_mreg_match_cb(struct mlx5_hlist *list,
- struct mlx5_hlist_entry *entry, uint64_t key,
+void flow_dv_tag_remove_cb(void *tool_ctx, struct mlx5_list_entry *entry);
+struct mlx5_list_entry *flow_dv_tag_clone_cb(void *tool_ctx,
+ struct mlx5_list_entry *oentry,
+ void *cb_ctx);
+void flow_dv_tag_clone_free_cb(void *tool_ctx, struct mlx5_list_entry *entry);
+
+int flow_dv_modify_match_cb(void *tool_ctx, struct mlx5_list_entry *entry,
+ void *cb_ctx);
+struct mlx5_list_entry *flow_dv_modify_create_cb(void *tool_ctx, void *ctx);
+void flow_dv_modify_remove_cb(void *tool_ctx, struct mlx5_list_entry *entry);
+struct mlx5_list_entry *flow_dv_modify_clone_cb(void *tool_ctx,
+ struct mlx5_list_entry *oentry,
+ void *ctx);
+void flow_dv_modify_clone_free_cb(void *tool_ctx,
+ struct mlx5_list_entry *entry);
+
+struct mlx5_list_entry *flow_dv_mreg_create_cb(void *tool_ctx, void *ctx);
+int flow_dv_mreg_match_cb(void *tool_ctx, struct mlx5_list_entry *entry,
void *cb_ctx);
-void flow_dv_mreg_remove_cb(struct mlx5_hlist *list,
- struct mlx5_hlist_entry *entry);
-
-int flow_dv_encap_decap_match_cb(struct mlx5_hlist *list,
- struct mlx5_hlist_entry *entry,
- uint64_t key, void *cb_ctx);
-struct mlx5_hlist_entry *flow_dv_encap_decap_create_cb(struct mlx5_hlist *list,
- uint64_t key, void *cb_ctx);
-void flow_dv_encap_decap_remove_cb(struct mlx5_hlist *list,
- struct mlx5_hlist_entry *entry);
+void flow_dv_mreg_remove_cb(void *tool_ctx, struct mlx5_list_entry *entry);
+struct mlx5_list_entry *flow_dv_mreg_clone_cb(void *tool_ctx,
+ struct mlx5_list_entry *entry,
+ void *ctx);
+void flow_dv_mreg_clone_free_cb(void *tool_ctx, struct mlx5_list_entry *entry);
+
+int flow_dv_encap_decap_match_cb(void *tool_ctx, struct mlx5_list_entry *entry,
+ void *cb_ctx);
+struct mlx5_list_entry *flow_dv_encap_decap_create_cb(void *tool_ctx,
+ void *cb_ctx);
+void flow_dv_encap_decap_remove_cb(void *tool_ctx,
+ struct mlx5_list_entry *entry);
+struct mlx5_list_entry *flow_dv_encap_decap_clone_cb(void *tool_ctx,
+ struct mlx5_list_entry *entry,
+ void *cb_ctx);
+void flow_dv_encap_decap_clone_free_cb(void *tool_ctx,
+ struct mlx5_list_entry *entry);
int flow_dv_matcher_match_cb(void *tool_ctx, struct mlx5_list_entry *entry,
void *ctx);
@@ -3580,25 +3580,9 @@ flow_dv_validate_action_aso_ct(struct rte_eth_dev *dev,
return 0;
}
-/**
- * Match encap_decap resource.
- *
- * @param list
- * Pointer to the hash list.
- * @param entry
- * Pointer to exist resource entry object.
- * @param key
- * Key of the new entry.
- * @param ctx_cb
- * Pointer to new encap_decap resource.
- *
- * @return
- * 0 on matching, none-zero otherwise.
- */
int
-flow_dv_encap_decap_match_cb(struct mlx5_hlist *list __rte_unused,
- struct mlx5_hlist_entry *entry,
- uint64_t key __rte_unused, void *cb_ctx)
+flow_dv_encap_decap_match_cb(void *tool_ctx __rte_unused,
+ struct mlx5_list_entry *entry, void *cb_ctx)
{
struct mlx5_flow_cb_ctx *ctx = cb_ctx;
struct mlx5_flow_dv_encap_decap_resource *ctx_resource = ctx->data;
@@ -3617,25 +3601,10 @@ flow_dv_encap_decap_match_cb(struct mlx5_hlist *list __rte_unused,
return -1;
}
-/**
- * Allocate encap_decap resource.
- *
- * @param list
- * Pointer to the hash list.
- * @param entry
- * Pointer to exist resource entry object.
- * @param ctx_cb
- * Pointer to new encap_decap resource.
- *
- * @return
- * 0 on matching, none-zero otherwise.
- */
-struct mlx5_hlist_entry *
-flow_dv_encap_decap_create_cb(struct mlx5_hlist *list,
- uint64_t key __rte_unused,
- void *cb_ctx)
+struct mlx5_list_entry *
+flow_dv_encap_decap_create_cb(void *tool_ctx, void *cb_ctx)
{
- struct mlx5_dev_ctx_shared *sh = list->ctx;
+ struct mlx5_dev_ctx_shared *sh = tool_ctx;
struct mlx5_flow_cb_ctx *ctx = cb_ctx;
struct mlx5dv_dr_domain *domain;
struct mlx5_flow_dv_encap_decap_resource *ctx_resource = ctx->data;
@@ -3673,6 +3642,38 @@ flow_dv_encap_decap_create_cb(struct mlx5_hlist *list,
return &resource->entry;
}
+struct mlx5_list_entry *
+flow_dv_encap_decap_clone_cb(void *tool_ctx, struct mlx5_list_entry *oentry,
+ void *cb_ctx)
+{
+ struct mlx5_dev_ctx_shared *sh = tool_ctx;
+ struct mlx5_flow_cb_ctx *ctx = cb_ctx;
+ struct mlx5_flow_dv_encap_decap_resource *cache_resource;
+ uint32_t idx;
+
+ cache_resource = mlx5_ipool_malloc(sh->ipool[MLX5_IPOOL_DECAP_ENCAP],
+ &idx);
+ if (!cache_resource) {
+ rte_flow_error_set(ctx->error, ENOMEM,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "cannot allocate resource memory");
+ return NULL;
+ }
+ memcpy(cache_resource, oentry, sizeof(*cache_resource));
+ cache_resource->idx = idx;
+ return &cache_resource->entry;
+}
+
+void
+flow_dv_encap_decap_clone_free_cb(void *tool_ctx, struct mlx5_list_entry *entry)
+{
+ struct mlx5_dev_ctx_shared *sh = tool_ctx;
+ struct mlx5_flow_dv_encap_decap_resource *res =
+ container_of(entry, typeof(*res), entry);
+
+ mlx5_ipool_free(sh->ipool[MLX5_IPOOL_DECAP_ENCAP], res->idx);
+}
+
/**
* Find existing encap/decap resource or create and register a new one.
*
@@ -3697,7 +3698,7 @@ flow_dv_encap_decap_resource_register
{
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_dev_ctx_shared *sh = priv->sh;
- struct mlx5_hlist_entry *entry;
+ struct mlx5_list_entry *entry;
union {
struct {
uint32_t ft_type:8;
@@ -5322,30 +5323,14 @@ flow_dv_validate_action_modify_ipv6_dscp(const uint64_t action_flags,
return ret;
}
-/**
- * Match modify-header resource.
- *
- * @param list
- * Pointer to the hash list.
- * @param entry
- * Pointer to exist resource entry object.
- * @param key
- * Key of the new entry.
- * @param ctx
- * Pointer to new modify-header resource.
- *
- * @return
- * 0 on matching, non-zero otherwise.
- */
int
-flow_dv_modify_match_cb(struct mlx5_hlist *list __rte_unused,
- struct mlx5_hlist_entry *entry,
- uint64_t key __rte_unused, void *cb_ctx)
+flow_dv_modify_match_cb(void *tool_ctx __rte_unused,
+ struct mlx5_list_entry *entry, void *cb_ctx)
{
struct mlx5_flow_cb_ctx *ctx = cb_ctx;
struct mlx5_flow_dv_modify_hdr_resource *ref = ctx->data;
struct mlx5_flow_dv_modify_hdr_resource *resource =
- container_of(entry, typeof(*resource), entry);
+ container_of(entry, typeof(*resource), entry);
uint32_t key_len = sizeof(*ref) - offsetof(typeof(*ref), ft_type);
key_len += ref->actions_num * sizeof(ref->actions[0]);
@@ -5353,11 +5338,10 @@ flow_dv_modify_match_cb(struct mlx5_hlist *list __rte_unused,
memcmp(&ref->ft_type, &resource->ft_type, key_len);
}
-struct mlx5_hlist_entry *
-flow_dv_modify_create_cb(struct mlx5_hlist *list, uint64_t key __rte_unused,
- void *cb_ctx)
+struct mlx5_list_entry *
+flow_dv_modify_create_cb(void *tool_ctx, void *cb_ctx)
{
- struct mlx5_dev_ctx_shared *sh = list->ctx;
+ struct mlx5_dev_ctx_shared *sh = tool_ctx;
struct mlx5_flow_cb_ctx *ctx = cb_ctx;
struct mlx5dv_dr_domain *ns;
struct mlx5_flow_dv_modify_hdr_resource *entry;
@@ -5396,6 +5380,33 @@ flow_dv_modify_create_cb(struct mlx5_hlist *list, uint64_t key __rte_unused,
return &entry->entry;
}
+struct mlx5_list_entry *
+flow_dv_modify_clone_cb(void *tool_ctx __rte_unused,
+ struct mlx5_list_entry *oentry, void *cb_ctx)
+{
+ struct mlx5_flow_cb_ctx *ctx = cb_ctx;
+ struct mlx5_flow_dv_modify_hdr_resource *entry;
+ struct mlx5_flow_dv_modify_hdr_resource *ref = ctx->data;
+ uint32_t data_len = ref->actions_num * sizeof(ref->actions[0]);
+
+ entry = mlx5_malloc(0, sizeof(*entry) + data_len, 0, SOCKET_ID_ANY);
+ if (!entry) {
+ rte_flow_error_set(ctx->error, ENOMEM,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "cannot allocate resource memory");
+ return NULL;
+ }
+ memcpy(entry, oentry, sizeof(*entry) + data_len);
+ return &entry->entry;
+}
+
+void
+flow_dv_modify_clone_free_cb(void *tool_ctx __rte_unused,
+ struct mlx5_list_entry *entry)
+{
+ mlx5_free(entry);
+}
+
/**
* Validate the sample action.
*
@@ -5667,7 +5678,7 @@ flow_dv_modify_hdr_resource_register
uint32_t key_len = sizeof(*resource) -
offsetof(typeof(*resource), ft_type) +
resource->actions_num * sizeof(resource->actions[0]);
- struct mlx5_hlist_entry *entry;
+ struct mlx5_list_entry *entry;
struct mlx5_flow_cb_ctx ctx = {
.error = error,
.data = resource,
@@ -9975,16 +9986,16 @@ flow_dv_matcher_clone_free_cb(void *tool_ctx __rte_unused,
mlx5_free(entry);
}
-struct mlx5_hlist_entry *
-flow_dv_tbl_create_cb(struct mlx5_hlist *list, uint64_t key64, void *cb_ctx)
+struct mlx5_list_entry *
+flow_dv_tbl_create_cb(void *tool_ctx, void *cb_ctx)
{
- struct mlx5_dev_ctx_shared *sh = list->ctx;
+ struct mlx5_dev_ctx_shared *sh = tool_ctx;
struct mlx5_flow_cb_ctx *ctx = cb_ctx;
struct rte_eth_dev *dev = ctx->dev;
struct mlx5_flow_tbl_data_entry *tbl_data;
- struct mlx5_flow_tbl_tunnel_prm *tt_prm = ctx->data;
+ struct mlx5_flow_tbl_tunnel_prm *tt_prm = ctx->data2;
struct rte_flow_error *error = ctx->error;
- union mlx5_flow_tbl_key key = { .v64 = key64 };
+ union mlx5_flow_tbl_key key = { .v64 = *(uint64_t *)(ctx->data) };
struct mlx5_flow_tbl_resource *tbl;
void *domain;
uint32_t idx = 0;
@@ -10061,13 +10072,13 @@ flow_dv_tbl_create_cb(struct mlx5_hlist *list, uint64_t key64, void *cb_ctx)
}
int
-flow_dv_tbl_match_cb(struct mlx5_hlist *list __rte_unused,
- struct mlx5_hlist_entry *entry, uint64_t key64,
- void *cb_ctx __rte_unused)
+flow_dv_tbl_match_cb(void *tool_ctx __rte_unused, struct mlx5_list_entry *entry,
+ void *cb_ctx)
{
+ struct mlx5_flow_cb_ctx *ctx = cb_ctx;
struct mlx5_flow_tbl_data_entry *tbl_data =
container_of(entry, struct mlx5_flow_tbl_data_entry, entry);
- union mlx5_flow_tbl_key key = { .v64 = key64 };
+ union mlx5_flow_tbl_key key = { .v64 = *(uint64_t *)(ctx->data) };
return tbl_data->level != key.level ||
tbl_data->id != key.id ||
@@ -10076,6 +10087,39 @@ flow_dv_tbl_match_cb(struct mlx5_hlist *list __rte_unused,
tbl_data->is_egress != !!key.is_egress;
}
+struct mlx5_list_entry *
+flow_dv_tbl_clone_cb(void *tool_ctx, struct mlx5_list_entry *oentry,
+ void *cb_ctx)
+{
+ struct mlx5_dev_ctx_shared *sh = tool_ctx;
+ struct mlx5_flow_cb_ctx *ctx = cb_ctx;
+ struct mlx5_flow_tbl_data_entry *tbl_data;
+ struct rte_flow_error *error = ctx->error;
+ uint32_t idx = 0;
+
+ tbl_data = mlx5_ipool_malloc(sh->ipool[MLX5_IPOOL_JUMP], &idx);
+ if (!tbl_data) {
+ rte_flow_error_set(error, ENOMEM,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL,
+ "cannot allocate flow table data entry");
+ return NULL;
+ }
+ memcpy(tbl_data, oentry, sizeof(*tbl_data));
+ tbl_data->idx = idx;
+ return &tbl_data->entry;
+}
+
+void
+flow_dv_tbl_clone_free_cb(void *tool_ctx, struct mlx5_list_entry *entry)
+{
+ struct mlx5_dev_ctx_shared *sh = tool_ctx;
+ struct mlx5_flow_tbl_data_entry *tbl_data =
+ container_of(entry, struct mlx5_flow_tbl_data_entry, entry);
+
+ mlx5_ipool_free(sh->ipool[MLX5_IPOOL_JUMP], tbl_data->idx);
+}
+
/**
* Get a flow table.
*
@@ -10126,9 +10170,10 @@ flow_dv_tbl_resource_get(struct rte_eth_dev *dev,
struct mlx5_flow_cb_ctx ctx = {
.dev = dev,
.error = error,
- .data = &tt_prm,
+ .data = &table_key.v64,
+ .data2 = &tt_prm,
};
- struct mlx5_hlist_entry *entry;
+ struct mlx5_list_entry *entry;
struct mlx5_flow_tbl_data_entry *tbl_data;
entry = mlx5_hlist_register(priv->sh->flow_tbls, table_key.v64, &ctx);
@@ -10147,12 +10192,11 @@ flow_dv_tbl_resource_get(struct rte_eth_dev *dev,
}
void
-flow_dv_tbl_remove_cb(struct mlx5_hlist *list,
- struct mlx5_hlist_entry *entry)
+flow_dv_tbl_remove_cb(void *tool_ctx, struct mlx5_list_entry *entry)
{
- struct mlx5_dev_ctx_shared *sh = list->ctx;
+ struct mlx5_dev_ctx_shared *sh = tool_ctx;
struct mlx5_flow_tbl_data_entry *tbl_data =
- container_of(entry, struct mlx5_flow_tbl_data_entry, entry);
+ container_of(entry, struct mlx5_flow_tbl_data_entry, entry);
MLX5_ASSERT(entry && sh);
if (tbl_data->jump.action)
@@ -10160,7 +10204,7 @@ flow_dv_tbl_remove_cb(struct mlx5_hlist *list,
if (tbl_data->tbl.obj)
mlx5_flow_os_destroy_flow_tbl(tbl_data->tbl.obj);
if (tbl_data->tunnel_offload && tbl_data->external) {
- struct mlx5_hlist_entry *he;
+ struct mlx5_list_entry *he;
struct mlx5_hlist *tunnel_grp_hash;
struct mlx5_flow_tunnel_hub *thub = sh->tunnel_hub;
union tunnel_tbl_key tunnel_key = {
@@ -10169,11 +10213,14 @@ flow_dv_tbl_remove_cb(struct mlx5_hlist *list,
.group = tbl_data->group_id
};
uint32_t table_level = tbl_data->level;
+ struct mlx5_flow_cb_ctx ctx = {
+ .data = (void *)&tunnel_key.val,
+ };
tunnel_grp_hash = tbl_data->tunnel ?
tbl_data->tunnel->groups :
thub->groups;
- he = mlx5_hlist_lookup(tunnel_grp_hash, tunnel_key.val, NULL);
+ he = mlx5_hlist_lookup(tunnel_grp_hash, tunnel_key.val, &ctx);
if (he)
mlx5_hlist_unregister(tunnel_grp_hash, he);
DRV_LOG(DEBUG,
@@ -10326,29 +10373,29 @@ flow_dv_matcher_register(struct rte_eth_dev *dev,
return 0;
}
-struct mlx5_hlist_entry *
-flow_dv_tag_create_cb(struct mlx5_hlist *list, uint64_t key, void *ctx)
+struct mlx5_list_entry *
+flow_dv_tag_create_cb(void *tool_ctx, void *cb_ctx)
{
- struct mlx5_dev_ctx_shared *sh = list->ctx;
- struct rte_flow_error *error = ctx;
+ struct mlx5_dev_ctx_shared *sh = tool_ctx;
+ struct mlx5_flow_cb_ctx *ctx = cb_ctx;
struct mlx5_flow_dv_tag_resource *entry;
uint32_t idx = 0;
int ret;
entry = mlx5_ipool_zmalloc(sh->ipool[MLX5_IPOOL_TAG], &idx);
if (!entry) {
- rte_flow_error_set(error, ENOMEM,
+ rte_flow_error_set(ctx->error, ENOMEM,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
"cannot allocate resource memory");
return NULL;
}
entry->idx = idx;
- entry->tag_id = key;
- ret = mlx5_flow_os_create_flow_action_tag(key,
+ entry->tag_id = *(uint32_t *)(ctx->data);
+ ret = mlx5_flow_os_create_flow_action_tag(entry->tag_id,
&entry->action);
if (ret) {
mlx5_ipool_free(sh->ipool[MLX5_IPOOL_TAG], idx);
- rte_flow_error_set(error, ENOMEM,
+ rte_flow_error_set(ctx->error, ENOMEM,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL, "cannot create action");
return NULL;
@@ -10357,14 +10404,45 @@ flow_dv_tag_create_cb(struct mlx5_hlist *list, uint64_t key, void *ctx)
}
int
-flow_dv_tag_match_cb(struct mlx5_hlist *list __rte_unused,
- struct mlx5_hlist_entry *entry, uint64_t key,
- void *cb_ctx __rte_unused)
+flow_dv_tag_match_cb(void *tool_ctx __rte_unused, struct mlx5_list_entry *entry,
+ void *cb_ctx)
{
+ struct mlx5_flow_cb_ctx *ctx = cb_ctx;
struct mlx5_flow_dv_tag_resource *tag =
- container_of(entry, struct mlx5_flow_dv_tag_resource, entry);
+ container_of(entry, struct mlx5_flow_dv_tag_resource, entry);
- return key != tag->tag_id;
+ return *(uint32_t *)(ctx->data) != tag->tag_id;
+}
+
+struct mlx5_list_entry *
+flow_dv_tag_clone_cb(void *tool_ctx, struct mlx5_list_entry *oentry,
+ void *cb_ctx)
+{
+ struct mlx5_dev_ctx_shared *sh = tool_ctx;
+ struct mlx5_flow_cb_ctx *ctx = cb_ctx;
+ struct mlx5_flow_dv_tag_resource *entry;
+ uint32_t idx = 0;
+
+ entry = mlx5_ipool_malloc(sh->ipool[MLX5_IPOOL_TAG], &idx);
+ if (!entry) {
+ rte_flow_error_set(ctx->error, ENOMEM,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "cannot allocate tag resource memory");
+ return NULL;
+ }
+ memcpy(entry, oentry, sizeof(*entry));
+ entry->idx = idx;
+ return &entry->entry;
+}
+
+void
+flow_dv_tag_clone_free_cb(void *tool_ctx, struct mlx5_list_entry *entry)
+{
+ struct mlx5_dev_ctx_shared *sh = tool_ctx;
+ struct mlx5_flow_dv_tag_resource *tag =
+ container_of(entry, struct mlx5_flow_dv_tag_resource, entry);
+
+ mlx5_ipool_free(sh->ipool[MLX5_IPOOL_TAG], tag->idx);
}
/**
@@ -10391,9 +10469,13 @@ flow_dv_tag_resource_register
{
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_flow_dv_tag_resource *resource;
- struct mlx5_hlist_entry *entry;
+ struct mlx5_list_entry *entry;
+ struct mlx5_flow_cb_ctx ctx = {
+ .error = error,
+ .data = &tag_be24,
+ };
- entry = mlx5_hlist_register(priv->sh->tag_table, tag_be24, error);
+ entry = mlx5_hlist_register(priv->sh->tag_table, tag_be24, &ctx);
if (entry) {
resource = container_of(entry, struct mlx5_flow_dv_tag_resource,
entry);
@@ -10405,12 +10487,11 @@ flow_dv_tag_resource_register
}
void
-flow_dv_tag_remove_cb(struct mlx5_hlist *list,
- struct mlx5_hlist_entry *entry)
+flow_dv_tag_remove_cb(void *tool_ctx, struct mlx5_list_entry *entry)
{
- struct mlx5_dev_ctx_shared *sh = list->ctx;
+ struct mlx5_dev_ctx_shared *sh = tool_ctx;
struct mlx5_flow_dv_tag_resource *tag =
- container_of(entry, struct mlx5_flow_dv_tag_resource, entry);
+ container_of(entry, struct mlx5_flow_dv_tag_resource, entry);
MLX5_ASSERT(tag && sh && tag->action);
claim_zero(mlx5_flow_os_destroy_flow_action(tag->action));
@@ -13592,19 +13673,10 @@ flow_dv_matcher_release(struct rte_eth_dev *dev,
return ret;
}
-/**
- * Release encap_decap resource.
- *
- * @param list
- * Pointer to the hash list.
- * @param entry
- * Pointer to exist resource entry object.
- */
void
-flow_dv_encap_decap_remove_cb(struct mlx5_hlist *list,
- struct mlx5_hlist_entry *entry)
+flow_dv_encap_decap_remove_cb(void *tool_ctx, struct mlx5_list_entry *entry)
{
- struct mlx5_dev_ctx_shared *sh = list->ctx;
+ struct mlx5_dev_ctx_shared *sh = tool_ctx;
struct mlx5_flow_dv_encap_decap_resource *res =
container_of(entry, typeof(*res), entry);
@@ -13664,8 +13736,8 @@ flow_dv_jump_tbl_resource_release(struct rte_eth_dev *dev,
}
void
-flow_dv_modify_remove_cb(struct mlx5_hlist *list __rte_unused,
- struct mlx5_hlist_entry *entry)
+flow_dv_modify_remove_cb(void *tool_ctx __rte_unused,
+ struct mlx5_list_entry *entry)
{
struct mlx5_flow_dv_modify_hdr_resource *res =
container_of(entry, typeof(*res), entry);