Skip to content

Commit 8300f22

Browse files
roidayanSaeed Mahameed
authored andcommitted
net/mlx5e: Create new flow attr for multi table actions
Some TC actions use post actions for their implementation. For example CT and sample actions. Create a new flow attr after each multi table action and create a post action rule for it. First flow attr being offloaded normally and linked to the next attr (post action rule) with setting an id on reg_c. Post action rules match the id on reg_c and continue to the next one. The flow counter is allocated on the last rule. Signed-off-by: Roi Dayan <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 314e110 commit 8300f22

File tree

9 files changed

+483
-67
lines changed

9 files changed

+483
-67
lines changed

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

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
33

44
#include "act.h"
5+
#include "en/tc/post_act.h"
56
#include "en/tc_priv.h"
67
#include "mlx5_core.h"
78

@@ -101,3 +102,75 @@ mlx5e_tc_act_init_parse_state(struct mlx5e_tc_act_parse_state *parse_state,
101102
parse_state->num_actions = flow_action->num_entries;
102103
parse_state->extack = extack;
103104
}
105+
106+
void
107+
mlx5e_tc_act_reorder_flow_actions(struct flow_action *flow_action,
108+
struct mlx5e_tc_flow_action *flow_action_reorder)
109+
{
110+
struct flow_action_entry *act;
111+
int i, j = 0;
112+
113+
flow_action_for_each(i, act, flow_action) {
114+
/* Add CT action to be first. */
115+
if (act->id == FLOW_ACTION_CT)
116+
flow_action_reorder->entries[j++] = act;
117+
}
118+
119+
flow_action_for_each(i, act, flow_action) {
120+
if (act->id == FLOW_ACTION_CT)
121+
continue;
122+
flow_action_reorder->entries[j++] = act;
123+
}
124+
}
125+
126+
int
127+
mlx5e_tc_act_post_parse(struct mlx5e_tc_act_parse_state *parse_state,
128+
struct flow_action *flow_action,
129+
struct mlx5_flow_attr *attr,
130+
enum mlx5_flow_namespace_type ns_type)
131+
{
132+
struct flow_action_entry *act;
133+
struct mlx5e_tc_act *tc_act;
134+
struct mlx5e_priv *priv;
135+
int err = 0, i;
136+
137+
priv = parse_state->flow->priv;
138+
139+
flow_action_for_each(i, act, flow_action) {
140+
tc_act = mlx5e_tc_act_get(act->id, ns_type);
141+
if (!tc_act || !tc_act->post_parse ||
142+
!tc_act->can_offload(parse_state, act, i, attr))
143+
continue;
144+
145+
err = tc_act->post_parse(parse_state, priv, attr);
146+
if (err)
147+
goto out;
148+
}
149+
150+
out:
151+
return err;
152+
}
153+
154+
int
155+
mlx5e_tc_act_set_next_post_act(struct mlx5e_tc_flow *flow,
156+
struct mlx5_flow_attr *attr,
157+
struct mlx5_flow_attr *next_attr)
158+
{
159+
struct mlx5_core_dev *mdev = flow->priv->mdev;
160+
struct mlx5e_tc_mod_hdr_acts *mod_acts;
161+
int err;
162+
163+
mod_acts = &attr->parse_attr->mod_hdr_acts;
164+
165+
/* Set handle on current post act rule to next post act rule. */
166+
err = mlx5e_tc_post_act_set_handle(mdev, next_attr->post_act_handle, mod_acts);
167+
if (err) {
168+
mlx5_core_warn(mdev, "Failed setting post action handle");
169+
return err;
170+
}
171+
172+
attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
173+
MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
174+
175+
return 0;
176+
}

drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ struct mlx5e_tc_act {
4242
int (*post_parse)(struct mlx5e_tc_act_parse_state *parse_state,
4343
struct mlx5e_priv *priv,
4444
struct mlx5_flow_attr *attr);
45+
46+
bool (*is_multi_table_act)(struct mlx5e_priv *priv,
47+
const struct flow_action_entry *act,
48+
struct mlx5_flow_attr *attr);
49+
};
50+
51+
struct mlx5e_tc_flow_action {
52+
unsigned int num_entries;
53+
struct flow_action_entry **entries;
4554
};
4655

4756
extern struct mlx5e_tc_act mlx5e_tc_act_drop;
@@ -74,4 +83,19 @@ mlx5e_tc_act_init_parse_state(struct mlx5e_tc_act_parse_state *parse_state,
7483
struct flow_action *flow_action,
7584
struct netlink_ext_ack *extack);
7685

