[04/13] net/mlx5: use mask for meter register setting

Message ID 20210331073632.1443011-5-lizh@nvidia.com (mailing list archive)
State Superseded, archived
Delegated to: Raslan Darawsheh
Headers
Series Add ASO meter support in MLX5 PMD |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Li Zhang March 31, 2021, 7:36 a.m. UTC
  From: Shun Hao <shunh@nvidia.com>

ASO meter feature may require to locate the flow
context tag action after the ASO action.
When color register is shared by meter_id/flow_id, it's like:
Bits[0-7] A meter color value set by the HW.
Bits[8-31] A flow id and meter id set by SW.

Currently the tag action for meter writes all the bits
of the meter register, so it will potentially overwrite
meter color when ASO meter action is before the tag action.

Set only 24-MSB-bits of meter register in the meter tag action.

Signed-off-by: Shun Hao <shunh@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow.c    | 27 +++++++++++++++++----------
 drivers/net/mlx5/mlx5_flow.h    |  2 ++
 drivers/net/mlx5/mlx5_flow_dv.c |  2 ++
 3 files changed, 21 insertions(+), 10 deletions(-)
  

Patch

diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index cffd6129e8..a4bed659f2 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -4274,9 +4274,11 @@  flow_hairpin_split(struct rte_eth_dev *dev,
 	rte_memcpy(actions_rx, actions, sizeof(struct rte_flow_action));
 	actions_rx++;
 	set_tag = (void *)actions_rx;
-	set_tag->id = mlx5_flow_get_reg_id(dev, MLX5_HAIRPIN_RX, 0, NULL);
+	*set_tag = (struct mlx5_rte_flow_action_set_tag) {
+		.id = mlx5_flow_get_reg_id(dev, MLX5_HAIRPIN_RX, 0, NULL),
+		.data = flow_id,
+	};
 	MLX5_ASSERT(set_tag->id > REG_NON);
-	set_tag->data = flow_id;
 	tag_action->conf = set_tag;
 	/* Create Tx item list. */
 	rte_memcpy(actions_tx, actions, sizeof(struct rte_flow_action));
@@ -4511,6 +4513,13 @@  flow_meter_split_prep(struct rte_eth_dev *dev,
 	set_tag = (struct mlx5_rte_flow_action_set_tag *)actions_pre;
 	tag_item_spec = (struct mlx5_rte_flow_item_tag *)sfx_items;
 	tag_item_mask = tag_item_spec + 1;
+	/* Both flow_id and meter_id share the same register. */
+	*set_tag = (struct mlx5_rte_flow_action_set_tag) {
+		.id = mlx5_flow_get_reg_id(dev, MLX5_MTR_ID, 0, error),
+		.offset = mtr_id_offset,
+		.length = mtr_reg_bits,
+		.data = fm->idx,
+	};
 	/*
 	 * The color Reg bits used by flow_id are growing from
 	 * msb to lsb, so must do bit reverse for flow_id val in RegC.
@@ -4518,12 +4527,8 @@  flow_meter_split_prep(struct rte_eth_dev *dev,
 	for (shift = 0; shift < flow_id_bits; shift++)
 		flow_id_val = (flow_id_val << 1) |
 			      (((tag_id - 1) >> shift) & 0x1);
-	/* Both flow_id and meter_id share the same register. */
-	set_tag->id = mlx5_flow_get_reg_id(dev, MLX5_MTR_ID, 0, error);
-	set_tag->data =
-		(fm->idx | (flow_id_val << (mtr_reg_bits - flow_id_bits)))
-		<< mtr_id_offset;
-	tag_item_spec->id = set_tag->id;
+	set_tag->data |= flow_id_val << (mtr_reg_bits - flow_id_bits);
+	tag_item_spec->id = set_tag->id << mtr_id_offset;
 	tag_item_spec->data = set_tag->data;
 	tag_item_mask->data = UINT32_MAX << mtr_id_offset;
 	tag_action->type = (enum rte_flow_action_type)
@@ -4911,10 +4916,12 @@  flow_sample_split_prep(struct rte_eth_dev *dev,
 		ret = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG, 0, error);
 		if (ret < 0)
 			return ret;
-		set_tag->id = ret;
 		mlx5_ipool_malloc(priv->sh->ipool
 				  [MLX5_IPOOL_RSS_EXPANTION_FLOW_ID], &tag_id);
-		set_tag->data = tag_id;
+		*set_tag = (struct mlx5_rte_flow_action_set_tag) {
+			.id = ret,
+			.data = tag_id,
+		};
 		/* Prepare the suffix subflow items. */
 		tag_spec = (void *)(sfx_items + SAMPLE_SUFFIX_ITEM);
 		tag_spec->data = tag_id;
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 76870b8061..e7f0906209 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -55,6 +55,8 @@  struct mlx5_rte_flow_item_tag {
 /* Modify selected register. */
 struct mlx5_rte_flow_action_set_tag {
 	enum modify_reg id;
+	uint8_t offset;
+	uint8_t length;
 	uint32_t data;
 };
 
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index d5c8f32038..30fec09987 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -964,6 +964,8 @@  flow_dv_convert_action_set_reg
 	actions[i] = (struct mlx5_modification_cmd) {
 		.action_type = MLX5_MODIFICATION_TYPE_SET,
 		.field = reg_to_field[conf->id],
+		.offset = conf->offset,
+		.length = conf->length,
 	};
 	actions[i].data0 = rte_cpu_to_be_32(actions[i].data0);
 	actions[i].data1 = rte_cpu_to_be_32(conf->data);