Skip to content

Commit 08fe94e

Browse files
Paul BlakeySaeed Mahameed
authored andcommitted
net/mlx5e: TC, Remove special handling of CT action
CT action has special treating as a per-flow action since it was assumed to be singular and reordered to be first on the action list. This isn't the case anymore, and can be converted to just a FWD to pre_ct + MODIFY_HEAD, and handled per post_act rule. Remove special handling of CT action, and offload it while post parsing each ct attribute. Signed-off-by: Paul Blakey <[email protected]> Reviewed-by: Roi Dayan <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 67efaf4 commit 08fe94e

File tree

5 files changed

+58
-213
lines changed

5 files changed

+58
-213
lines changed

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ struct mlx5e_tc_act_parse_state {
1818
struct netlink_ext_ack *extack;
1919
u32 actions;
2020
bool ct;
21-
bool ct_clear;
2221
bool encap;
2322
bool decap;
2423
bool mpls_push;

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

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -28,30 +28,16 @@ tc_act_parse_ct(struct mlx5e_tc_act_parse_state *parse_state,
2828
struct mlx5e_priv *priv,
2929
struct mlx5_flow_attr *attr)
3030
{
31-
bool clear_action = act->ct.action & TCA_CT_ACT_CLEAR;
3231
int err;
3332

34-
/* It's redundant to do ct clear more than once. */
35-
if (clear_action && parse_state->ct_clear)
36-
return 0;
37-
38-
err = mlx5_tc_ct_parse_action(parse_state->ct_priv, attr,
39-
&attr->parse_attr->mod_hdr_acts,
40-
act, parse_state->extack);
33+
err = mlx5_tc_ct_parse_action(parse_state->ct_priv, attr, act, parse_state->extack);
4134
if (err)
4235
return err;
4336

44-
4537
if (mlx5e_is_eswitch_flow(parse_state->flow))
4638
attr->esw_attr->split_count = attr->esw_attr->out_count;
4739

48-
if (clear_action) {
49-
parse_state->ct_clear = true;
50-
} else {
51-
attr->flags |= MLX5_ATTR_FLAG_CT;
52-
flow_flag_set(parse_state->flow, CT);
53-
parse_state->ct = true;
54-
}
40+
attr->flags |= MLX5_ATTR_FLAG_CT;
5541

5642
return 0;
5743
}
@@ -61,27 +47,10 @@ tc_act_post_parse_ct(struct mlx5e_tc_act_parse_state *parse_state,
6147
struct mlx5e_priv *priv,
6248
struct mlx5_flow_attr *attr)
6349
{
64-
struct mlx5e_tc_mod_hdr_acts *mod_acts = &attr->parse_attr->mod_hdr_acts;
65-
int err;
66-
67-
/* If ct action exist, we can ignore previous ct_clear actions */
68-
if (parse_state->ct)
50+
if (!(attr->flags & MLX5_ATTR_FLAG_CT))
6951
return 0;
7052

71-
if (parse_state->ct_clear) {
72-
err = mlx5_tc_ct_set_ct_clear_regs(parse_state->ct_priv, mod_acts);
73-
if (err) {
74-
NL_SET_ERR_MSG_MOD(parse_state->extack,
75-
"Failed to set registers for ct clear");
76-
return err;
77-
}
78-
attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
79-
80-
/* Prevent handling of additional, redundant clear actions */
81-
parse_state->ct_clear = false;
82-
}
83-
84-
return 0;
53+
return mlx5_tc_ct_flow_offload(parse_state->ct_priv, attr);
8554
}
8655

8756
static bool

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

Lines changed: 41 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,6 @@ struct mlx5_tc_ct_priv {
8383
struct mlx5_tc_ct_debugfs debugfs;
8484
};
8585

86-
struct mlx5_ct_flow {
87-
struct mlx5_flow_attr *pre_ct_attr;
88-
struct mlx5_flow_handle *pre_ct_rule;
89-
struct mlx5_ct_ft *ft;
90-
};
91-
9286
struct mlx5_ct_zone_rule {
9387
struct mlx5_ct_fs_rule *rule;
9488
struct mlx5e_mod_hdr_handle *mh;
@@ -598,12 +592,6 @@ mlx5_tc_ct_entry_set_registers(struct mlx5_tc_ct_priv *ct_priv,
598592
return 0;
599593
}
600594

601-
int mlx5_tc_ct_set_ct_clear_regs(struct mlx5_tc_ct_priv *priv,
602-
struct mlx5e_tc_mod_hdr_acts *mod_acts)
603-
{
604-
return mlx5_tc_ct_entry_set_registers(priv, mod_acts, 0, 0, 0, 0);
605-
}
606-
607595
static int
608596
mlx5_tc_ct_parse_mangle_to_mod_act(struct flow_action_entry *act,
609597
char *modact)
@@ -1545,7 +1533,6 @@ mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv,
15451533
int
15461534
mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
15471535
struct mlx5_flow_attr *attr,
1548-
struct mlx5e_tc_mod_hdr_acts *mod_acts,
15491536
const struct flow_action_entry *act,
15501537
struct netlink_ext_ack *extack)
15511538
{
@@ -1555,8 +1542,8 @@ mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
15551542
return -EOPNOTSUPP;
15561543
}
15571544

1545+
attr->ct_attr.ct_action |= act->ct.action; /* So we can have clear + ct */
15581546
attr->ct_attr.zone = act->ct.zone;
1559-
attr->ct_attr.ct_action = act->ct.action;
15601547
attr->ct_attr.nf_ft = act->ct.flow_table;
15611548
attr->ct_attr.act_miss_cookie = act->miss_cookie;
15621549

@@ -1892,14 +1879,14 @@ mlx5_tc_ct_del_ft_cb(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_ft *ft)
18921879

18931880
/* We translate the tc filter with CT action to the following HW model:
18941881
*
1895-
* +---------------------+
1896-
* + ft prio (tc chain) +
1897-
* + original match +
1898-
* +---------------------+
1882+
* +-----------------------+
1883+
* + rule (either original +
1884+
* + or post_act rule) +
1885+
* +-----------------------+
18991886
* | set act_miss_cookie mapping
19001887
* | set fte_id
19011888
* | set tunnel_id
1902-
* | do decap
1889+
* | rest of actions before the CT action (for this orig/post_act rule)
19031890
* |
19041891
* +-------------+
19051892
* | Chain 0 |
@@ -1924,32 +1911,21 @@ mlx5_tc_ct_del_ft_cb(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_ft *ft)
19241911
* | do nat (if needed)
19251912
* v
19261913
* +--------------+
1927-
* + post_act + original filter actions
1914+
* + post_act + rest of parsed filter's actions
19281915
* + fte_id match +------------------------>
19291916
* +--------------+
19301917
*
19311918
*/
1932-
static struct mlx5_flow_handle *
1919+
static int
19331920
__mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *ct_priv,
1934-
struct mlx5_flow_spec *orig_spec,
19351921
struct mlx5_flow_attr *attr)
19361922
{
19371923
bool nat = attr->ct_attr.ct_action & TCA_CT_ACT_NAT;
19381924
struct mlx5e_priv *priv = netdev_priv(ct_priv->netdev);
1939-
struct mlx5e_tc_mod_hdr_acts *pre_mod_acts;
1940-
u32 attr_sz = ns_to_attr_sz(ct_priv->ns_type);
1941-
struct mlx5_flow_attr *pre_ct_attr;
1942-
struct mlx5_modify_hdr *mod_hdr;
1943-
struct mlx5_ct_flow *ct_flow;
19441925
int act_miss_mapping = 0, err;
19451926
struct mlx5_ct_ft *ft;
19461927
u16 zone;
19471928

1948-
ct_flow = kzalloc(sizeof(*ct_flow), GFP_KERNEL);
1949-
if (!ct_flow) {
1950-
return ERR_PTR(-ENOMEM);
1951-
}
1952-
19531929
/* Register for CT established events */
19541930
ft = mlx5_tc_ct_add_ft_cb(ct_priv, attr->ct_attr.zone,
19551931
attr->ct_attr.nf_ft);
@@ -1958,160 +1934,97 @@ __mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *ct_priv,
19581934
ct_dbg("Failed to register to ft callback");
19591935
goto err_ft;
19601936
}
1961-
ct_flow->ft = ft;
1962-
1963-
/* Base flow attributes of both rules on original rule attribute */
1964-
ct_flow->pre_ct_attr = mlx5_alloc_flow_attr(ct_priv->ns_type);
1965-
if (!ct_flow->pre_ct_attr) {
1966-
err = -ENOMEM;
1967-
goto err_alloc_pre;
1968-
}
1969-
1970-
pre_ct_attr = ct_flow->pre_ct_attr;
1971-
memcpy(pre_ct_attr, attr, attr_sz);
1972-
pre_mod_acts = &pre_ct_attr->parse_attr->mod_hdr_acts;
1973-
1974-
/* Modify the original rule's action to fwd and modify, leave decap */
1975-
pre_ct_attr->action = attr->action & MLX5_FLOW_CONTEXT_ACTION_DECAP;
1976-
pre_ct_attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
1977-
MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
1937+
attr->ct_attr.ft = ft;
19781938

