diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index cfb33251cf..38c5672436 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -50,8 +50,6 @@
 #include "mlx5_nl.h"
 #include "mlx5_devx.h"
 
-#define MLX5_TAGS_HLIST_ARRAY_SIZE	(1 << 15)
-
 #ifndef HAVE_IBV_MLX5_MOD_MPW
 #define MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED (1 << 2)
 #define MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW (1 << 3)
@@ -312,46 +310,6 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv)
 					      flow_dv_dest_array_clone_free_cb);
 	if (!sh->dest_array_list)
 		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, false,
-					  false, sh, flow_dv_tag_create_cb,
-					  flow_dv_tag_match_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;
-	}
-	snprintf(s, sizeof(s), "%s_hdr_modify", sh->ibdev_name);
-	sh->modify_cmds = mlx5_hlist_create(s, MLX5_FLOW_HDR_MODIFY_HTABLE_SZ,
-					    true, false, sh,
-					    flow_dv_modify_create_cb,
-					    flow_dv_modify_match_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;
-	}
-	snprintf(s, sizeof(s), "%s_encaps_decaps", sh->ibdev_name);
-	sh->encaps_decaps = mlx5_hlist_create(s,
-					      MLX5_FLOW_ENCAP_DECAP_HTABLE_SZ,
-					      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_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;
-	}
 #endif
 #ifdef HAVE_MLX5DV_DR
 	void *domain;
@@ -396,7 +354,7 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv)
 		goto error;
 	}
 #endif
-	if (!sh->tunnel_hub)
+	if (!sh->tunnel_hub && priv->config.dv_miss_info)
 		err = mlx5_alloc_tunnel_hub(sh);
 	if (err) {
 		DRV_LOG(ERR, "mlx5_alloc_tunnel_hub failed err=%d", err);
diff --git a/drivers/net/mlx5/mlx5_defs.h b/drivers/net/mlx5/mlx5_defs.h
index ca67ce8213..fe86bb40d3 100644
--- a/drivers/net/mlx5/mlx5_defs.h
+++ b/drivers/net/mlx5/mlx5_defs.h
@@ -188,6 +188,12 @@
 /* Size of the simple hash table for encap decap table. */
 #define MLX5_FLOW_ENCAP_DECAP_HTABLE_SZ (1 << 12)
 
+/* Size of the hash table for tag table. */
+#define MLX5_TAGS_HLIST_ARRAY_SIZE	(1 << 15)
+
+/* Size fo the hash table for SFT table. */
+#define MLX5_FLOW_SFT_HLIST_ARRAY_SIZE	4096
+
 /* Hairpin TX/RX queue configuration parameters. */
 #define MLX5_HAIRPIN_QUEUE_STRIDE 6
 #define MLX5_HAIRPIN_JUMBO_LOG_SIZE (14 + 2)
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index b30e5a82ce..9fc50a5daa 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -310,6 +310,41 @@ mlx5_flow_tunnel_ip_check(const struct rte_flow_item *item __rte_unused,
 	}
 }
 
