summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2026-10-15 11:50:37 +0200
committerPaolo Abeni <pabeni@redhat.com>2026-10-15 11:50:37 +0200
commit00d8d01ff8d337c08de9368072f090b5f3a66bcb (patch)
treeab2d4013c1e2a3d0a943646773898608f43152b0
parent0e96012d3df7098dbde46ec94cc3402f97487d1b (diff)
parent3636705910f925190c949513cc5d8fa5d3f3ed92 (diff)
Merge branch 'net-mlx5-less-memory-per-offloaded-tc-rule'
Alexandre Cassen says: ==================== net/mlx5: less memory per offloaded tc rule Two mlx5 allocations hold more memory than an offloaded tc rule needs. A NIC flow keeps a 4 KB allocation for parse attributes that nothing reads after offload. An FTE under hardware steering keeps the 1 KB action array it was built in while a rule rarely needs more than three entries. Freeing the first after offload saves 4 KB per NIC flow. Shrinking the second saves about 1 KB per FTE under hardware steering. ==================== Link: https://patch.msgid.link/20261009052103.3621855-1-acassen@corp.free.fr Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tc.c18
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c10
2 files changed, 22 insertions, 6 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index c99e824b4c6d..708b7987ea4c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -1414,6 +1414,16 @@ void mlx5e_del_offloaded_nic_rule(struct mlx5e_priv *priv,
MLX5E_TC_FT_LEVEL);
}
+static void mlx5e_tc_free_parse_attr(struct mlx5_flow_attr *attr)
+{
+ if (!attr->parse_attr)
+ return;
+
+ mlx5e_mod_hdr_dealloc(&attr->parse_attr->mod_hdr_acts);
+ kvfree(attr->parse_attr);
+ attr->parse_attr = NULL;
+}
+
static void mlx5e_tc_del_nic_flow(struct mlx5e_priv *priv,
struct mlx5e_tc_flow *flow)
{
@@ -1436,10 +1446,8 @@ static void mlx5e_tc_del_nic_flow(struct mlx5e_priv *priv,
}
mutex_unlock(&tc->t_lock);
- if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) {
- mlx5e_mod_hdr_dealloc(&attr->parse_attr->mod_hdr_acts);
+ if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR)
mlx5e_tc_detach_mod_hdr(priv, flow, attr);
- }
if (attr->action & MLX5_FLOW_CONTEXT_ACTION_COUNT)
mlx5_fc_destroy(priv->mdev, attr->counter);
@@ -1450,7 +1458,7 @@ static void mlx5e_tc_del_nic_flow(struct mlx5e_priv *priv,
free_flow_post_acts(flow);
mlx5_tc_ct_delete_flow(get_ct_priv(flow->priv), attr);
- kvfree(attr->parse_attr);
+ mlx5e_tc_free_parse_attr(attr);
kfree(flow->attr);
}
@@ -4759,6 +4767,7 @@ mlx5e_add_nic_flow(struct mlx5e_priv *priv,
if (err)
goto err_free;
+ mlx5e_tc_free_parse_attr(flow->attr);
flow_flag_set(flow, OFFLOADED);
*__flow = flow;
@@ -4766,7 +4775,6 @@ mlx5e_add_nic_flow(struct mlx5e_priv *priv,
err_free:
flow_flag_set(flow, FAILED);
- mlx5e_mod_hdr_dealloc(&parse_attr->mod_hdr_acts);
mlx5e_flow_put(priv, flow);
out:
return err;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c
index 5a172c572a68..da6e57c103d6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c
@@ -746,6 +746,7 @@ static int mlx5_fs_fte_get_hws_actions(struct mlx5_flow_root_namespace *ns,
struct mlx5_fs_hws_context *fs_ctx = &ns->fs_hws_context;
struct mlx5hws_action_dest_attr *dest_actions;
struct mlx5hws_context *ctx = fs_ctx->hws_ctx;
+ struct mlx5_fs_hws_rule_action *rule_actions;
struct mlx5_fs_hws_rule_action *fs_actions;
struct mlx5_core_dev *dev = ns->dev;
struct mlx5hws_action *dest_action;
@@ -1041,13 +1042,20 @@ static int mlx5_fs_fte_get_hws_actions(struct mlx5_flow_root_namespace *ns,
fs_actions[num_fs_actions++].action = tmp_action;
(*ractions)[num_actions++].action = tmp_action;
+ rule_actions = kmemdup_array(fs_actions, num_fs_actions,
+ sizeof(*fs_actions), GFP_KERNEL);
+ if (!rule_actions) {
+ err = -ENOMEM;
+ goto free_actions;
+ }
+ kfree(fs_actions);
kfree(dest_actions);
/* Actions created specifically for this rule will be destroyed
* once rule is deleted.
*/
fte->fs_hws_rule.num_fs_actions = num_fs_actions;
- fte->fs_hws_rule.hws_fs_actions = fs_actions;
+ fte->fs_hws_rule.hws_fs_actions = rule_actions;
return 0;