19791939
err = mlx5e_tc_action_miss_mapping_get(ct_priv->priv, attr, attr->ct_attr.act_miss_cookie,
19801940
&act_miss_mapping);
19811941
if (err) {
19821942
ct_dbg("Failed to get register mapping for act miss");
19831943
goto err_get_act_miss;
19841944
}
1985-
attr->ct_attr.act_miss_mapping = act_miss_mapping;
19861945

1987-
err = mlx5e_tc_match_to_reg_set(priv->mdev, pre_mod_acts, ct_priv->ns_type,
1988-
MAPPED_OBJ_TO_REG, act_miss_mapping);
1946+
err = mlx5e_tc_match_to_reg_set(priv->mdev, &attr->parse_attr->mod_hdr_acts,
1947+
ct_priv->ns_type, MAPPED_OBJ_TO_REG, act_miss_mapping);
19891948
if (err) {
19901949
ct_dbg("Failed to set act miss register mapping");
19911950
goto err_mapping;
19921951
}
19931952

1994-
/* If original flow is decap, we do it before going into ct table
1995-
* so add a rewrite for the tunnel match_id.
1996-
*/
1997-
if ((pre_ct_attr->action & MLX5_FLOW_CONTEXT_ACTION_DECAP) &&
1998-
attr->chain == 0) {
1999-
err = mlx5e_tc_match_to_reg_set(priv->mdev, pre_mod_acts,
2000-
ct_priv->ns_type,
2001-
TUNNEL_TO_REG,
2002-
attr->tunnel_id);
2003-
if (err) {
2004-
ct_dbg("Failed to set tunnel register mapping");
2005-
goto err_mapping;
2006-
}
2007-
}
2008-
2009-
/* Change original rule point to ct table
2010-
* Chain 0 sets the zone and jumps to ct table
1953+
/* Chain 0 sets the zone and jumps to ct table
20111954
* Other chains jump to pre_ct table to align with act_ct cached logic
20121955
*/
2013-
pre_ct_attr->dest_chain = 0;
20141956
if (!attr->chain) {
20151957
zone = ft->zone & MLX5_CT_ZONE_MASK;
2016-
err = mlx5e_tc_match_to_reg_set(priv->mdev, pre_mod_acts, ct_priv->ns_type,
2017-
ZONE_TO_REG, zone);
1958+
err = mlx5e_tc_match_to_reg_set(priv->mdev, &attr->parse_attr->mod_hdr_acts,
1959+
ct_priv->ns_type, ZONE_TO_REG, zone);
20181960
if (err) {
20191961
ct_dbg("Failed to set zone register mapping");
20201962
goto err_mapping;
20211963
}
20221964

2023-
pre_ct_attr->dest_ft = nat ? ct_priv->ct_nat : ct_priv->ct;
1965+
attr->dest_ft = nat ? ct_priv->ct_nat : ct_priv->ct;
20241966
} else {
2025-
pre_ct_attr->dest_ft = nat ? ft->pre_ct_nat.ft : ft->pre_ct.ft;
2026-
}
2027-
2028-
mod_hdr = mlx5_modify_header_alloc(priv->mdev, ct_priv->ns_type,
2029-
pre_mod_acts->num_actions,
2030-
pre_mod_acts->actions);
2031-
if (IS_ERR(mod_hdr)) {
2032-
err = PTR_ERR(mod_hdr);
2033-
ct_dbg("Failed to create pre ct mod hdr");
2034-
goto err_mapping;
2035-
}
2036-
pre_ct_attr->modify_hdr = mod_hdr;
2037-
ct_flow->pre_ct_rule = mlx5_tc_rule_insert(priv, orig_spec,
2038-
pre_ct_attr);
2039-
if (IS_ERR(ct_flow->pre_ct_rule)) {
2040-
err = PTR_ERR(ct_flow->pre_ct_rule);
2041-
ct_dbg("Failed to add pre ct rule");
2042-
goto err_insert_orig;
1967+
attr->dest_ft = nat ? ft->pre_ct_nat.ft : ft->pre_ct.ft;
20431968
}
20441969