86+
void
87+
mlx5e_tc_act_reorder_flow_actions(struct flow_action *flow_action,
88+
struct mlx5e_tc_flow_action *flow_action_reorder);
89+
90+
int
91+
mlx5e_tc_act_post_parse(struct mlx5e_tc_act_parse_state *parse_state,
92+
struct flow_action *flow_action,
93+
struct mlx5_flow_attr *attr,
94+
enum mlx5_flow_namespace_type ns_type);
95+
96+
int
97+
mlx5e_tc_act_set_next_post_act(struct mlx5e_tc_flow *flow,
98+
struct mlx5_flow_attr *attr,
99+
struct mlx5_flow_attr *next_attr);
100+
77101
#endif /* __MLX5_EN_TC_ACT_H__ */

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,9 @@ mlx5e_tc_post_act_add(struct mlx5e_post_act *post_act, struct mlx5_flow_attr *at
140140
goto err_xarray;
141141

142142
handle->attr = post_attr;
143-
err = mlx5e_tc_post_act_offload(post_act, handle);
144-
if (err)
145-
goto err_rule;
146-
147143

148144
return handle;
149145

150-
err_rule:
151-
xa_erase(&post_act->ids, handle->id);
152146
err_xarray:
153147
kfree(post_attr);
154148
kfree(handle);

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,9 @@ mlx5e_tc_sample_offload(struct mlx5e_tc_psample *tc_psample,
533533
err = PTR_ERR(post_act_handle);
534534
goto err_post_act;
535535
}
536+
err = mlx5e_tc_post_act_offload(tc_psample->post_act, post_act_handle);
537+
if (err)
538+
goto err_post_rule;
536539
sample_flow->post_act_handle = post_act_handle;
537540
} else {
538541
err = add_post_rule(esw, sample_flow, spec, attr, &default_tbl_id);

drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1823,6 +1823,9 @@ __mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *ct_priv,
18231823
ct_dbg("Failed to allocate post action handle");
18241824
goto err_post_act_handle;
18251825
}
1826+
err = mlx5e_tc_post_act_offload(ct_priv->post_act, handle);
1827+
if (err)
1828+
goto err_alloc_pre;
18261829
ct_flow->post_act_handle = handle;
18271830

18281831
/* Base flow attributes of both rules on original rule attribute */

drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ struct mlx5e_tc_flow {
109109
struct completion init_done;
110110
struct completion del_hw_done;
111111
struct mlx5_flow_attr *attr;
112+
struct list_head attrs;
112113
};
113114

114115
struct mlx5_flow_handle *
@@ -129,6 +130,12 @@ mlx5e_tc_offload_fdb_rules(struct mlx5_eswitch *esw,
129130
struct mlx5_flow_spec *spec,
130131
struct mlx5_flow_attr *attr);
131132

133+
struct mlx5_flow_attr *
134+
mlx5e_tc_get_encap_attr(struct mlx5e_tc_flow *flow);
135+
136+
void mlx5e_tc_unoffload_flow_post_acts(struct mlx5e_tc_flow *flow);
137+
int mlx5e_tc_offload_flow_post_acts(struct mlx5e_tc_flow *flow);
138+
132139
bool mlx5e_is_eswitch_flow(struct mlx5e_tc_flow *flow);
133140
bool mlx5e_is_ft_flow(struct mlx5e_tc_flow *flow);
134141
bool mlx5e_is_offloaded_flow(struct mlx5e_tc_flow *flow);

drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -173,19 +173,29 @@ void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv,
173173
list_for_each_entry(flow, flow_list, tmp_list) {
174174
if (!mlx5e_is_offloaded_flow(flow) || !flow_flag_test(flow, SLOW))
175175
continue;
176-
attr = flow->attr;
177-
esw_attr = attr->esw_attr;
178-
spec = &attr->parse_attr->spec;
179176

177+
spec = &flow->attr->parse_attr->spec;
178+
179+
attr = mlx5e_tc_get_encap_attr(flow);
180+
esw_attr = attr->esw_attr;
180181
esw_attr->dests[flow->tmp_entry_index].pkt_reformat = e->pkt_reformat;
181182
esw_attr->dests[flow->tmp_entry_index].flags |= MLX5_ESW_DEST_ENCAP_VALID;
182183

183184
/* Do not offload flows with unresolved neighbors */
184185
if (!mlx5e_tc_flow_all_encaps_valid(esw_attr))
185186
continue;
187+
188+
err = mlx5e_tc_offload_flow_post_acts(flow);
189+
if (err) {
190+
mlx5_core_warn(priv->mdev, "Failed to update flow post acts, %d\n",
191+
err);
192+
continue;
193+
}
194+
186195
/* update from slow path rule to encap rule */
187-
rule = mlx5e_tc_offload_fdb_rules(esw, flow, spec, attr);
196+
rule = mlx5e_tc_offload_fdb_rules(esw, flow, spec, flow->attr);
188197
if (IS_ERR(rule)) {
198+
mlx5e_tc_unoffload_flow_post_acts(flow);
189199
err = PTR_ERR(rule);
190200
mlx5_core_warn(priv->mdev, "Failed to update cached encapsulation flow, %d\n",
191201
err);
@@ -214,12 +224,13 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
214224
list_for_each_entry(flow, flow_list, tmp_list) {
215225
if (!mlx5e_is_offloaded_flow(flow) || flow_flag_test(flow, SLOW))
216226
continue;
217-
attr = flow->attr;
218-
esw_attr = attr->esw_attr;
219-
spec = &attr->parse_attr->spec;
227+
spec = &flow->attr->parse_attr->spec;
220228

221229
/* update from encap rule to slow path rule */
222230
rule = mlx5e_tc_offload_to_slow_path(esw, flow, spec);
231+
232+
attr = mlx5e_tc_get_encap_attr(flow);
233+
esw_attr = attr->esw_attr;
223234
/* mark the flow's encap dest as non-valid */
224235
esw_attr->dests[flow->tmp_entry_index].flags &= ~MLX5_ESW_DEST_ENCAP_VALID;
225236

@@ -230,7 +241,8 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
230241
continue;
231242
}
232243

233-
mlx5e_tc_unoffload_fdb_rules(esw, flow, attr);
244+
mlx5e_tc_unoffload_fdb_rules(esw, flow, flow->attr);
245+
mlx5e_tc_unoffload_flow_post_acts(flow);
234246
flow->rule[0] = rule;
235247
/* was unset when fast path rule removed */
236248
flow_flag_set(flow, OFFLOADED);
@@ -495,6 +507,9 @@ void mlx5e_detach_encap(struct mlx5e_priv *priv,
495507
struct mlx5e_encap_entry *e = flow->encaps[out_index].e;
496508
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
497509

510+
if (!mlx5e_is_eswitch_flow(flow))
511+
return;
512+
498513
if (attr->esw_attr->dests[out_index].flags &
499514
MLX5_ESW_DEST_CHAIN_WITH_SRC_PORT_CHANGE)
500515
mlx5e_detach_encap_route(priv, flow, out_index);
@@ -1360,17 +1375,19 @@ static void mlx5e_reoffload_encap(struct mlx5e_priv *priv,
13601375

13611376
list_for_each_entry(flow, encap_flows, tmp_list) {
13621377
struct mlx5e_tc_flow_parse_attr *parse_attr;
1363-
struct mlx5_flow_attr *attr = flow->attr;
13641378
struct mlx5_esw_flow_attr *esw_attr;
13651379
struct mlx5_flow_handle *rule;
1380+
struct mlx5_flow_attr *attr;
13661381
struct mlx5_flow_spec *spec;
13671382

13681383
if (flow_flag_test(flow, FAILED))
13691384
continue;
13701385

1386+
spec = &flow->attr->parse_attr->spec;
1387+
1388+
attr = mlx5e_tc_get_encap_attr(flow);
13711389
esw_attr = attr->esw_attr;
13721390
parse_attr = attr->parse_attr;
1373-
spec = &parse_attr->spec;
13741391

13751392
err = mlx5e_update_vf_tunnel(esw, esw_attr, &parse_attr->mod_hdr_acts,
13761393
e->out_dev, e->route_dev_ifindex,
@@ -1392,9 +1409,18 @@ static void mlx5e_reoffload_encap(struct mlx5e_priv *priv,
13921409
esw_attr->dests[flow->tmp_entry_index].flags |= MLX5_ESW_DEST_ENCAP_VALID;
13931410
if (!mlx5e_tc_flow_all_encaps_valid(esw_attr))
13941411
goto offload_to_slow_path;
1412+
1413+
err = mlx5e_tc_offload_flow_post_acts(flow);
1414+
if (err) {
1415+
mlx5_core_warn(priv->mdev, "Failed to update flow post acts, %d\n",
1416+
err);
1417+
goto offload_to_slow_path;
1418+
}
1419+
13951420
/* update from slow path rule to encap rule */
1396-
rule = mlx5e_tc_offload_fdb_rules(esw, flow, spec, attr);
1421+
rule = mlx5e_tc_offload_fdb_rules(esw, flow, spec, flow->attr);
13971422
if (IS_ERR(rule)) {
1423+
mlx5e_tc_unoffload_flow_post_acts(flow);
13981424
err = PTR_ERR(rule);
13991425
mlx5_core_warn(priv->mdev, "Failed to update cached encapsulation flow, %d\n",
14001426
err);

0 commit comments

Comments
 (0)