Skip to contentSkip to conversation

net/mlx5: fix multi process Tx default rules

PATCH In review Gregory Etelson 2 participants 4 messages Oct 29, 2025 – Nov 2, 2025 Network drivers

lore
Share & tools
lore
#0 lore raw

PATCH 1/3 net/mlx5: fix multi process Tx default rules

From: Michael Baum <[email protected]>

When representor matching is disabled, an egress default rule is inserted which matches all and copies REG_A to REG_C_1 (when dv_xmeta_en == 4) and jump to group 1. All user rules started from group 1.

When 2 processes are working together, the first one creates this flow rule and the second one is failed with errno EEXIST. This renders all user egress rules in 2nd process to be invalid.

This patch changes this default rule match on SQs.

Fixes 483181f7b6dd ("net/mlx5: support device control of representor matching")

# Conflicts:
# drivers/net/mlx5/mlx5_flow_hw.c

---
 drivers/net/mlx5/mlx5_flow.h    |  4 +++-
 drivers/net/mlx5/mlx5_flow_hw.c | 24 +++++++++++-------------
 drivers/net/mlx5/mlx5_trigger.c | 25 +++++++++++++------------
 drivers/net/mlx5/mlx5_txq.c     |  8 ++++++++
 4 files changed, 35 insertions(+), 26 deletions(-)