2045-
attr->ct_attr.ct_flow = ct_flow;
2046-
mlx5e_mod_hdr_dealloc(pre_mod_acts);
1970+
attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
1971+
attr->ct_attr.act_miss_mapping = act_miss_mapping;
20471972

2048-
return ct_flow->pre_ct_rule;
1973+
return 0;
20491974

2050-
err_insert_orig:
2051-
mlx5_modify_header_dealloc(priv->mdev, pre_ct_attr->modify_hdr);
20521975
err_mapping:
2053-
mlx5e_mod_hdr_dealloc(pre_mod_acts);
20541976
mlx5e_tc_action_miss_mapping_put(ct_priv->priv, attr, act_miss_mapping);
20551977
err_get_act_miss:
2056-
kfree(ct_flow->pre_ct_attr);
2057-
err_alloc_pre:
20581978
mlx5_tc_ct_del_ft_cb(ct_priv, ft);
20591979
err_ft:
2060-
kfree(ct_flow);
20611980
netdev_warn(priv->netdev, "Failed to offload ct flow, err %d\n", err);
2062-
return ERR_PTR(err);
1981+
return err;
20631982
}
20641983

2065-
struct mlx5_flow_handle *
2066-
mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *priv,
2067-
struct mlx5_flow_spec *spec,
2068-
struct mlx5_flow_attr *attr,
2069-
struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts)
1984+
int
1985+
mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *priv, struct mlx5_flow_attr *attr)
20701986
{
2071-
struct mlx5_flow_handle *rule;
1987+
int err;
20721988

20731989
if (!priv)
2074-
return ERR_PTR(-EOPNOTSUPP);
1990+
return -EOPNOTSUPP;
1991+
1992+
if (attr->ct_attr.ct_action & TCA_CT_ACT_CLEAR) {
1993+
err = mlx5_tc_ct_entry_set_registers(priv, &attr->parse_attr->mod_hdr_acts,
1994+
0, 0, 0, 0);
1995+
if (err)
1996+
return err;
1997+
1998+
attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
1999+
}
2000+
2001+
if (!attr->ct_attr.nf_ft) /* means only ct clear action, and not ct_clear,ct() */
2002+
return 0;
20752003

20762004
mutex_lock(&priv->control_lock);
2077-
rule = __mlx5_tc_ct_flow_offload(priv, spec, attr);
2005+
err = __mlx5_tc_ct_flow_offload(priv, attr);
20782006
mutex_unlock(&priv->control_lock);
20792007

2080-
return rule;
2008+
return err;
20812009
}
20822010

