Merge branch 'net-do-not-warn-on-best-effort-skb-allocation-failures'

Breno Leitao says:

====================
net: do not warn on best-effort skb allocation failures

Both netconsole and netpoll keep a small preallocated pool of skbs
(skb_pool) so they can still get a buffer under memory pressure.

On the hot path they first attempt a normal GFP_ATOMIC allocation and only
fall back to the pool when that fails, keeping the pool as a last resort.

This is where the problem happens. If alloc_skb() fails, we now have
more than 100 message coming from the page=0 failure, which consumes
the scarce pool of skb, making the real issue disappear.

So the noise (memory allocation failure) deplets the SKB buffer and
crowds out the real message we were trying to deliver.

This is happening on the Meta fleet. The stack trace looks like:

  pr/netcon_ext0: page allocation failure: order:0, mode:0x40820(GFP_ATOMIC|__GFP_COMP), nodemask=(null),cpuset=/,mems_allowed=0
  ...
  dump_stack_lvl
  warn_alloc
  __alloc_pages_slowpath
  __alloc_frozen_pages_noprof
  alloc_pages_mpol
  alloc_slab_page
  allocate_slab
  kmem_cache_alloc_node_noprof
  __alloc_skb
  send_udp
  netconsole_write
  nbcon_emit_next_record
  nbcon_emit_one
  nbcon_kthread_func
  kthread

Solution: Do not warn if netconsole/netpoll fails to allocate these SKBs.
Pass __GFP_NOWARN on these best-effort allocations -- both the hot-path
attempt in netconsole's find_skb() and the pool refill in netpoll's
refill_skbs() -- and let the existing fallback paths do their job
quietly. The allocation will happen on SKB refill workqueue.

Given I am touching this code, if alloc_skb() fails, reschedule the
workqueue to try later.
====================

Link: https://patch.msgid.link/20260629-netpoll_no_warn-v1-0-f380f0b2cd0c@debian.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-06-30 17:15:13 -07:00
commit 1c664ec4b9
2 changed files with 2 additions and 2 deletions

View File

@ -1737,7 +1737,7 @@ static struct sk_buff *find_skb(struct netpoll *np, int len, int reserve)
netpoll_zap_completion_queue();
repeat:
skb = alloc_skb(len, GFP_ATOMIC);
skb = alloc_skb(len, GFP_ATOMIC | __GFP_NOWARN);
if (!skb)
skb = netcons_skb_pop(np, len);

View File

@ -221,7 +221,7 @@ static void refill_skbs(struct netpoll *np)
skb_pool = &np->skb_pool;
while (READ_ONCE(skb_pool->qlen) < MAX_SKBS) {
skb = alloc_skb(MAX_SKB_SIZE, GFP_ATOMIC);
skb = alloc_skb(MAX_SKB_SIZE, GFP_ATOMIC | __GFP_NOWARN);
if (!skb)
break;