drivers/net/mlx5/mlx5_flow.h +3 -1
index ff61706054..07d2f4185c 100644
@@ -3582,7 +3582,9 @@ int mlx5_flow_hw_esw_create_sq_miss_flow(struct rte_eth_dev *dev,
 int mlx5_flow_hw_esw_destroy_sq_miss_flow(struct rte_eth_dev *dev,
 					  uint32_t sqn);
 int mlx5_flow_hw_esw_create_default_jump_flow(struct rte_eth_dev *dev);
-int mlx5_flow_hw_create_tx_default_mreg_copy_flow(struct rte_eth_dev *dev);
+int mlx5_flow_hw_create_tx_default_mreg_copy_flow(struct rte_eth_dev *dev,
+						  uint32_t sqn,
+						  bool external);
 int mlx5_flow_hw_tx_repr_matching_flow(struct rte_eth_dev *dev, uint32_t sqn, bool external);
 int mlx5_flow_hw_lacp_rx_flow(struct rte_eth_dev *dev);
 int mlx5_flow_actions_validate(struct rte_eth_dev *dev,
drivers/net/mlx5/mlx5_flow_hw.c +11 -13
index 491a78a0de..d945c88eb0 100644
@@ -10643,7 +10643,7 @@ flow_hw_create_tx_default_mreg_copy_table(struct rte_eth_dev *dev,
 			.priority = MLX5_HW_LOWEST_PRIO_ROOT,
 			.egress = 1,
 		},
-		.nb_flows = 1, /* One default flow rule for all. */
+		.nb_flows = MLX5_HW_CTRL_FLOW_NB_RULES,
 	};
 	struct mlx5_flow_template_table_cfg tx_tbl_cfg = {
 		.attr = tx_tbl_attr,
@@ -16004,21 +16004,18 @@ mlx5_flow_hw_esw_create_default_jump_flow(struct rte_eth_dev *dev)
 }
 
 int
-mlx5_flow_hw_create_tx_default_mreg_copy_flow(struct rte_eth_dev *dev)
+mlx5_flow_hw_create_tx_default_mreg_copy_flow(struct rte_eth_dev *dev, uint32_t sqn, bool external)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct rte_flow_item_eth promisc = {
-		.hdr.dst_addr.addr_bytes = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
-		.hdr.src_addr.addr_bytes = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
-		.hdr.ether_type = 0,
+	struct mlx5_rte_flow_item_sq sq_spec = {
+		.queue = sqn,
 	};
-	struct rte_flow_item eth_all[] = {
-		[0] = {
-			.type = RTE_FLOW_ITEM_TYPE_ETH,
-			.spec = &promisc,
-			.mask = &promisc,
+	struct rte_flow_item items[] = {
+		{
+			.type = (enum rte_flow_item_type)MLX5_RTE_FLOW_ITEM_TYPE_SQ,
+			.spec = &sq_spec,
 		},
-		[1] = {
+		{
 			.type = RTE_FLOW_ITEM_TYPE_END,
 		},
 	};
@@ -16048,6 +16045,7 @@ mlx5_flow_hw_create_tx_default_mreg_copy_flow(struct rte_eth_dev *dev)
 	};
 	struct mlx5_ctrl_flow_info flow_info = {
 		.type = MLX5_CTRL_FLOW_TYPE_TX_META_COPY,
+		.tx_repr_sq = sqn,
 	};
 
 	MLX5_ASSERT(priv->master);
@@ -16057,7 +16055,7 @@ mlx5_flow_hw_create_tx_default_mreg_copy_flow(struct rte_eth_dev *dev)
 		return 0;
 	return flow_hw_create_ctrl_flow(dev, dev,
 					priv->hw_ctrl_fdb->hw_tx_meta_cpy_tbl,
-					eth_all, 0, copy_reg_action, 0, &flow_info, false);
+					items, 0, copy_reg_action, 0, &flow_info, external);
 }
 
 int
drivers/net/mlx5/mlx5_trigger.c +13 -12
index 916ac03c16..e6acb56d4d 100644
@@ -1606,18 +1606,6 @@ mlx5_traffic_enable_hws(struct rte_eth_dev *dev)
 	unsigned int i;
 	int ret;
 
-	/*
-	 * With extended metadata enabled, the Tx metadata copy is handled by default
-	 * Tx tagging flow rules, so default Tx flow rule is not needed. It is only
-	 * required when representor matching is disabled.
-	 */
-	if (config->dv_esw_en &&
-	    !config->repr_matching &&
-	    config->dv_xmeta_en == MLX5_XMETA_MODE_META32_HWS &&
-	    priv->master) {
-		if (mlx5_flow_hw_create_tx_default_mreg_copy_flow(dev))
-			goto error;
-	}
 	for (i = 0; i < priv->txqs_n; ++i) {
 		struct mlx5_txq_ctrl *txq = mlx5_txq_get(dev, i);
 		uint32_t queue;
@@ -1639,6 +1627,19 @@ mlx5_traffic_enable_hws(struct rte_eth_dev *dev)
 				goto error;
 			}
 		}
+		/*
+		 * With extended metadata enabled, the Tx metadata copy is handled by default
+		 * Tx tagging flow rules, so default Tx flow rule is not needed. It is only
+		 * required when representor matching is disabled.
+		 */
+		if (config->dv_esw_en && !config->repr_matching &&
+		    config->dv_xmeta_en == MLX5_XMETA_MODE_META32_HWS &&
+		    (priv->master || priv->representor)) {
+			if (mlx5_flow_hw_create_tx_default_mreg_copy_flow(dev, queue, false)) {
+				mlx5_txq_release(dev, i);
+				goto error;
+			}
+		}
 		mlx5_txq_release(dev, i);
 	}
 	if (config->fdb_def_rule) {
drivers/net/mlx5/mlx5_txq.c +8 -0
index b090d8274d..834ca541d5 100644
@@ -1459,6 +1459,14 @@ rte_pmd_mlx5_external_sq_enable(uint16_t port_id, uint32_t sq_num)
 				mlx5_flow_hw_esw_destroy_sq_miss_flow(dev, sq_num);
 			return -rte_errno;
 		}
+
+		if (!priv->sh->config.repr_matching &&
+		    priv->sh->config.dv_xmeta_en == MLX5_XMETA_MODE_META32_HWS &&
+		    mlx5_flow_hw_create_tx_default_mreg_copy_flow(dev, sq_num, true)) {
+			if (sq_miss_created)
+				mlx5_flow_hw_esw_destroy_sq_miss_flow(dev, sq_num);
+			return -rte_errno;
+		}
 		return 0;
 	}
 #endif
Signature · 1 line
2.51.0
#1 lore raw

PATCH 2/3 net/mlx5: fix control flow leakage for external SQ

From: Viacheslav Ovsiienko <[email protected]>