20832011
static void
20842012
__mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *ct_priv,
2085-
struct mlx5_ct_flow *ct_flow,
20862013
struct mlx5_flow_attr *attr)
20872014
{
2088-
struct mlx5_flow_attr *pre_ct_attr = ct_flow->pre_ct_attr;
2089-
struct mlx5e_priv *priv = netdev_priv(ct_priv->netdev);
2090-
2091-
mlx5_tc_rule_delete(priv, ct_flow->pre_ct_rule, pre_ct_attr);
2092-
mlx5_modify_header_dealloc(priv->mdev, pre_ct_attr->modify_hdr);
2093-
20942015
mlx5e_tc_action_miss_mapping_put(ct_priv->priv, attr, attr->ct_attr.act_miss_mapping);
2095-
mlx5_tc_ct_del_ft_cb(ct_priv, ct_flow->ft);
2096-
2097-
kfree(ct_flow->pre_ct_attr);
2098-
kfree(ct_flow);
2016+
mlx5_tc_ct_del_ft_cb(ct_priv, attr->ct_attr.ft);
20992017
}
21002018

21012019
void
21022020
mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv,
21032021
struct mlx5_flow_attr *attr)
21042022
{
2105-
struct mlx5_ct_flow *ct_flow = attr->ct_attr.ct_flow;
2106-
2107-
/* We are called on error to clean up stuff from parsing
2108-
* but we don't have anything for now
2109-
*/
2110-
if (!ct_flow)
2023+
if (!attr->ct_attr.nf_ft) /* means only ct clear action, and not ct_clear,ct() */
21112024
return;
21122025

21132026
mutex_lock(&priv->control_lock);
2114-
__mlx5_tc_ct_delete_flow(priv, ct_flow, attr);
2027+
__mlx5_tc_ct_delete_flow(priv, attr);
21152028
mutex_unlock(&priv->control_lock);
21162029
}
21172030

0 commit comments

Comments
 (0)