Commit 4f953be8 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'mlx5-hws-fixes-2025-08-17'

Mark Bloch says:

====================
mlx5 HWS fixes 2025-08-17

The following patch set focuses on hardware steering fixes
found by the team.
====================

Link: https://patch.msgid.link/20250817202323.308604-1-mbloch@nvidia.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents d9cef55e d2d6f950
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -173,6 +173,8 @@ static void mlx5_ct_fs_hmfs_fill_rule_actions(struct mlx5_ct_fs_hmfs *fs_hmfs,

	memset(rule_actions, 0, NUM_CT_HMFS_RULES * sizeof(*rule_actions));
	rule_actions[0].action = mlx5_fc_get_hws_action(fs_hmfs->ctx, attr->counter);
	rule_actions[0].counter.offset =
		attr->counter->id - attr->counter->bulk->base_id;
	/* Modify header is special, it may require extra arguments outside the action itself. */
	if (mh_action->mh_data) {
		rule_actions[1].modify_header.offset = mh_action->mh_data->offset;
+62 −19
Original line number Diff line number Diff line
@@ -74,9 +74,9 @@ static void hws_bwc_matcher_init_attr(struct mlx5hws_bwc_matcher *bwc_matcher,
static int
hws_bwc_matcher_move_all_simple(struct mlx5hws_bwc_matcher *bwc_matcher)
{
	bool move_error = false, poll_error = false, drain_error = false;
	struct mlx5hws_context *ctx = bwc_matcher->matcher->tbl->ctx;
	struct mlx5hws_matcher *matcher = bwc_matcher->matcher;
	int drain_error = 0, move_error = 0, poll_error = 0;
	u16 bwc_queues = mlx5hws_bwc_queues(ctx);
	struct mlx5hws_rule_attr rule_attr;
	struct mlx5hws_bwc_rule *bwc_rule;
@@ -84,6 +84,7 @@ hws_bwc_matcher_move_all_simple(struct mlx5hws_bwc_matcher *bwc_matcher)
	struct list_head *rules_list;
	u32 pending_rules;
	int i, ret = 0;
	bool drain;

	mlx5hws_bwc_rule_fill_attr(bwc_matcher, 0, 0, &rule_attr);

@@ -99,23 +100,37 @@ hws_bwc_matcher_move_all_simple(struct mlx5hws_bwc_matcher *bwc_matcher)
			ret = mlx5hws_matcher_resize_rule_move(matcher,
							       bwc_rule->rule,
							       &rule_attr);
			if (unlikely(ret && !move_error)) {
			if (unlikely(ret)) {
				if (!move_error) {
					mlx5hws_err(ctx,
						    "Moving BWC rule: move failed (%d), attempting to move rest of the rules\n",
						    ret);
				move_error = true;
					move_error = ret;
				}
				/* Rule wasn't queued, no need to poll */
				continue;
			}

			pending_rules++;
			drain = pending_rules >=
				hws_bwc_get_burst_th(ctx, rule_attr.queue_id);
			ret = mlx5hws_bwc_queue_poll(ctx,
						     rule_attr.queue_id,
						     &pending_rules,
						     false);
			if (unlikely(ret && !poll_error)) {
						     drain);
			if (unlikely(ret)) {
				if (ret == -ETIMEDOUT) {
					mlx5hws_err(ctx,
						    "Moving BWC rule: timeout polling for completions (%d), aborting rehash\n",
						    ret);
					return ret;
				}
				if (!poll_error) {
					mlx5hws_err(ctx,
					    "Moving BWC rule: poll failed (%d), attempting to move rest of the rules\n",
						    "Moving BWC rule: polling for completions failed (%d), attempting to move rest of the rules\n",
						    ret);
				poll_error = true;
					poll_error = ret;
				}
			}
		}

@@ -126,17 +141,30 @@ hws_bwc_matcher_move_all_simple(struct mlx5hws_bwc_matcher *bwc_matcher)
						     rule_attr.queue_id,
						     &pending_rules,
						     true);
			if (unlikely(ret && !drain_error)) {
			if (unlikely(ret)) {
				if (ret == -ETIMEDOUT) {
					mlx5hws_err(ctx,
					    "Moving BWC rule: drain failed (%d), attempting to move rest of the rules\n",
						    "Moving bwc rule: timeout draining completions (%d), aborting rehash\n",
						    ret);
				drain_error = true;
					return ret;
				}
				if (!drain_error) {
					mlx5hws_err(ctx,
						    "Moving bwc rule: drain failed (%d), attempting to move rest of the rules\n",
						    ret);
					drain_error = ret;
				}
			}
		}
	}

	if (move_error || poll_error || drain_error)
		ret = -EINVAL;
	/* Return the first error that happened */
	if (unlikely(move_error))
		return move_error;
	if (unlikely(poll_error))
		return poll_error;
	if (unlikely(drain_error))
		return drain_error;

	return ret;
}
@@ -1035,6 +1063,21 @@ int mlx5hws_bwc_rule_create_simple(struct mlx5hws_bwc_rule *bwc_rule,
		return 0; /* rule inserted successfully */
	}

	/* Rule insertion could fail due to queue being full, timeout, or
	 * matcher in resize. In such cases, no point in trying to rehash.
	 */
	if (ret == -EBUSY || ret == -ETIMEDOUT || ret == -EAGAIN) {
		mutex_unlock(queue_lock);
		mlx5hws_err(ctx,
			    "BWC rule insertion failed - %s (%d)\n",
			    ret == -EBUSY ? "queue is full" :
			    ret == -ETIMEDOUT ? "timeout" :
			    ret == -EAGAIN ? "matcher in resize" : "N/A",
			    ret);
		hws_bwc_rule_cnt_dec(bwc_rule);
		return ret;
	}

	/* At this point the rule wasn't added.
	 * It could be because there was collision, or some other problem.
	 * Try rehash by size and insert rule again - last chance.
+28 −13
Original line number Diff line number Diff line
@@ -1328,11 +1328,11 @@ mlx5hws_bwc_matcher_move_all_complex(struct mlx5hws_bwc_matcher *bwc_matcher)
{
	struct mlx5hws_context *ctx = bwc_matcher->matcher->tbl->ctx;
	struct mlx5hws_matcher *matcher = bwc_matcher->matcher;
	bool move_error = false, poll_error = false;
	u16 bwc_queues = mlx5hws_bwc_queues(ctx);
	struct mlx5hws_bwc_rule *tmp_bwc_rule;
	struct mlx5hws_rule_attr rule_attr;
	struct mlx5hws_table *isolated_tbl;
	int move_error = 0, poll_error = 0;
	struct mlx5hws_rule *tmp_rule;
	struct list_head *rules_list;
	u32 expected_completions = 1;
@@ -1391,11 +1391,15 @@ mlx5hws_bwc_matcher_move_all_complex(struct mlx5hws_bwc_matcher *bwc_matcher)
			ret = mlx5hws_matcher_resize_rule_move(matcher,
							       tmp_rule,
							       &rule_attr);
			if (unlikely(ret && !move_error)) {
			if (unlikely(ret)) {
				if (!move_error) {
					mlx5hws_err(ctx,
					    "Moving complex BWC rule failed (%d), attempting to move rest of the rules\n",
						    "Moving complex BWC rule: move failed (%d), attempting to move rest of the rules\n",
						    ret);
				move_error = true;
					move_error = ret;
				}
				/* Rule wasn't queued, no need to poll */
				continue;
			}

			expected_completions = 1;