There is the private API rte_pmd_mlx5_external_sq_enable(), that allows application to create the Send Queue (SQ) on its own and then enable this queue usage as "external SQ".

On this enabling call some implicit flows are created to provide compliant SQs behavior - copy metadata register, forward queue originated packet to correct VF, etc.

These implicit flows are marked as "external" ones, and there is no cleanup on device start and stop for this kind of flows. Also, PMD has no knowledge if external SQ is still in use by application and implicit cleanup can not be performed.

As a result, on multiple device start/stop cycles application re-creates and re-enables many external SQs, causing implicit flow tables overflow.

To resolve this issue the rte_pmd_mlx5_external_sq_disable() API is provided, that allows to application to notify PMD the external SQ is not in usage anymore and related implicit flows can be dismissed.

Fixes 26e1eaf2dac4 ("net/mlx5: support device control for E-Switch default rule")
---
 drivers/net/mlx5/mlx5_flow.h    |  12 ++--
 drivers/net/mlx5/mlx5_flow_hw.c | 106 +++++++++++++++++++++++++++++++-
 drivers/net/mlx5/mlx5_trigger.c |   2 +-
 drivers/net/mlx5/mlx5_txq.c     |  55 +++++++++++++++--
 drivers/net/mlx5/rte_pmd_mlx5.h |  18 ++++++
 5 files changed, 181 insertions(+), 12 deletions(-)
drivers/net/mlx5/mlx5_flow.h +8 -4
index 07d2f4185c..adfe84ef54 100644
@@ -3580,12 +3580,16 @@ int mlx5_flow_hw_flush_ctrl_flows(struct rte_eth_dev *dev);
 int mlx5_flow_hw_esw_create_sq_miss_flow(struct rte_eth_dev *dev,
 					 uint32_t sqn, bool external);
 int mlx5_flow_hw_esw_destroy_sq_miss_flow(struct rte_eth_dev *dev,
-					  uint32_t sqn);
+					  uint32_t sqn, bool external);
 int mlx5_flow_hw_esw_create_default_jump_flow(struct rte_eth_dev *dev);
 int mlx5_flow_hw_create_tx_default_mreg_copy_flow(struct rte_eth_dev *dev,
-						  uint32_t sqn,
-						  bool external);
-int mlx5_flow_hw_tx_repr_matching_flow(struct rte_eth_dev *dev, uint32_t sqn, bool external);
+						  uint32_t sqn, bool external);
+int mlx5_flow_hw_destroy_tx_default_mreg_copy_flow(struct rte_eth_dev *dev,
+						   uint32_t sqn, bool external);
+int mlx5_flow_hw_create_tx_repr_matching_flow(struct rte_eth_dev *dev,
+					      uint32_t sqn, bool external);
+int mlx5_flow_hw_destroy_tx_repr_matching_flow(struct rte_eth_dev *dev,
+					       uint32_t sqn, bool external);
 int mlx5_flow_hw_lacp_rx_flow(struct rte_eth_dev *dev);
 int mlx5_flow_actions_validate(struct rte_eth_dev *dev,
 		const struct rte_flow_actions_template_attr *attr,
drivers/net/mlx5/mlx5_flow_hw.c +103 -3

131 lines not on this page · raw message

drivers/net/mlx5/mlx5_trigger.c +1 -1
index e6acb56d4d..6acf398ccc 100644
@@ -1622,7 +1622,7 @@ mlx5_traffic_enable_hws(struct rte_eth_dev *dev)
 			}
 		}
 		if (config->dv_esw_en && config->repr_matching) {
-			if (mlx5_flow_hw_tx_repr_matching_flow(dev, queue, false)) {
+			if (mlx5_flow_hw_create_tx_repr_matching_flow(dev, queue, false)) {
 				mlx5_txq_release(dev, i);
 				goto error;
 			}
drivers/net/mlx5/mlx5_txq.c +51 -4

80 lines not on this page · raw message

drivers/net/mlx5/rte_pmd_mlx5.h +18 -0
index 4d4821afae..31f99e7a78 100644
@@ -484,6 +484,24 @@ typedef void (*rte_pmd_mlx5_driver_event_callback_t)(uint16_t port_id,
 		const void *opaque);
 
 
+/**
+ * Disable traffic for external SQ. Should be invoked by application
+ * before destroying the external SQ.
+ *
+ * @param[in] port_id
+ *   The port identifier of the Ethernet device.
+ * @param[in] sq_num
+ *   SQ HW number.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ *   Possible values for rte_errno:
+ *   - EINVAL - invalid sq_number or port type.
+ *   - ENODEV - there is no Ethernet device for this port id.
+ */
+__rte_experimental
+int rte_pmd_mlx5_external_sq_disable(uint16_t port_id, uint32_t sq_num);
+
 /**
  * Register mlx5 driver event callback.
  *
Signature · 1 line
2.51.0
#2 lore raw

PATCH 3/3 net/mlx5: support flow metadata exchange between E-Switch and VM

In reply to Gregory Etelson

MLX5 port firmware has wiped out flow metadata if a packet was moved between E-switch and VM applications.

Starting from version 47.0274, firmware can be configured to preserve flow metadata after a packet was transferred between E-Switch and VM applications.

The patch allows VM application to work with ingress and egress flow metadata:

* Support FDB-to-VPORT and VPORT-to-FDB bits in firmware VPORT table.
* If VM ingress flow has RSS or QUEUE actions, copy medata from C1 register to B register.
* For VM egress flows, copy medata from register A to register C1.

---
 doc/guides/nics/mlx5.rst             |  10 ++
 drivers/common/mlx5/mlx5_devx_cmds.c |  31 ++++++
 drivers/common/mlx5/mlx5_devx_cmds.h |   5 +
 drivers/common/mlx5/mlx5_prm.h       |  55 +++++++++-
 drivers/net/mlx5/mlx5.c              |   4 +-
 drivers/net/mlx5/mlx5.h              |   3 +-
 drivers/net/mlx5/mlx5_flow.c         |  74 ++++++++++----
 drivers/net/mlx5/mlx5_flow.h         |  18 +++-
 drivers/net/mlx5/mlx5_flow_hw.c      | 144 +++++++++++++++++++++++++--
 drivers/net/mlx5/mlx5_trigger.c      |  13 ++-
 drivers/net/mlx5/mlx5_txq.c          |   2 +-
 11 files changed, 322 insertions(+), 37 deletions(-)
doc/guides/nics/mlx5.rst +10 -0
index 20056f61d6..fde98ae993 100644
@@ -2482,6 +2482,16 @@ and it should be allowed to specify zero values as parameters
 for the META and MARK flow items and actions.
 In the same time, zero mask has no meaning and should be rejected on validation stage.
 
+Starting from firmware version 47.0274, if :ref:`switchdev mode <mlx5_switchdev>` was enabled
+flow metadata can be shared between flows in FDB and VF domains:
+
+* If metadata was attached to FDB flow and that flow transferred incoming packet to a VF,
+  representor, ingress flow bound to the VF can match the metadata.
+
+* If metadata was attached to VF egress flow, FDB flow can match the metadata.
+
+The metadata sharing functionality is controlled with firmware configuration.
+
 Requirements
 ^^^^^^^^^^^^
 
drivers/common/mlx5/mlx5_devx_cmds.c +31 -0
index 5622847a4a..385759230a 100644
@@ -487,6 +487,34 @@ mlx5_devx_cmd_destroy(struct mlx5_devx_obj *obj)
 	return ret;
 }
 
+static int
+mlx5_devx_cmd_query_esw_vport_context(void *ctx,
+				      struct mlx5_hca_attr *attr)
+{
+	uint32_t in[MLX5_ST_SZ_DW(query_esw_vport_context_in)] = {0};
+	uint32_t out[MLX5_ST_SZ_DW(query_esw_vport_context_out)] = {0};
+	void *vctx;
+	int rc;
+
+	MLX5_SET(query_esw_vport_context_in, in, opcode, MLX5_CMD_OP_QUERY_ESW_VPORT_CONTEXT);
+	rc = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
+	if (rc || MLX5_FW_STATUS(out)) {
+		DEVX_DRV_LOG(ERR, out, "query ESW vport context", NULL, 0);
+		return MLX5_DEVX_ERR_RC(rc);
+	}
+	vctx = MLX5_ADDR_OF(query_esw_vport_context_out, out, esw_vport_context);
+	attr->fdb_to_vport_reg_c = MLX5_GET(esw_vport_context, vctx, fdb_to_vport_reg_c);
+	if (attr->fdb_to_vport_reg_c != 0) {
+		attr->vport_to_fdb_metadata =
+			MLX5_GET(esw_vport_context, vctx, vport_to_fdb_metadata);
+		attr->fdb_to_vport_metadata =
+			MLX5_GET(esw_vport_context, vctx, fdb_to_vport_metadata);
+		attr->fdb_to_vport_reg_c_id =
+			MLX5_GET(esw_vport_context, vctx, fdb_to_vport_reg_c_id);
+	}
+	return 0;
+}
+
 /**
  * Query NIC vport context.
  * Fills minimal inline attribute.
@@ -531,6 +559,8 @@ mlx5_devx_cmd_query_nic_vport_context(void *ctx,
 						   min_wqe_inline_mode);
 	attr->system_image_guid = MLX5_GET64(nic_vport_context, vctx,
 					     system_image_guid);
+	attr->vport_to_fdb_metadata = MLX5_GET(nic_vport_context, vctx, vport_to_fdb_metadata);
+	attr->fdb_to_vport_metadata = MLX5_GET(nic_vport_context, vctx, fdb_to_vport_metadata);
 	return 0;
 }
 
@@ -1407,6 +1437,7 @@ mlx5_devx_cmd_query_hca_attr(void *ctx,
 				 esw_manager_vport_number_valid);
 		attr->esw_mgr_vport_id =
 			MLX5_GET(esw_cap, hcattr, esw_manager_vport_number);
+		mlx5_devx_cmd_query_esw_vport_context(ctx, attr);
 	}
 	if (attr->eswitch_manager) {
 		uint32_t esw_reg, reg_c_8_15;
drivers/common/mlx5/mlx5_devx_cmds.h +5 -0
index 01dbb40040..efae6826dc 100644
@@ -262,6 +262,8 @@ struct mlx5_hca_attr {
 	uint32_t mini_cqe_resp_l3_l4_tag:1;
 	uint32_t enhanced_cqe_compression:1;
 	uint32_t pkt_integrity_match:1; /* 1 if HW supports integrity item */
+	uint32_t fdb_to_vport_metadata:1; /* 1 if enabled */
+	uint32_t vport_to_fdb_metadata:1; /* 1 if enabled */
 	struct mlx5_hca_qos_attr qos;
 	struct mlx5_hca_vdpa_attr vdpa;
 	struct mlx5_hca_flow_attr flow;
@@ -328,6 +330,9 @@ struct mlx5_hca_attr {
 	uint32_t fdb_unified_en:1;
 	uint32_t jump_fdb_rx_en:1;
 	uint32_t fdb_rx_set_flow_tag_stc:1;
+	uint32_t return_reg_id:16;
+	uint32_t fdb_to_vport_reg_c:1;
+	uint8_t fdb_to_vport_reg_c_id;
 	uint8_t max_header_modify_pattern_length;
 	uint64_t system_image_guid;
 	uint32_t log_max_conn_track_offload:5;
drivers/common/mlx5/mlx5_prm.h +54 -1

74 lines not on this page · raw message

drivers/net/mlx5/mlx5.c +3 -1
index b018a4f0e2..6686dd7587 100644
@@ -1651,7 +1651,9 @@ mlx5_init_hws_flow_tags_registers(struct mlx5_dev_ctx_shared *sh)
 	unset |= 1 << mlx5_regc_index(REG_C_6);
 	if (sh->config.dv_esw_en)
 		unset |= 1 << mlx5_regc_index(REG_C_0);
-	if (meta_mode == MLX5_XMETA_MODE_META32_HWS)
+	if (meta_mode == MLX5_XMETA_MODE_META32_HWS ||
+	    mlx5_vport_rx_metadata_passing_enabled(sh) ||
+	    mlx5_vport_tx_metadata_passing_enabled(sh))
 		unset |= 1 << mlx5_regc_index(REG_C_1);
 	masks &= ~unset;
 	for (i = 0, j = 0; i < MLX5_FLOW_HW_TAGS_MAX; i++) {
drivers/net/mlx5/mlx5.h +2 -1
index 07418b0922..e955c19217 100644
@@ -2032,7 +2032,8 @@ struct mlx5_priv {
 	rte_spinlock_t hw_ctrl_lock;
 	LIST_HEAD(hw_ctrl_flow, mlx5_ctrl_flow_entry) hw_ctrl_flows;
 	LIST_HEAD(hw_ext_ctrl_flow, mlx5_ctrl_flow_entry) hw_ext_ctrl_flows;
-	struct mlx5_flow_hw_ctrl_fdb *hw_ctrl_fdb;
+	struct mlx5_flow_hw_ctrl_fdb *hw_ctrl_fdb; /* FDB control flow context */
+	struct mlx5_flow_hw_ctrl_nic *hw_ctrl_nic; /* NIC control flow context */
 	struct rte_flow_pattern_template *hw_tx_repr_tagging_pt;
 	struct rte_flow_actions_template *hw_tx_repr_tagging_at;
 	struct rte_flow_template_table *hw_tx_repr_tagging_tbl;
drivers/net/mlx5/mlx5_flow.c +57 -17

93 lines not on this page · raw message

drivers/net/mlx5/mlx5_flow.h +17 -1
index adfe84ef54..2a7d22dfad 100644
@@ -1755,6 +1755,10 @@ struct rte_flow_template_table {
 	struct mlx5_dr_rule_action_container rule_acts[];
 };
 
+bool mlx5_vport_rx_metadata_passing_enabled(const struct mlx5_dev_ctx_shared *sh);
+bool mlx5_vport_tx_metadata_passing_enabled(const struct mlx5_dev_ctx_shared *sh);
+bool mlx5_esw_metadata_passing_enabled(const struct mlx5_dev_ctx_shared *sh);
+
 static __rte_always_inline struct mlx5dr_matcher *
 mlx5_table_matcher(const struct rte_flow_template_table *table)
 {
@@ -1799,6 +1803,11 @@ flow_hw_get_reg_id_by_domain(struct rte_eth_dev *dev,
 		    sh->config.dv_xmeta_en == MLX5_XMETA_MODE_META32_HWS) {
 			return REG_C_1;
 		}
+		if ((mlx5_vport_rx_metadata_passing_enabled(sh) &&
+		     domain_type == MLX5DR_TABLE_TYPE_NIC_RX) ||
+		    (mlx5_vport_tx_metadata_passing_enabled(sh) &&
+		     domain_type == MLX5DR_TABLE_TYPE_NIC_TX))
+			return REG_C_1;
 		/*
 		 * On root table - PMD allows only egress META matching, thus
 		 * REG_A matching is sufficient.
@@ -3015,6 +3024,12 @@ struct mlx5_flow_hw_ctrl_fdb {
 	struct rte_flow_template_table *hw_lacp_rx_tbl;
 };
 
+struct mlx5_flow_hw_ctrl_nic {
+	struct rte_flow_pattern_template *tx_meta_items_tmpl;
+	struct rte_flow_actions_template *tx_meta_actions_tmpl;
+	struct rte_flow_template_table *hw_tx_meta_cpy_tbl;
+};
+
 #define MLX5_CTRL_PROMISCUOUS    (RTE_BIT32(0))
 #define MLX5_CTRL_ALL_MULTICAST  (RTE_BIT32(1))
 #define MLX5_CTRL_BROADCAST      (RTE_BIT32(2))
@@ -3582,8 +3597,9 @@ int mlx5_flow_hw_esw_create_sq_miss_flow(struct rte_eth_dev *dev,
 int mlx5_flow_hw_esw_destroy_sq_miss_flow(struct rte_eth_dev *dev,
 					  uint32_t sqn, bool external);
 int mlx5_flow_hw_esw_create_default_jump_flow(struct rte_eth_dev *dev);
-int mlx5_flow_hw_create_tx_default_mreg_copy_flow(struct rte_eth_dev *dev,
+int mlx5_flow_hw_create_fdb_tx_default_mreg_copy_flow(struct rte_eth_dev *dev,
 						  uint32_t sqn, bool external);
+int mlx5_flow_hw_create_nic_tx_default_mreg_copy_flow(struct rte_eth_dev *dev, uint32_t sqn);
 int mlx5_flow_hw_destroy_tx_default_mreg_copy_flow(struct rte_eth_dev *dev,
 						   uint32_t sqn, bool external);
 int mlx5_flow_hw_create_tx_repr_matching_flow(struct rte_eth_dev *dev,
drivers/net/mlx5/mlx5_flow_hw.c +134 -10

198 lines not on this page · raw message

drivers/net/mlx5/mlx5_trigger.c +8 -5
index 6acf398ccc..996c1eb6ac 100644
@@ -1604,7 +1604,7 @@ mlx5_traffic_enable_hws(struct rte_eth_dev *dev)
 	struct mlx5_sh_config *config = &priv->sh->config;
 	uint64_t flags = 0;
 	unsigned int i;
-	int ret;
+	int ret = 0;
 
 	for (i = 0; i < priv->txqs_n; ++i) {
 		struct mlx5_txq_ctrl *txq = mlx5_txq_get(dev, i);
@@ -1635,10 +1635,13 @@ mlx5_traffic_enable_hws(struct rte_eth_dev *dev)
 		if (config->dv_esw_en && !config->repr_matching &&
 		    config->dv_xmeta_en == MLX5_XMETA_MODE_META32_HWS &&
 		    (priv->master || priv->representor)) {
-			if (mlx5_flow_hw_create_tx_default_mreg_copy_flow(dev, queue, false)) {
-				mlx5_txq_release(dev, i);
-				goto error;
-			}
+			ret = mlx5_flow_hw_create_fdb_tx_default_mreg_copy_flow(dev, queue, false);
+		} else if (mlx5_vport_tx_metadata_passing_enabled(priv->sh)) {
+			ret = mlx5_flow_hw_create_nic_tx_default_mreg_copy_flow(dev, queue);
+		}
+		if (ret != 0) {
+			mlx5_txq_release(dev, i);
+			goto error;
 		}
 		mlx5_txq_release(dev, i);
 	}
drivers/net/mlx5/mlx5_txq.c +1 -1
index 1d258f979c..e20165d74e 100644
@@ -1462,7 +1462,7 @@ rte_pmd_mlx5_external_sq_enable(uint16_t port_id, uint32_t sq_num)
 
 		if (!priv->sh->config.repr_matching &&
 		    priv->sh->config.dv_xmeta_en == MLX5_XMETA_MODE_META32_HWS &&
-		    mlx5_flow_hw_create_tx_default_mreg_copy_flow(dev, sq_num, true)) {
+		    mlx5_flow_hw_create_fdb_tx_default_mreg_copy_flow(dev, sq_num, true)) {
 			if (sq_miss_created)
 				mlx5_flow_hw_esw_destroy_sq_miss_flow(dev, sq_num, true);
 			return -rte_errno;
Signature · 1 line
2.51.0
#3 lore raw
In reply to Gregory Etelson

Hi,

Quoted 10 lines · Gregory Etelson

From: Michael Baum <[email protected]>

When representor matching is disabled, an egress default rule is inserted which matches all and copies REG_A to REG_C_1 (when dv_xmeta_en == 4) and jump to group 1. All user rules started from group 1.

When 2 processes are working together, the first one creates this flow rule and the second one is failed with errno EEXIST. This renders all user egress rules in 2nd process to be invalid.

Quoted 8 lines

This patch changes this default rule match on SQs.

Fixes 483181f7b6dd ("net/mlx5: support device control of representor matching")

Series applied to next-net-mlx,

Kindest regards
Raslan Darawsheh