* [PATCH net-next v3 0/4] net/sched: let actions drop their per CPU memory
@ 2026-11-09 12:46 Alexandre Cassen
2026-11-09 12:46 ` [PATCH net-next v3 1/4] net/sched: honor TCA_ACT_FLAGS_NO_PERCPU_STATS in more actions Alexandre Cassen
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: Alexandre Cassen @ 2026-11-09 12:46 UTC (permalink / raw)
To: Jamal Hadi Salim, Jiri Pirko
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Vladimir Oltean, Ido Schimmel, Daniel Borkmann,
Martin KaFai Lau, John Fastabend, Stanislav Fomichev,
Alexei Starovoitov, Andrii Nakryiko, Eduard Zingerman,
Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
Emil Tsalapatis, Ihor Solodrai, netdev, bpf
This series lets actions drop their per CPU stats and lets skip_sw
tunnel_key actions drop their dst cache:
- skbedit, police, mpls and sample honor TCA_ACT_FLAGS_NO_PERCPU_STATS.
- bpf, ife and skbmod honor it too. All actions now do.
- Action init sees the offload flags of the filter. A skip_sw filter
alone now satisfies the skbedit queue_mapping check.
- tunnel_key skips the dst cache for skip_sw actions.
v3:
- Add patch 2 for bpf, ife and skbmod (Jamal).
- Add Jamal's Reviewed-by to patch 3.
- Correct the memory saving in patch 1 to 8 KB. The 6.5 KB in v2 ignored
the padding that the alignment of the stats adds.
- Reword the title. Patch 2 does not concern hardware only actions.
v2: https://lore.kernel.org/netdev/20261104214607.556269-1-acassen@corp.free.fr/
- Add the act_api patch so that a skip_sw filter is enough for the
tunnel_key patch (Sashiko [1], Jakub).
- Give the memory saving in the tunnel_key patch (Sashiko [1], Jakub)
and in patch 1.
- Drop the race note from patch 1. Commit 1800f27a5ef8 ("net/sched:
act_api: take tcfa_lock for hardware stats updates") fixes this race,
which Sashiko [1] also flags.
- Add Jamal's Reviewed-by to patch 1 and the tunnel_key patch.
v1: https://lore.kernel.org/netdev/20261009051930.3619697-1-acassen@corp.free.fr/
[1] https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261009051930.3619697-1-acassen%40corp.free.fr
Alexandre Cassen (4):
net/sched: honor TCA_ACT_FLAGS_NO_PERCPU_STATS in more actions
net/sched: honor TCA_ACT_FLAGS_NO_PERCPU_STATS in bpf, ife and skbmod
net/sched: act_api: pass the filter offload flags to action init
net/sched: act_tunnel_key: skip dst cache for skip_sw actions
net/sched/act_api.c | 17 +++++++----------
net/sched/act_bpf.c | 8 ++++----
net/sched/act_ife.c | 24 ++++++++++++------------
net/sched/act_mpls.c | 8 ++++----
net/sched/act_police.c | 10 +++++-----
net/sched/act_sample.c | 6 +++---
net/sched/act_skbedit.c | 9 +++++----
net/sched/act_skbmod.c | 8 ++++----
net/sched/act_tunnel_key.c | 10 +++++++---
9 files changed, 51 insertions(+), 49 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH net-next v3 1/4] net/sched: honor TCA_ACT_FLAGS_NO_PERCPU_STATS in more actions
2026-11-09 12:46 [PATCH net-next v3 0/4] net/sched: let actions drop their per CPU memory Alexandre Cassen
@ 2026-11-09 12:46 ` Alexandre Cassen
2026-11-09 12:46 ` [PATCH net-next v3 2/4] net/sched: honor TCA_ACT_FLAGS_NO_PERCPU_STATS in bpf, ife and skbmod Alexandre Cassen
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Alexandre Cassen @ 2026-11-09 12:46 UTC (permalink / raw)
To: Jamal Hadi Salim, Jiri Pirko
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Vladimir Oltean, Ido Schimmel, netdev
skbedit, police, mpls and sample store and dump
TCA_ACT_FLAGS_NO_PERCPU_STATS since commit 40bd094d65fc ("flow_offload:
fill flags to action structure"), but still allocate per CPU stats.
These take about 8 KB per action on a 128 CPU host.
Honor the flag as the other offloadable actions already do. For example,
a per subscriber policer offloaded to hardware:
tc filter add dev $DEV ingress protocol ip flower skip_sw \
dst_ip 10.0.0.1/32 \
action police index 1 rate 1mbit burst 10k \
conform-exceed drop/pipe no_percpu
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Alexandre Cassen <acassen@corp.free.fr>
---
net/sched/act_mpls.c | 8 ++++----
net/sched/act_police.c | 10 +++++-----
net/sched/act_sample.c | 6 +++---
net/sched/act_skbedit.c | 9 +++++----
4 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/net/sched/act_mpls.c b/net/sched/act_mpls.c
index aa56521b7179..a870386386d9 100644
--- a/net/sched/act_mpls.c
+++ b/net/sched/act_mpls.c
@@ -60,7 +60,7 @@ TC_INDIRECT_SCOPE int tcf_mpls_act(struct sk_buff *skb,
int mac_len;
tcf_lastuse_update(&m->tcf_tm);
- bstats_update(this_cpu_ptr(m->common.cpu_bstats), skb);
+ tcf_action_update_bstats(&m->common, skb);
/* Ensure 'data' points at mac_header prior calling mpls manipulating
* functions.
@@ -123,7 +123,7 @@ TC_INDIRECT_SCOPE int tcf_mpls_act(struct sk_buff *skb,
return p->action;
drop:
- qstats_cpu_drop_inc(m->common.cpu_qstats);
+ tcf_action_inc_drop_qstats(&m->common);
return TC_ACT_SHOT;
}
@@ -196,8 +196,8 @@ static int tcf_mpls_init(struct net *net, struct nlattr *nla,
return ACT_P_BOUND;
if (!exists) {
- ret = tcf_idr_create(tn, index, est, a, &act_mpls_ops, bind,
- true, flags);
+ ret = tcf_idr_create_from_flags(tn, index, est, a,
+ &act_mpls_ops, bind, flags);
if (ret) {
tcf_idr_cleanup(tn, index);
return ret;
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index 3f8147f37549..0b0c09e3dfd9 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -80,8 +80,8 @@ static int tcf_police_init(struct net *net, struct nlattr *nla,
return ACT_P_BOUND;
if (!exists) {
- ret = tcf_idr_create(tn, index, NULL, a,
- &act_police_ops, bind, true, flags);
+ ret = tcf_idr_create_from_flags(tn, index, NULL, a,
+ &act_police_ops, bind, flags);
if (ret) {
tcf_idr_cleanup(tn, index);
return ret;
@@ -259,7 +259,7 @@ TC_INDIRECT_SCOPE int tcf_police_act(struct sk_buff *skb,
int ret;
tcf_lastuse_update(&police->tcf_tm);
- bstats_update(this_cpu_ptr(police->common.cpu_bstats), skb);
+ tcf_action_update_bstats(&police->common, skb);
p = rcu_dereference_bh(police->params);
ret = p->action;
@@ -313,10 +313,10 @@ TC_INDIRECT_SCOPE int tcf_police_act(struct sk_buff *skb,
}
inc_overlimits:
- qstats_cpu_overlimit_inc(police->common.cpu_qstats);
+ tcf_action_inc_overlimit_qstats(&police->common);
inc_drops:
if (ret == TC_ACT_SHOT)
- qstats_cpu_drop_inc(police->common.cpu_qstats);
+ tcf_action_inc_drop_qstats(&police->common);
end:
return ret;
}
diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c
index 44319a159b55..3029e93c4dea 100644
--- a/net/sched/act_sample.c
+++ b/net/sched/act_sample.c
@@ -69,8 +69,8 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,
return ACT_P_BOUND;
if (!exists) {
- ret = tcf_idr_create(tn, index, est, a,
- &act_sample_ops, bind, true, flags);
+ ret = tcf_idr_create_from_flags(tn, index, est, a,
+ &act_sample_ops, bind, flags);
if (ret) {
tcf_idr_cleanup(tn, index);
return ret;
@@ -173,7 +173,7 @@ TC_INDIRECT_SCOPE int tcf_sample_act(struct sk_buff *skb,
int retval;
tcf_lastuse_update(&s->tcf_tm);
- bstats_update(this_cpu_ptr(s->common.cpu_bstats), skb);
+ tcf_action_update_bstats(&s->common, skb);
retval = READ_ONCE(s->tcf_action);
psample_group = rcu_dereference_bh(s->psample_group);
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c
index 26258b353cde..1f958b7d2a60 100644
--- a/net/sched/act_skbedit.c
+++ b/net/sched/act_skbedit.c
@@ -45,7 +45,7 @@ TC_INDIRECT_SCOPE int tcf_skbedit_act(struct sk_buff *skb,
struct tcf_skbedit_params *params;
tcf_lastuse_update(&d->tcf_tm);
- bstats_update(this_cpu_ptr(d->common.cpu_bstats), skb);
+ tcf_action_update_bstats(&d->common, skb);
params = rcu_dereference_bh(d->params);
@@ -85,7 +85,7 @@ TC_INDIRECT_SCOPE int tcf_skbedit_act(struct sk_buff *skb,
return params->action;
err:
- qstats_cpu_drop_inc(d->common.cpu_qstats);
+ tcf_action_inc_drop_qstats(&d->common);
return TC_ACT_SHOT;
}
@@ -221,8 +221,9 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
}
if (!exists) {
- ret = tcf_idr_create(tn, index, est, a,
- &act_skbedit_ops, bind, true, act_flags);
+ ret = tcf_idr_create_from_flags(tn, index, est, a,
+ &act_skbedit_ops, bind,
+ act_flags);
if (ret) {
tcf_idr_cleanup(tn, index);
return ret;
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next v3 2/4] net/sched: honor TCA_ACT_FLAGS_NO_PERCPU_STATS in bpf, ife and skbmod
2026-11-09 12:46 [PATCH net-next v3 0/4] net/sched: let actions drop their per CPU memory Alexandre Cassen
2026-11-09 12:46 ` [PATCH net-next v3 1/4] net/sched: honor TCA_ACT_FLAGS_NO_PERCPU_STATS in more actions Alexandre Cassen
@ 2026-11-09 12:46 ` Alexandre Cassen
2026-11-12 1:22 ` Jakub Kicinski
2026-11-09 12:46 ` [PATCH net-next v3 3/4] net/sched: act_api: pass the filter offload flags to action init Alexandre Cassen
` (2 subsequent siblings)
4 siblings, 1 reply; 8+ messages in thread
From: Alexandre Cassen @ 2026-11-09 12:46 UTC (permalink / raw)
To: Jamal Hadi Salim, Jiri Pirko
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Vladimir Oltean, Ido Schimmel, Daniel Borkmann,
Martin KaFai Lau, John Fastabend, Stanislav Fomichev,
Alexei Starovoitov, Andrii Nakryiko, Eduard Zingerman,
Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
Emil Tsalapatis, Ihor Solodrai, netdev, bpf
bpf, ife and skbmod are the last actions that ignore
TCA_ACT_FLAGS_NO_PERCPU_STATS. Commit 40bd094d65fc ("flow_offload: fill
flags to action structure") makes them store and dump the flag. They
still allocate per CPU stats, about 8 KB per action on a 128 CPU host.
Yet tc reports no_percpu on them.
Honor the flag here too. These actions run only in software. With
no_percpu every packet takes tcfa_lock to update the stats. Only the
users who set the flag pay this cost.
Signed-off-by: Alexandre Cassen <acassen@corp.free.fr>
---
net/sched/act_bpf.c | 8 ++++----
net/sched/act_ife.c | 24 ++++++++++++------------
net/sched/act_skbmod.c | 8 ++++----
3 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c
index 06d8f78b7368..3aea3ff5785f 100644
--- a/net/sched/act_bpf.c
+++ b/net/sched/act_bpf.c
@@ -42,7 +42,7 @@ TC_INDIRECT_SCOPE int tcf_bpf_act(struct sk_buff *skb,
int action, filter_res;
tcf_lastuse_update(&prog->tcf_tm);
- bstats_update(this_cpu_ptr(prog->common.cpu_bstats), skb);
+ tcf_action_update_bstats(&prog->common, skb);
filter = rcu_dereference_bh(prog->filter);
if (at_ingress) {
@@ -76,7 +76,7 @@ TC_INDIRECT_SCOPE int tcf_bpf_act(struct sk_buff *skb,
break;
case TC_ACT_SHOT:
action = filter_res;
- qstats_cpu_drop_inc(prog->common.cpu_qstats);
+ tcf_action_inc_drop_qstats(&prog->common);
break;
case TC_ACT_UNSPEC:
action = prog->tcf_action;
@@ -305,8 +305,8 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
index = parm->index;
ret = tcf_idr_check_alloc(tn, &index, act, bind);
if (!ret) {
- ret = tcf_idr_create(tn, index, est, act,
- &act_bpf_ops, bind, true, flags);
+ ret = tcf_idr_create_from_flags(tn, index, est, act,
+ &act_bpf_ops, bind, flags);
if (ret < 0) {
tcf_idr_cleanup(tn, index);
return ret;
diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
index 3946a9589bb8..a931f0d353d2 100644
--- a/net/sched/act_ife.c
+++ b/net/sched/act_ife.c
@@ -551,8 +551,8 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
}
if (!exists) {
- ret = tcf_idr_create(tn, index, est, a, &act_ife_ops,
- bind, true, flags);
+ ret = tcf_idr_create_from_flags(tn, index, est, a,
+ &act_ife_ops, bind, flags);
if (ret) {
tcf_idr_cleanup(tn, index);
kfree(p);
@@ -720,7 +720,7 @@ static int tcf_ife_decode(struct sk_buff *skb, const struct tc_action *a,
p = rcu_dereference_bh(ife->params);
- bstats_update(this_cpu_ptr(ife->common.cpu_bstats), skb);
+ tcf_action_update_bstats(&ife->common, skb);
tcf_lastuse_update(&ife->tcf_tm);
if (skb_at_tc_ingress(skb))
@@ -728,7 +728,7 @@ static int tcf_ife_decode(struct sk_buff *skb, const struct tc_action *a,
tlv_data = ife_decode(skb, &metalen);
if (unlikely(!tlv_data)) {
- qstats_cpu_drop_inc(ife->common.cpu_qstats);
+ tcf_action_inc_drop_qstats(&ife->common);
return TC_ACT_SHOT;
}
@@ -742,7 +742,7 @@ static int tcf_ife_decode(struct sk_buff *skb, const struct tc_action *a,
curr_data = ife_tlv_meta_decode(tlv_data, ifehdr_end, &mtype,
&dlen, NULL);
if (!curr_data) {
- qstats_cpu_drop_inc(ife->common.cpu_qstats);
+ tcf_action_inc_drop_qstats(&ife->common);
return TC_ACT_SHOT;
}
@@ -751,7 +751,7 @@ static int tcf_ife_decode(struct sk_buff *skb, const struct tc_action *a,
/* abuse overlimits to count metadata we cannot
* decode: no ops for it, or the decoder rejected it
*/
- qstats_cpu_overlimit_inc(ife->common.cpu_qstats);
+ tcf_action_inc_overlimit_qstats(&ife->common);
if (ret == -ENOENT)
pr_info_ratelimited("Unknown metaid %d dlen %d\n",
@@ -763,7 +763,7 @@ static int tcf_ife_decode(struct sk_buff *skb, const struct tc_action *a,
}
if (WARN_ON(tlv_data != ifehdr_end)) {
- qstats_cpu_drop_inc(ife->common.cpu_qstats);
+ tcf_action_inc_drop_qstats(&ife->common);
return TC_ACT_SHOT;
}
@@ -819,21 +819,21 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a,
exceed_mtu = true;
}
- bstats_update(this_cpu_ptr(ife->common.cpu_bstats), skb);
+ tcf_action_update_bstats(&ife->common, skb);
tcf_lastuse_update(&ife->tcf_tm);
if (!metalen) { /* no metadata to send */
/* abuse overlimits to count when we allow packet
* with no metadata
*/
- qstats_cpu_overlimit_inc(ife->common.cpu_qstats);
+ tcf_action_inc_overlimit_qstats(&ife->common);
return action;
}
/* could be stupid policy setup or mtu config
* so lets be conservative.. */
if ((action == TC_ACT_SHOT) || exceed_mtu) {
drop:
- qstats_cpu_drop_inc(ife->common.cpu_qstats);
+ tcf_action_inc_drop_qstats(&ife->common);
return TC_ACT_SHOT;
}
@@ -898,9 +898,9 @@ TC_INDIRECT_SCOPE int tcf_ife_act(struct sk_buff *skb,
int ret;
if (unlikely(!tcf_ife_is_eth_skb(skb))) {
- bstats_update(this_cpu_ptr(ife->common.cpu_bstats), skb);
+ tcf_action_update_bstats(&ife->common, skb);
tcf_lastuse_update(&ife->tcf_tm);
- qstats_cpu_drop_inc(ife->common.cpu_qstats);
+ tcf_action_inc_drop_qstats(&ife->common);
return TC_ACT_SHOT;
}
diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c
index 09e9dcf58253..72dedb9b19a6 100644
--- a/net/sched/act_skbmod.c
+++ b/net/sched/act_skbmod.c
@@ -32,7 +32,7 @@ TC_INDIRECT_SCOPE int tcf_skbmod_act(struct sk_buff *skb,
u64 flags;
tcf_lastuse_update(&d->tcf_tm);
- bstats_update(this_cpu_ptr(d->common.cpu_bstats), skb);
+ tcf_action_update_bstats(&d->common, skb);
p = rcu_dereference_bh(d->skbmod_p);
if (unlikely(p->action == TC_ACT_SHOT))
@@ -91,7 +91,7 @@ TC_INDIRECT_SCOPE int tcf_skbmod_act(struct sk_buff *skb,
return p->action;
drop:
- qstats_cpu_overlimit_inc(d->common.cpu_qstats);
+ tcf_action_inc_overlimit_qstats(&d->common);
return TC_ACT_SHOT;
}
@@ -171,8 +171,8 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla,
}
if (!exists) {
- ret = tcf_idr_create(tn, index, est, a,
- &act_skbmod_ops, bind, true, flags);
+ ret = tcf_idr_create_from_flags(tn, index, est, a,
+ &act_skbmod_ops, bind, flags);
if (ret) {
tcf_idr_cleanup(tn, index);
return ret;
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next v3 3/4] net/sched: act_api: pass the filter offload flags to action init
2026-11-09 12:46 [PATCH net-next v3 0/4] net/sched: let actions drop their per CPU memory Alexandre Cassen
2026-11-09 12:46 ` [PATCH net-next v3 1/4] net/sched: honor TCA_ACT_FLAGS_NO_PERCPU_STATS in more actions Alexandre Cassen
2026-11-09 12:46 ` [PATCH net-next v3 2/4] net/sched: honor TCA_ACT_FLAGS_NO_PERCPU_STATS in bpf, ife and skbmod Alexandre Cassen
@ 2026-11-09 12:46 ` Alexandre Cassen
2026-11-09 12:46 ` [PATCH net-next v3 4/4] net/sched: act_tunnel_key: skip dst cache for skip_sw actions Alexandre Cassen
2026-11-12 1:30 ` [PATCH net-next v3 0/4] net/sched: let actions drop their per CPU memory patchwork-bot+netdevbpf
4 siblings, 0 replies; 8+ messages in thread
From: Alexandre Cassen @ 2026-11-09 12:46 UTC (permalink / raw)
To: Jamal Hadi Salim, Jiri Pirko
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Vladimir Oltean, Ido Schimmel, netdev
A skip_sw filter gives its skip_sw flag to its actions only after their
->init() returns. ->init() then cannot know that the action never runs
in software unless the user also sets skip_sw on the action. Since
commit 34d35b4edbbe ("net/sched: act_api: deny mismatched
skip_sw/skip_hw flags for actions created by classifiers"), this action
flag also needs the filter one. The Sashiko AI review [1] of the
tunnel_key dst cache patch reports this limit.
Pass the filter offload flags to ->init() so that an action can skip the
state only the software path needs, like the tunnel_key dst cache.
tcf_idr_create() stores them in the new action, which replaces the
inheritance after ->init(). Since commit 9463e8d8c692 ("net/sched:
act_api: inherit filter offload flags only on new actions"), this
inheritance only applies to new actions, so the final action flags do
not change.
No action reads skip_hw at init and only act_skbedit reads skip_sw.
Since commit 4a6a676f8c16 ("act_skbedit: skbedit queue mapping for
receive queue"), it requires skip_sw for a receive queue_mapping. The
filter flag is now enough for this check.
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261009051930.3619697-1-acassen%40corp.free.fr [1]
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Alexandre Cassen <acassen@corp.free.fr>
---
net/sched/act_api.c | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index e142d33dc5ef..13317d1abde1 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -1531,6 +1531,12 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
ops[i - 1] = a_o;
}
+ /* New actions inherit these flags and init can skip software state */
+ if (tc_skip_sw(fl_flags))
+ flags |= TCA_ACT_FLAGS_SKIP_SW;
+ if (tc_skip_hw(fl_flags))
+ flags |= TCA_ACT_FLAGS_SKIP_HW;
+
for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
act = tcf_action_init_1(net, tp, tb[i], est, ops[i - 1],
&init_res[i - 1], flags, extack);
@@ -1549,9 +1555,7 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
/* Action is created by classifier and is not
* standalone. Check that the user did not set
* any action flags different than the
- * classifier flags, and inherit the flags from
- * the classifier for the compatibility case
- * where no flags were specified at all.
+ * classifier flags.
*/
if ((tc_act_skip_sw(act->tcfa_flags) && !skip_sw) ||
(tc_act_skip_hw(act->tcfa_flags) && !skip_hw)) {
@@ -1560,13 +1564,6 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
err = -EINVAL;
goto err;
}
- /* Other filters share an existing action */
- if (init_res[i - 1] != ACT_P_CREATED)
- continue;
- if (skip_sw)
- act->tcfa_flags |= TCA_ACT_FLAGS_SKIP_SW;
- if (skip_hw)
- act->tcfa_flags |= TCA_ACT_FLAGS_SKIP_HW;
continue;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next v3 4/4] net/sched: act_tunnel_key: skip dst cache for skip_sw actions
2026-11-09 12:46 [PATCH net-next v3 0/4] net/sched: let actions drop their per CPU memory Alexandre Cassen
` (2 preceding siblings ...)
2026-11-09 12:46 ` [PATCH net-next v3 3/4] net/sched: act_api: pass the filter offload flags to action init Alexandre Cassen
@ 2026-11-09 12:46 ` Alexandre Cassen
2026-11-12 1:30 ` [PATCH net-next v3 0/4] net/sched: let actions drop their per CPU memory patchwork-bot+netdevbpf
4 siblings, 0 replies; 8+ messages in thread
From: Alexandre Cassen @ 2026-11-09 12:46 UTC (permalink / raw)
To: Jamal Hadi Salim, Jiri Pirko
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Vladimir Oltean, Ido Schimmel, netdev
A tunnel_key set action allocates a per CPU dst cache for the software
path. This takes about 5 KB per action on a 128 CPU host. An action
flagged skip_sw never runs in software and the dst_cache helpers handle
a missing cache, so skip the allocation. Since the previous patch, a
skip_sw filter alone is enough. A replace leaves the flags of an
existing action unchanged, so check these rather than the request ones.
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Alexandre Cassen <acassen@corp.free.fr>
---
net/sched/act_tunnel_key.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
index 503834853306..28d9cc080101 100644
--- a/net/sched/act_tunnel_key.c
+++ b/net/sched/act_tunnel_key.c
@@ -481,9 +481,13 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
}
#ifdef CONFIG_DST_CACHE
- ret = dst_cache_init(&metadata->u.tun_info.dst_cache, GFP_KERNEL);
- if (ret)
- goto release_tun_meta;
+ if (!((exists ? (*a)->tcfa_flags : act_flags) &
+ TCA_ACT_FLAGS_SKIP_SW)) {
+ ret = dst_cache_init(&metadata->u.tun_info.dst_cache,
+ GFP_KERNEL);
+ if (ret)
+ goto release_tun_meta;
+ }
#endif
if (opts_len) {
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH net-next v3 2/4] net/sched: honor TCA_ACT_FLAGS_NO_PERCPU_STATS in bpf, ife and skbmod
2026-11-09 12:46 ` [PATCH net-next v3 2/4] net/sched: honor TCA_ACT_FLAGS_NO_PERCPU_STATS in bpf, ife and skbmod Alexandre Cassen
@ 2026-11-12 1:22 ` Jakub Kicinski
2026-11-12 9:06 ` Alexandre Cassen
0 siblings, 1 reply; 8+ messages in thread
From: Jakub Kicinski @ 2026-11-12 1:22 UTC (permalink / raw)
To: Alexandre Cassen
Cc: Jamal Hadi Salim, Jiri Pirko, David S. Miller, Eric Dumazet,
Paolo Abeni, Simon Horman, Vladimir Oltean, Ido Schimmel,
Daniel Borkmann, Martin KaFai Lau, John Fastabend,
Stanislav Fomichev, Alexei Starovoitov, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Song Liu,
Yonghong Song, Jiri Olsa, Emil Tsalapatis, Ihor Solodrai, netdev,
bpf
On Mon, 9 Nov 2026 13:46:13 +0100 Alexandre Cassen wrote:
> - ret = tcf_idr_create(tn, index, est, act,
> - &act_bpf_ops, bind, true, flags);
> + ret = tcf_idr_create_from_flags(tn, index, est, act,
> + &act_bpf_ops, bind, flags);
Now that we modified all actions could you take a look at removing
the unnecessary API variants? tcf_idr_create() has one remaining
caller AFAICT, so we can probably rename tcf_idr_create_from_flags()
back to tcf_idr_create() and make using flags the default?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next v3 0/4] net/sched: let actions drop their per CPU memory
2026-11-09 12:46 [PATCH net-next v3 0/4] net/sched: let actions drop their per CPU memory Alexandre Cassen
` (3 preceding siblings ...)
2026-11-09 12:46 ` [PATCH net-next v3 4/4] net/sched: act_tunnel_key: skip dst cache for skip_sw actions Alexandre Cassen
@ 2026-11-12 1:30 ` patchwork-bot+netdevbpf
4 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-11-12 1:30 UTC (permalink / raw)
To: Alexandre Cassen
Cc: jhs, jiri, davem, edumazet, kuba, pabeni, horms, vladimir.oltean,
idosch, daniel, martin.lau, john.fastabend, sdf, ast, andrii,
eddyz87, memxor, song, yonghong.song, jolsa, emil, ihor.solodrai,
netdev, bpf
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Mon, 9 Nov 2026 13:46:11 +0100 you wrote:
> This series lets actions drop their per CPU stats and lets skip_sw
> tunnel_key actions drop their dst cache:
>
> - skbedit, police, mpls and sample honor TCA_ACT_FLAGS_NO_PERCPU_STATS.
> - bpf, ife and skbmod honor it too. All actions now do.
> - Action init sees the offload flags of the filter. A skip_sw filter
> alone now satisfies the skbedit queue_mapping check.
> - tunnel_key skips the dst cache for skip_sw actions.
>
> [...]
Here is the summary with links:
- [net-next,v3,1/4] net/sched: honor TCA_ACT_FLAGS_NO_PERCPU_STATS in more actions
https://git.kernel.org/netdev/net-next/c/a4c9d4347525
- [net-next,v3,2/4] net/sched: honor TCA_ACT_FLAGS_NO_PERCPU_STATS in bpf, ife and skbmod
https://git.kernel.org/netdev/net-next/c/72760229298c
- [net-next,v3,3/4] net/sched: act_api: pass the filter offload flags to action init
https://git.kernel.org/netdev/net-next/c/7744652f1063
- [net-next,v3,4/4] net/sched: act_tunnel_key: skip dst cache for skip_sw actions
https://git.kernel.org/netdev/net-next/c/fc40a98e5be9
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next v3 2/4] net/sched: honor TCA_ACT_FLAGS_NO_PERCPU_STATS in bpf, ife and skbmod
2026-11-12 1:22 ` Jakub Kicinski
@ 2026-11-12 9:06 ` Alexandre Cassen
0 siblings, 0 replies; 8+ messages in thread
From: Alexandre Cassen @ 2026-11-12 9:06 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Jamal Hadi Salim, Jiri Pirko, David S. Miller, Eric Dumazet,
Paolo Abeni, Simon Horman, Vladimir Oltean, Ido Schimmel,
Daniel Borkmann, Martin KaFai Lau, John Fastabend,
Stanislav Fomichev, Alexei Starovoitov, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Song Liu,
Yonghong Song, Jiri Olsa, Emil Tsalapatis, Ihor Solodrai, netdev,
bpf
On 11/12/26 02:22, Jakub Kicinski wrote:
> On Mon, 9 Nov 2026 13:46:13 +0100 Alexandre Cassen wrote:
>> - ret = tcf_idr_create(tn, index, est, act,
>> - &act_bpf_ops, bind, true, flags);
>> + ret = tcf_idr_create_from_flags(tn, index, est, act,
>> + &act_bpf_ops, bind, flags);
>
> Now that we modified all actions could you take a look at removing
> the unnecessary API variants? tcf_idr_create() has one remaining
> caller AFAICT, so we can probably rename tcf_idr_create_from_flags()
> back to tcf_idr_create() and make using flags the default?
ack, will have a look over the week-end (and try to respond to the
sashiko boy on previous mlx5 patchset for tunnel key partitioning)
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-11-12 9:06 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-09 12:46 [PATCH net-next v3 0/4] net/sched: let actions drop their per CPU memory Alexandre Cassen
2026-11-09 12:46 ` [PATCH net-next v3 1/4] net/sched: honor TCA_ACT_FLAGS_NO_PERCPU_STATS in more actions Alexandre Cassen
2026-11-09 12:46 ` [PATCH net-next v3 2/4] net/sched: honor TCA_ACT_FLAGS_NO_PERCPU_STATS in bpf, ife and skbmod Alexandre Cassen
2026-11-12 1:22 ` Jakub Kicinski
2026-11-12 9:06 ` Alexandre Cassen
2026-11-09 12:46 ` [PATCH net-next v3 3/4] net/sched: act_api: pass the filter offload flags to action init Alexandre Cassen
2026-11-09 12:46 ` [PATCH net-next v3 4/4] net/sched: act_tunnel_key: skip dst cache for skip_sw actions Alexandre Cassen
2026-11-12 1:30 ` [PATCH net-next v3 0/4] net/sched: let actions drop their per CPU memory patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox