diff options
| author | Eric Dumazet <edumazet@google.com> | 2026-03-11 22:13:40 +0300 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-03-13 05:25:33 +0300 |
| commit | 08dc30de1a402fe88fd80592cf6c72c4c2ebbcbc (patch) | |
| tree | c2eca015f3486894357232b49c9573a92d706af6 | |
| parent | 15abbe7c82661209c1dc67c21903c07e2fff5aae (diff) | |
| download | linux-08dc30de1a402fe88fd80592cf6c72c4c2ebbcbc.tar.xz | |
net: add skb_defer_disable_key static key
Add a static key to bypass skb_attempt_defer_free() steps
if net.core.skb_defer_max is set to zero.
Main benefit is the atomic_long_inc_return() avoidance.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260311191340.1996888-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | net/core/net-sysfs.h | 1 | ||||
| -rw-r--r-- | net/core/skbuff.c | 5 | ||||
| -rw-r--r-- | net/core/sysctl_net_core.c | 25 |
3 files changed, 30 insertions, 1 deletions
diff --git a/net/core/net-sysfs.h b/net/core/net-sysfs.h index e938f25e8e86..38e2e3ffd0bd 100644 --- a/net/core/net-sysfs.h +++ b/net/core/net-sysfs.h @@ -13,4 +13,5 @@ int netdev_change_owner(struct net_device *, const struct net *net_old, extern struct mutex rps_default_mask_mutex; +DECLARE_STATIC_KEY_FALSE(skb_defer_disable_key); #endif diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 513cbfed19bc..3d6978dd0aa8 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -7256,6 +7256,8 @@ static void kfree_skb_napi_cache(struct sk_buff *skb) local_bh_enable(); } +DEFINE_STATIC_KEY_FALSE(skb_defer_disable_key); + /** * skb_attempt_defer_free - queue skb for remote freeing * @skb: buffer @@ -7272,6 +7274,9 @@ void skb_attempt_defer_free(struct sk_buff *skb) bool kick; int cpu; + if (static_branch_unlikely(&skb_defer_disable_key)) + goto nodefer; + /* zero copy notifications should not be delayed. */ if (skb_zcopy(skb)) goto nodefer; diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index 502705e04649..b508618bfc12 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c @@ -349,6 +349,29 @@ static int proc_do_rss_key(const struct ctl_table *table, int write, return proc_dostring(&fake_table, write, buffer, lenp, ppos); } +static int proc_do_skb_defer_max(const struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) +{ + static DEFINE_MUTEX(skb_defer_max_mutex); + int ret, oval, nval; + + mutex_lock(&skb_defer_max_mutex); + + oval = !net_hotdata.sysctl_skb_defer_max; + ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + nval = !net_hotdata.sysctl_skb_defer_max; + + if (nval != oval) { + if (nval) + static_branch_enable(&skb_defer_disable_key); + else + static_branch_disable(&skb_defer_disable_key); + } + + mutex_unlock(&skb_defer_max_mutex); + return ret; +} + #ifdef CONFIG_BPF_JIT static int proc_dointvec_minmax_bpf_enable(const struct ctl_table *table, int write, void *buffer, size_t *lenp, @@ -650,7 +673,7 @@ static struct ctl_table net_core_table[] = { .data = &net_hotdata.sysctl_skb_defer_max, .maxlen = sizeof(unsigned int), .mode = 0644, - .proc_handler = proc_dointvec_minmax, + .proc_handler = proc_do_skb_defer_max, .extra1 = SYSCTL_ZERO, }, }; |
