Skip to content

Commit 4f953be

Browse files
committed
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: Jakub Kicinski <kuba@kernel.org>
2 parents d9cef55 + d2d6f95 commit 4f953be

File tree

11 files changed

+112
-38
lines changed

11 files changed

+112
-38
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_hmfs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ static void mlx5_ct_fs_hmfs_fill_rule_actions(struct mlx5_ct_fs_hmfs *fs_hmfs,
173173

174174
memset(rule_actions, 0, NUM_CT_HMFS_RULES * sizeof(*rule_actions));
175175
rule_actions[0].action = mlx5_fc_get_hws_action(fs_hmfs->ctx, attr->counter);
176+
rule_actions[0].counter.offset =
177+
attr->counter->id - attr->counter->bulk->base_id;
176178
/* Modify header is special, it may require extra arguments outside the action itself. */
177179
if (mh_action->mh_data) {
178180
rule_actions[1].modify_header.offset = mh_action->mh_data->offset;

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,17 @@ static void hws_bwc_matcher_init_attr(struct mlx5hws_bwc_matcher *bwc_matcher,
7474
static int
7575
hws_bwc_matcher_move_all_simple(struct mlx5hws_bwc_matcher *bwc_matcher)
7676
{
77-
bool move_error = false, poll_error = false, drain_error = false;
7877
struct mlx5hws_context *ctx = bwc_matcher->matcher->tbl->ctx;
7978
struct mlx5hws_matcher *matcher = bwc_matcher->matcher;
79+
int drain_error = 0, move_error = 0, poll_error = 0;
8080
u16 bwc_queues = mlx5hws_bwc_queues(ctx);
8181
struct mlx5hws_rule_attr rule_attr;
8282
struct mlx5hws_bwc_rule *bwc_rule;
8383
struct mlx5hws_send_engine *queue;
8484
struct list_head *rules_list;
8585
u32 pending_rules;
8686
int i, ret = 0;
87+
bool drain;
8788

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

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

109114
pending_rules++;
115+
drain = pending_rules >=
116+
hws_bwc_get_burst_th(ctx, rule_attr.queue_id);
110117
ret = mlx5hws_bwc_queue_poll(ctx,
111118
rule_attr.queue_id,
112119
&pending_rules,
113-
false);
114-
if (unlikely(ret && !poll_error)) {
115-
mlx5hws_err(ctx,
116-
"Moving BWC rule: poll failed (%d), attempting to move rest of the rules\n",
117-
ret);
118-
poll_error = true;
120+
drain);
121+
if (unlikely(ret)) {
122+
if (ret == -ETIMEDOUT) {
123+
mlx5hws_err(ctx,
124+
"Moving BWC rule: timeout polling for completions (%d), aborting rehash\n",
125+
ret);
126+
return ret;
127+
}
128+
if (!poll_error) {
129+
mlx5hws_err(ctx,
130+
"Moving BWC rule: polling for completions failed (%d), attempting to move rest of the rules\n",
131+
ret);
132+
poll_error = ret;
133+
}
119134
}
120135
}
121136

@@ -126,17 +141,30 @@ hws_bwc_matcher_move_all_simple(struct mlx5hws_bwc_matcher *bwc_matcher)
126141
rule_attr.queue_id,
127142
&pending_rules,
128143
true);
129-
if (unlikely(ret && !drain_error)) {
130-
mlx5hws_err(ctx,
131-
"Moving BWC rule: drain failed (%d), attempting to move rest of the rules\n",
132-
ret);
133-
drain_error = true;
144+
if (unlikely(ret)) {
145+
if (ret == -ETIMEDOUT) {
146+
mlx5hws_err(ctx,
147+
"Moving bwc rule: timeout draining completions (%d), aborting rehash\n",
148+
ret);
149+
return ret;
150+
}
151+
if (!drain_error) {
152+
mlx5hws_err(ctx,
153+
"Moving bwc rule: drain failed (%d), attempting to move rest of the rules\n",
154+
ret);
155+
drain_error = ret;
156+
}
134157
}
135158
}
136159
}
137160

138-
if (move_error || poll_error || drain_error)
139-
ret = -EINVAL;
161+
/* Return the first error that happened */
162+
if (unlikely(move_error))
163+
return move_error;
164+
if (unlikely(poll_error))
165+
return poll_error;
166+
if (unlikely(drain_error))
167+
return drain_error;
140168

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

1066+
/* Rule insertion could fail due to queue being full, timeout, or
1067+
* matcher in resize. In such cases, no point in trying to rehash.
1068+
*/
1069+
if (ret == -EBUSY || ret == -ETIMEDOUT || ret == -EAGAIN) {
1070+
mutex_unlock(queue_lock);
1071+
mlx5hws_err(ctx,
1072+
"BWC rule insertion failed - %s (%d)\n",
1073+
ret == -EBUSY ? "queue is full" :
1074+
ret == -ETIMEDOUT ? "timeout" :
1075+
ret == -EAGAIN ? "matcher in resize" : "N/A",
1076+
ret);
1077+
hws_bwc_rule_cnt_dec(bwc_rule);
1078+
return ret;
1079+
}
1080+
10381081
/* At this point the rule wasn't added.
10391082
* It could be because there was collision, or some other problem.
10401083
* Try rehash by size and insert rule again - last chance.

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc_complex.c

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,11 +1328,11 @@ mlx5hws_bwc_matcher_move_all_complex(struct mlx5hws_bwc_matcher *bwc_matcher)
13281328
{
13291329
struct mlx5hws_context *ctx = bwc_matcher->matcher->tbl->ctx;
13301330
struct mlx5hws_matcher *matcher = bwc_matcher->matcher;
1331-
bool move_error = false, poll_error = false;
13321331
u16 bwc_queues = mlx5hws_bwc_queues(ctx);
13331332
struct mlx5hws_bwc_rule *tmp_bwc_rule;
13341333
struct mlx5hws_rule_attr rule_attr;
13351334
struct mlx5hws_table *isolated_tbl;
1335+
int move_error = 0, poll_error = 0;
13361336
struct mlx5hws_rule *tmp_rule;
13371337
struct list_head *rules_list;
13381338
u32 expected_completions = 1;
@@ -1391,23 +1391,35 @@ mlx5hws_bwc_matcher_move_all_complex(struct mlx5hws_bwc_matcher *bwc_matcher)
13911391
ret = mlx5hws_matcher_resize_rule_move(matcher,
13921392
tmp_rule,
13931393
&rule_attr);
1394-
if (unlikely(ret && !move_error)) {
1395-
mlx5hws_err(ctx,
1396-
"Moving complex BWC rule failed (%d), attempting to move rest of the rules\n",
1397-
ret);
1398-
move_error = true;
1394+
if (unlikely(ret)) {
1395+
if (!move_error) {
1396+
mlx5hws_err(ctx,
1397+
"Moving complex BWC rule: move failed (%d), attempting to move rest of the rules\n",
1398+
ret);
1399+
move_error = ret;
1400+
}
1401+
/* Rule wasn't queued, no need to poll */
1402+
continue;
13991403
}
14001404

14011405
expected_completions = 1;
14021406
ret = mlx5hws_bwc_queue_poll(ctx,
14031407
rule_attr.queue_id,
14041408
&expected_completions,
14051409
true);
1406-
if (unlikely(ret && !poll_error)) {
1407-
mlx5hws_err(ctx,
1408-
"Moving complex BWC rule: poll failed (%d), attempting to move rest of the rules\n",
1409-
ret);
1410-
poll_error = true;
1410+
if (unlikely(ret)) {
1411+
if (ret == -ETIMEDOUT) {
1412+
mlx5hws_err(ctx,
1413+
"Moving complex BWC rule: timeout polling for completions (%d), aborting rehash\n",
1414+
ret);
1415+
return ret;
1416+
}
1417+
if (!poll_error) {
1418+
mlx5hws_err(ctx,
1419+
"Moving complex BWC rule: polling for completions failed (%d), attempting to move rest of the rules\n",
1420+
ret);
1421+
poll_error = ret;
1422+
}
14111423
}
14121424

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

1425-
if (move_error || poll_error)
1426-
ret = -EINVAL;
1437+
/* Return the first error that happened */
1438+
if (unlikely(move_error))
1439+
return move_error;
1440+
if (unlikely(poll_error))
1441+
return poll_error;
14271442

14281443
return ret;
14291444
}

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/cmd.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ int mlx5hws_cmd_flow_table_create(struct mlx5_core_dev *mdev,
5555

5656
MLX5_SET(create_flow_table_in, in, opcode, MLX5_CMD_OP_CREATE_FLOW_TABLE);
5757
MLX5_SET(create_flow_table_in, in, table_type, ft_attr->type);
58+
MLX5_SET(create_flow_table_in, in, uid, ft_attr->uid);
5859

5960
ft_ctx = MLX5_ADDR_OF(create_flow_table_in, in, flow_table_context);
6061
MLX5_SET(flow_table_context, ft_ctx, level, ft_attr->level);

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/cmd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ struct mlx5hws_cmd_set_fte_attr {
3636
struct mlx5hws_cmd_ft_create_attr {
3737
u8 type;
3838
u8 level;
39+
u16 uid;
3940
bool rtc_valid;
4041
bool decap_en;
4142
bool reformat_en;

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ static int mlx5_cmd_hws_create_flow_table(struct mlx5_flow_root_namespace *ns,
267267

268268
tbl_attr.type = MLX5HWS_TABLE_TYPE_FDB;
269269
tbl_attr.level = ft_attr->level;
270+
tbl_attr.uid = ft_attr->uid;
270271
tbl = mlx5hws_table_create(ctx, &tbl_attr);
271272
if (!tbl) {
272273
mlx5_core_err(ns->dev, "Failed creating hws flow_table\n");

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ static int hws_matcher_create_end_ft_isolated(struct mlx5hws_matcher *matcher)
8585

8686
ret = mlx5hws_table_create_default_ft(tbl->ctx->mdev,
8787
tbl,
88+
0,
8889
&matcher->end_ft_id);
8990
if (ret) {
9091
mlx5hws_err(tbl->ctx, "Isolated matcher: failed to create end flow table\n");
@@ -112,7 +113,9 @@ static int hws_matcher_create_end_ft(struct mlx5hws_matcher *matcher)
112113
if (mlx5hws_matcher_is_isolated(matcher))
113114
ret = hws_matcher_create_end_ft_isolated(matcher);
114115
else
115-
ret = mlx5hws_table_create_default_ft(tbl->ctx->mdev, tbl,
116+
ret = mlx5hws_table_create_default_ft(tbl->ctx->mdev,
117+
tbl,
118+
0,
116119
&matcher->end_ft_id);
117120

118121
if (ret) {

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/mlx5hws.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ struct mlx5hws_context_attr {
7575
struct mlx5hws_table_attr {
7676
enum mlx5hws_table_type type;
7777
u32 level;
78+
u16 uid;
7879
};
7980

8081
enum mlx5hws_matcher_flow_src {

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,6 @@ static int hws_send_ring_open_cq(struct mlx5_core_dev *mdev,
964964
return -ENOMEM;
965965

966966
MLX5_SET(cqc, cqc_data, uar_page, mdev->priv.uar->index);
967-
MLX5_SET(cqc, cqc_data, cqe_sz, queue->num_entries);
968967
MLX5_SET(cqc, cqc_data, log_cq_size, ilog2(queue->num_entries));
969968

970969
err = hws_send_ring_alloc_cq(mdev, numa_node, queue, cqc_data, cq);

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,17 @@ u32 mlx5hws_table_get_id(struct mlx5hws_table *tbl)
99
}
1010

1111
static void hws_table_init_next_ft_attr(struct mlx5hws_table *tbl,
12+
u16 uid,
1213
struct mlx5hws_cmd_ft_create_attr *ft_attr)
1314
{
1415
ft_attr->type = tbl->fw_ft_type;
1516
if (tbl->type == MLX5HWS_TABLE_TYPE_FDB)
1617
ft_attr->level = tbl->ctx->caps->fdb_ft.max_level - 1;
1718
else
1819
ft_attr->level = tbl->ctx->caps->nic_ft.max_level - 1;
20+
1921
ft_attr->rtc_valid = true;
22+
ft_attr->uid = uid;
2023
}
2124

2225
static void hws_table_set_cap_attr(struct mlx5hws_table *tbl,
@@ -119,12 +122,12 @@ static int hws_table_connect_to_default_miss_tbl(struct mlx5hws_table *tbl, u32
119122

120123
int mlx5hws_table_create_default_ft(struct mlx5_core_dev *mdev,
121124
struct mlx5hws_table *tbl,
122-
u32 *ft_id)
125+
u16 uid, u32 *ft_id)
123126
{
124127
struct mlx5hws_cmd_ft_create_attr ft_attr = {0};
125128
int ret;
126129

127-
hws_table_init_next_ft_attr(tbl, &ft_attr);
130+
hws_table_init_next_ft_attr(tbl, uid, &ft_attr);
128131
hws_table_set_cap_attr(tbl, &ft_attr);
129132

130133
ret = mlx5hws_cmd_flow_table_create(mdev, &ft_attr, ft_id);
@@ -189,7 +192,10 @@ static int hws_table_init(struct mlx5hws_table *tbl)
189192
}
190193

191194
mutex_lock(&ctx->ctrl_lock);
192-
ret = mlx5hws_table_create_default_ft(tbl->ctx->mdev, tbl, &tbl->ft_id);
195+
ret = mlx5hws_table_create_default_ft(tbl->ctx->mdev,
196+
tbl,
197+
tbl->uid,
198+
&tbl->ft_id);
193199
if (ret) {
194200
mlx5hws_err(tbl->ctx, "Failed to create flow table object\n");
195201
mutex_unlock(&ctx->ctrl_lock);
@@ -239,6 +245,7 @@ struct mlx5hws_table *mlx5hws_table_create(struct mlx5hws_context *ctx,
239245
tbl->ctx = ctx;
240246
tbl->type = attr->type;
241247
tbl->level = attr->level;
248+
tbl->uid = attr->uid;
242249

243250
ret = hws_table_init(tbl);
244251
if (ret) {

0 commit comments

Comments
 (0)