147 lines
5.3 KiB
Diff
147 lines
5.3 KiB
Diff
From ecf0cb0c6c0e3b29c4e807a8b13feda75d404863 Mon Sep 17 00:00:00 2001
|
|
From: Kamal Heib <kheib@redhat.com>
|
|
Date: Fri, 17 Apr 2026 11:27:00 -0400
|
|
Subject: [PATCH] net/mlx5: HWS, fix simple rules rehash error flow
|
|
|
|
JIRA: https://redhat.atlassian.net/browse/RHEL-169055
|
|
|
|
commit 615b690612b7785ab8632f6a5a941550622e4e36
|
|
Author: Yevgeny Kliteynik <kliteyn@nvidia.com>
|
|
Date: Sun Aug 17 23:23:18 2025 +0300
|
|
|
|
net/mlx5: HWS, fix simple rules rehash error flow
|
|
|
|
Moving rules from matcher to matcher should not fail.
|
|
However, if it does fail due to various reasons, the error flow
|
|
should allow the kernel to continue functioning (albeit with broken
|
|
steering rules) instead of going into series of soft lock-ups or
|
|
some other problematic behaviour.
|
|
|
|
This patch fixes the error flow for moving simple rules:
|
|
- If new rule creation fails before it was even enqeued, do not
|
|
poll for completion
|
|
- If TIMEOUT happened while moving the rule, no point trying
|
|
to poll for completions for other rules. Something is broken,
|
|
completion won't come, just abort the rehash sequence.
|
|
- If some other completion with error received, don't give up.
|
|
Continue handling rest of the rules to minimize the damage.
|
|
- Make sure that the first error code that was received will
|
|
be actually returned to the caller instead of replacing it
|
|
with the generic error code.
|
|
|
|
All the aforementioned issues stem from the same bad error flow,
|
|
so no point fixing them one by one and leaving partially broken
|
|
code - fixing them in one patch.
|
|
|
|
Fixes: ef94799a8741 ("net/mlx5: HWS, rework rehash loop")
|
|
Signed-off-by: Yevgeny Kliteynik <kliteyn@nvidia.com>
|
|
Reviewed-by: Vlad Dogaru <vdogaru@nvidia.com>
|
|
Signed-off-by: Mark Bloch <mbloch@nvidia.com>
|
|
Link: https://patch.msgid.link/20250817202323.308604-3-mbloch@nvidia.com
|
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
|
|
Signed-off-by: Kamal Heib <kheib@redhat.com>
|
|
|
|
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c
|
|
index 92de4b761a83..0219a49b2326 100644
|
|
--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c
|
|
+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c
|
|
@@ -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;
|
|
@@ -99,11 +99,15 @@ 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)) {
|
|
- mlx5hws_err(ctx,
|
|
- "Moving BWC rule: move failed (%d), attempting to move rest of the rules\n",
|
|
- ret);
|
|
- move_error = true;
|
|
+ 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 = ret;
|
|
+ }
|
|
+ /* Rule wasn't queued, no need to poll */
|
|
+ continue;
|
|
}
|
|
|
|
pending_rules++;
|
|
@@ -111,11 +115,19 @@ hws_bwc_matcher_move_all_simple(struct mlx5hws_bwc_matcher *bwc_matcher)
|
|
rule_attr.queue_id,
|
|
&pending_rules,
|
|
false);
|
|
- if (unlikely(ret && !poll_error)) {
|
|
- mlx5hws_err(ctx,
|
|
- "Moving BWC rule: poll failed (%d), attempting to move rest of the rules\n",
|
|
- ret);
|
|
- poll_error = true;
|
|
+ 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: polling for completions failed (%d), attempting to move rest of the rules\n",
|
|
+ ret);
|
|
+ poll_error = ret;
|
|
+ }
|
|
}
|
|
}
|
|
|
|
@@ -126,17 +138,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)) {
|
|
- mlx5hws_err(ctx,
|
|
- "Moving BWC rule: drain failed (%d), attempting to move rest of the rules\n",
|
|
- ret);
|
|
- drain_error = true;
|
|
+ if (unlikely(ret)) {
|
|
+ if (ret == -ETIMEDOUT) {
|
|
+ mlx5hws_err(ctx,
|
|
+ "Moving bwc rule: timeout draining completions (%d), aborting rehash\n",
|
|
+ ret);
|
|
+ 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;
|
|
}
|
|
--
|
|
2.50.1 (Apple Git-155)
|
|
|