+static inline struct mlx5_hlist *
+flow_dv_hlist_prepare(struct mlx5_dev_ctx_shared *sh, struct mlx5_hlist **phl,
+		     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 *hl;
+	struct mlx5_hlist *expected = NULL;
+	char s[MLX5_NAME_SIZE];
+
+	hl = __atomic_load_n(phl, __ATOMIC_SEQ_CST);
+	if (likely(hl))
+		return hl;
+	snprintf(s, sizeof(s), "%s_%s", sh->ibdev_name, name);
+	hl = mlx5_hlist_create(s, size, direct_key, lcores_share,
+			ctx, cb_create, cb_match, cb_remove, cb_clone,
+			cb_clone_free);
+	if (!hl) {
+		DRV_LOG(ERR, "%s hash creation failed", name);
+		rte_errno = ENOMEM;
+		return NULL;
+	}
+	if (!__atomic_compare_exchange_n(phl, &expected, hl, false,
+					 __ATOMIC_SEQ_CST,
+					 __ATOMIC_SEQ_CST)) {
+		mlx5_hlist_destroy(hl);
+		hl = __atomic_load_n(phl, __ATOMIC_SEQ_CST);
+	}
+	return hl;
+}
+
 /* Update VLAN's VID/PCP based on input rte_flow_action.
  *
  * @param[in] action
@@ -3724,8 +3759,20 @@ flow_dv_encap_decap_resource_register
 		.error = error,
 		.data = resource,
 	};
+	struct mlx5_hlist *encaps_decaps;
 	uint64_t key64;
 
+	encaps_decaps = flow_dv_hlist_prepare(sh, &sh->encaps_decaps,
+				"encaps_decaps",
+				MLX5_FLOW_ENCAP_DECAP_HTABLE_SZ,
+				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_clone_cb,
+				flow_dv_encap_decap_clone_free_cb);
+	if (unlikely(!encaps_decaps))
+		return -rte_errno;
 	resource->flags = dev_flow->dv.group ? 0 : 1;
 	key64 =  __rte_raw_cksum(&encap_decap_key.v32,
 				 sizeof(encap_decap_key.v32), 0);
@@ -3733,7 +3780,7 @@ flow_dv_encap_decap_resource_register
 	    MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TUNNEL_TO_L2 &&
 	    resource->size)
 		key64 = __rte_raw_cksum(resource->buf, resource->size, key64);
-	entry = mlx5_hlist_register(sh->encaps_decaps, key64, &ctx);
+	entry = mlx5_hlist_register(encaps_decaps, key64, &ctx);
 	if (!entry)
 		return -rte_errno;
 	resource = container_of(entry, typeof(*resource), entry);
@@ -5739,8 +5786,20 @@ flow_dv_modify_hdr_resource_register
 		.error = error,
 		.data = resource,
 	};
+	struct mlx5_hlist *modify_cmds;
 	uint64_t key64;
 
+	modify_cmds = flow_dv_hlist_prepare(sh, &sh->modify_cmds,
+				"hdr_modify",
+				MLX5_FLOW_HDR_MODIFY_HTABLE_SZ,
+				true, false, sh,
+				flow_dv_modify_create_cb,
+				flow_dv_modify_match_cb,
+				flow_dv_modify_remove_cb,
+				flow_dv_modify_clone_cb,
+				flow_dv_modify_clone_free_cb);
+	if (unlikely(!modify_cmds))
+		return -rte_errno;
 	resource->root = !dev_flow->dv.group;
 	if (resource->actions_num > flow_dv_modify_hdr_action_max(dev,
 								resource->root))
@@ -5748,7 +5807,7 @@ flow_dv_modify_hdr_resource_register
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
 					  "too many modify header items");
 	key64 = __rte_raw_cksum(&resource->ft_type, key_len, 0);
-	entry = mlx5_hlist_register(sh->modify_cmds, key64, &ctx);
+	entry = mlx5_hlist_register(modify_cmds, key64, &ctx);
 	if (!entry)
 		return -rte_errno;
 	resource = container_of(entry, typeof(*resource), entry);
@@ -10530,8 +10589,20 @@ flow_dv_tag_resource_register
 					.error = error,
 					.data = &tag_be24,
 					};
-
-	entry = mlx5_hlist_register(priv->sh->tag_table, tag_be24, &ctx);
+	struct mlx5_hlist *tag_table;
+
+	tag_table = flow_dv_hlist_prepare(priv->sh, &priv->sh->tag_table,
+				      "tags",
+				      MLX5_TAGS_HLIST_ARRAY_SIZE,
+				      false, false, priv->sh,
+				      flow_dv_tag_create_cb,
+				      flow_dv_tag_match_cb,
+				      flow_dv_tag_remove_cb,
+				      flow_dv_tag_clone_cb,
+				      flow_dv_tag_clone_free_cb);
+	if (unlikely(!tag_table))
+		return -rte_errno;
+	entry = mlx5_hlist_register(tag_table, tag_be24, &ctx);
 	if (entry) {
 		resource = container_of(entry, struct mlx5_flow_dv_tag_resource,
 					entry);
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index a04f93e1d4..5da362a9d5 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -30,8 +30,6 @@
 #include "mlx5_flow.h"
 #include "mlx5_devx.h"
 
-#define MLX5_TAGS_HLIST_ARRAY_SIZE 8192
-
 static const char *MZ_MLX5_PMD_SHARED_DATA = "mlx5_pmd_shared_data";
 
 /* Spinlock for mlx5_shared_data allocation. */
