Merge branch 'net-sched-refine-fq_codel-memory-limits'

Eric Dumazet says:

====================
net/sched: refine fq_codel memory limits

Packets that are associated with local sockets sk_wmem_alloc
do not really need additional memory control.

First patch makes is_skb_wmem() available to modules.

Second patch uses is_skb_wmem() in fq_codel.
====================

Link: https://patch.msgid.link/20260512094859.3673997-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-05-13 19:13:46 -07:00
commit 18dc8e6d15
8 changed files with 17 additions and 18 deletions

View File

@ -1850,8 +1850,18 @@ static inline struct sock *sk_clone_lock(const struct sock *sk, const gfp_t prio
struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force,
gfp_t priority);
void __sock_wfree(struct sk_buff *skb);
void sock_wfree(struct sk_buff *skb);
#ifdef CONFIG_INET
void __sock_wfree(struct sk_buff *skb);
void tcp_wfree(struct sk_buff *skb);
#endif
static inline bool is_skb_wmem(const struct sk_buff *skb)
{
return skb->destructor == sock_wfree ||
(IS_ENABLED(CONFIG_INET) && skb->destructor == __sock_wfree) ||
(IS_ENABLED(CONFIG_INET) && skb->destructor == tcp_wfree);
}
struct sk_buff *sock_omalloc(struct sock *sk, unsigned long size,
gfp_t priority);
void skb_orphan_partial(struct sk_buff *skb);

View File

@ -390,7 +390,6 @@ static inline bool tcp_release_cb_cond(struct sock *sk)
return false;
}
void tcp_wfree(struct sk_buff *skb);
void tcp_write_timer_handler(struct sock *sk);
void tcp_delack_timer_handler(struct sock *sk);
int tcp_ioctl(struct sock *sk, int cmd, int *karg);

View File

@ -78,6 +78,7 @@
#include <net/mpls.h>
#include <net/mptcp.h>
#include <net/mctp.h>
#include <net/tcp.h>
#include <net/can.h>
#include <net/page_pool/helpers.h>
#include <net/psp/types.h>
@ -96,7 +97,6 @@
#include "devmem.h"
#include "net-sysfs.h"
#include "netmem_priv.h"
#include "sock_destructor.h"
#ifdef CONFIG_SKB_EXTENSIONS
static struct kmem_cache *skbuff_ext_cache __ro_after_init;

View File

@ -2708,6 +2708,7 @@ EXPORT_SYMBOL(sock_wfree);
/* This variant of sock_wfree() is used by TCP,
* since it sets SOCK_USE_WRITE_QUEUE.
*/
#ifdef CONFIG_INET
void __sock_wfree(struct sk_buff *skb)
{
struct sock *sk = skb->sk;
@ -2715,6 +2716,8 @@ void __sock_wfree(struct sk_buff *skb)
if (refcount_sub_and_test(skb->truesize, &sk->sk_wmem_alloc))
__sk_free(sk);
}
EXPORT_SYMBOL_GPL(__sock_wfree);
#endif
void skb_set_owner_w(struct sk_buff *skb, struct sock *sk)
{

View File

@ -1,12 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef _NET_CORE_SOCK_DESTRUCTOR_H
#define _NET_CORE_SOCK_DESTRUCTOR_H
#include <net/tcp.h>
static inline bool is_skb_wmem(const struct sk_buff *skb)
{
return skb->destructor == sock_wfree ||
skb->destructor == __sock_wfree ||
(IS_ENABLED(CONFIG_INET) && skb->destructor == tcp_wfree);
}
#endif

View File

@ -24,8 +24,6 @@
#include <net/ip.h>
#include <net/ipv6.h>
#include "../core/sock_destructor.h"
/* Use skb->cb to track consecutive/adjacent fragments coming at
* the end of the queue. Nodes in the rb-tree queue will
* contain "runs" of one or more adjacent fragments.

View File

@ -1415,6 +1415,7 @@ void tcp_wfree(struct sk_buff *skb)
out:
sk_free(sk);
}
EXPORT_SYMBOL_GPL(tcp_wfree);
/* Note: Called under soft irq.
* We can call TCP stack right away, unless socket is owned by user.

View File

@ -212,7 +212,7 @@ static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch,
q->new_flow_count++;
WRITE_ONCE(flow->deficit, q->quantum);
}
get_codel_cb(skb)->mem_usage = skb->truesize;
get_codel_cb(skb)->mem_usage = is_skb_wmem(skb) ? 0 : skb->truesize;
q->memory_usage += get_codel_cb(skb)->mem_usage;
memory_limited = q->memory_usage > q->memory_limit;
qdisc_qlen_inc(sch);