@@ -1403,11 +1407,19 @@ mlx5hws_bwc_matcher_move_all_complex(struct mlx5hws_bwc_matcher *bwc_matcher)
						     rule_attr.queue_id,
						     &expected_completions,
						     true);
			if (unlikely(ret && !poll_error)) {
			if (unlikely(ret)) {
				if (ret == -ETIMEDOUT) {
					mlx5hws_err(ctx,
						    "Moving complex BWC rule: timeout polling for completions (%d), aborting rehash\n",
						    ret);
					return ret;
				}
				if (!poll_error) {
					mlx5hws_err(ctx,
					    "Moving complex BWC rule: poll failed (%d), attempting to move rest of the rules\n",
						    "Moving complex BWC rule: polling for completions failed (%d), attempting to move rest of the rules\n",
						    ret);
				poll_error = true;
					poll_error = ret;
				}
			}

			/* Done moving the rule to the new matcher,
@@ -1422,8 +1434,11 @@ mlx5hws_bwc_matcher_move_all_complex(struct mlx5hws_bwc_matcher *bwc_matcher)
		}
	}

	if (move_error || poll_error)
		ret = -EINVAL;
	/* Return the first error that happened */
	if (unlikely(move_error))
		return move_error;
	if (unlikely(poll_error))
		return poll_error;

	return ret;
}
+1 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ int mlx5hws_cmd_flow_table_create(struct mlx5_core_dev *mdev,

	MLX5_SET(create_flow_table_in, in, opcode, MLX5_CMD_OP_CREATE_FLOW_TABLE);
	MLX5_SET(create_flow_table_in, in, table_type, ft_attr->type);
	MLX5_SET(create_flow_table_in, in, uid, ft_attr->uid);

	ft_ctx = MLX5_ADDR_OF(create_flow_table_in, in, flow_table_context);
	MLX5_SET(flow_table_context, ft_ctx, level, ft_attr->level);
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ struct mlx5hws_cmd_set_fte_attr {
struct mlx5hws_cmd_ft_create_attr {
	u8 type;
	u8 level;
	u16 uid;
	bool rtc_valid;
	bool decap_en;
	bool reformat_en;
Loading