mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH net v7] net: stop defer_count outliving the deferred-free list
@ 2026-10-29 21:11 Joseph Kain
  2026-10-29 21:13 ` netdev-bot+sinfo
  0 siblings, 1 reply; 3+ messages in thread
From: Joseph Kain @ 2026-10-29 21:11 UTC (permalink / raw)
  To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, David S. Miller, netdev
  Cc: Simon Horman, Kuniyuki Iwashima, Stanislav Fomichev, Jason Xing,
	Willem de Bruijn, Mina Almasry, Martin Karsten, Jiayuan Chen,
	linux-kernel, Joseph Kain

After the llist conversion, rejected frees retain their counter
increments. A producer racing the counter reset and list detach can
also leave a count for an skb already drained. Deferred freeing can
then remain disabled while the list is empty.

Undo rejected reservations and subtract only the number of skbs
drained. Allow admission up to the configured limit. Retain the
halfway notification and also notify when the reserved count reaches
the limit, covering reservations published after an earlier purge.

Fixes: 844c9db7f7f5 ("net: use llist for sd->defer_list")
Signed-off-by: Joseph Kain <jkain@nuro.ai>
Assisted-by: LLM
---
For 6.18-7.1, apply the drain change inside each NUMA-node iteration
of skb_defer_free_flush(), using sdn->defer_list and sdn->defer_count.
Initialize n to zero for each node.
---
 net/core/dev.c    |  8 +++++++-
 net/core/skbuff.c | 17 ++++++++++++++---
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 18dc88990510..7843ef511d7e 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6937,16 +6937,22 @@ static void __skb_defer_free_flush(struct skb_defer_node *sdn, int budget)
 {
 	struct llist_node *free_list;
 	struct sk_buff *skb, *next;
+	long n = 0;
 
 	if (llist_empty(&sdn->defer_list))
 		return;
-	atomic_long_set(&sdn->defer_count, 0);
 	free_list = llist_del_all(&sdn->defer_list);
 
 	llist_for_each_entry_safe(skb, next, free_list, ll_node) {
 		prefetch(next);
 		napi_consume_skb(skb, budget);
+		n++;
 	}
+	/* Subtract exactly what was drained. Never store an absolute value:
+	 * mixing one with the relative updates in skb_attempt_defer_free()
+	 * lets the counter go negative, and it is read as unsigned there.
+	 */
+	atomic_long_sub(n, &sdn->defer_count);
 }
 
 void skb_defer_node_flush(struct skb_defer_node *sdn)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 4aea06d5167d..b1d3fd783283 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -7388,8 +7388,14 @@ nodefer:	kfree_skb_napi_cache(skb);
 	defer_max = READ_ONCE(net_hotdata.sysctl_skb_defer_max);
 	defer_count = atomic_long_inc_return(&sdn->defer_count);
 
-	if (defer_count >= defer_max)
+	if (defer_count > defer_max) {
+		/* Undo the reservation. An llist_add() does not release one --
+		 * the skb stays charged until a flush subtracts the batch that
+		 * contains it -- so a rejected free must undo its own.
+		 */
+		atomic_long_dec(&sdn->defer_count);
 		goto nodefer;
+	}
 
 	llist_add(&skb->ll_node, &sdn->defer_list);
 
@@ -7398,8 +7404,13 @@ nodefer:	kfree_skb_napi_cache(skb);
 		return;
 	}
 
-	/* Send an IPI every time queue reaches half capacity. */
-	kick = (defer_count - 1) == (defer_max >> 1);
+	/* Half capacity, plus the skb that fills the queue. Equality alone can
+	 * be consumed early -- if the producer holding the kick value publishes
+	 * first, its purge drains only that skb and the reservations published
+	 * after it match nothing -- which would leave a full queue with nothing
+	 * pending.
+	 */
+	kick = (defer_count - 1) == (defer_max >> 1) || defer_count == defer_max;
 
 	/* Make sure to trigger NET_RX_SOFTIRQ on the remote CPU
 	 * if we are unlucky enough (this seems very unlikely).
-- 
2.55.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH net v7] net: stop defer_count outliving the deferred-free list
  2026-10-29 21:11 [PATCH net v7] net: stop defer_count outliving the deferred-free list Joseph Kain
@ 2026-10-29 21:13 ` netdev-bot+sinfo
  2026-10-29 21:21   ` Joseph Kain
  0 siblings, 1 reply; 3+ messages in thread
From: netdev-bot+sinfo @ 2026-10-29 21:13 UTC (permalink / raw)
  To: Joseph Kain
  Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, David S. Miller,
	netdev, Simon Horman, Kuniyuki Iwashima, Stanislav Fomichev,
	Jason Xing, Willem de Bruijn, Mina Almasry, Martin Karsten,
	Jiayuan Chen, linux-kernel

Hi!

This is an automated message. This series looks like a fix, but its
commit messages seem to be missing some information:

 - How the issue was discovered, e.g. hit in production, hit during
   development, syzbot report, manual code inspection, LLM or static
   analysis tool scan.

 - Whether the issue was actually triggered, or is only theoretical
   (e.g. found by code inspection). If it was triggered please include
   the symptoms, like the stack trace or error messages.

Please do not repost the series just to address the above. Instead,
reply to this email with the missing information, so that reviewers
can take it into account. If the series needs another revision for
other reasons, please include the information in the commit messages
then.

The evaluation is done by an LLM so it may be wrong, if you think
that is the case please reply and explain.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH net v7] net: stop defer_count outliving the deferred-free list
  2026-10-29 21:13 ` netdev-bot+sinfo
@ 2026-10-29 21:21   ` Joseph Kain
  0 siblings, 0 replies; 3+ messages in thread
From: Joseph Kain @ 2026-10-29 21:21 UTC (permalink / raw)
  To: netdev-bot+sinfo
  Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, David S. Miller,
	netdev, Simon Horman, Kuniyuki Iwashima, Stanislav Fomichev,
	Jason Xing, Willem de Bruijn, Mina Almasry, Martin Karsten,
	Jiayuan Chen, linux-kernel

On Thu, Oct 29, 2026 at 2:13 PM <netdev-bot+sinfo@kernel.org> wrote:
>
> Hi!
>
> This is an automated message. This series looks like a fix, but its
> commit messages seem to be missing some information:
>
>  - How the issue was discovered, e.g. hit in production, hit during
>    development, syzbot report, manual code inspection, LLM or static
>    analysis tool scan.
>
>  - Whether the issue was actually triggered, or is only theoretical
>    (e.g. found by code inspection). If it was triggered please include
>    the symptoms, like the stack trace or error messages.
>
> Please do not repost the series just to address the above. Instead,
> reply to this email with the missing information, so that reviewers
> can take it into account. If the series needs another revision for
> other reasons, please include the information in the commit messages
> then.
>
> The evaluation is done by an LLM so it may be wrong, if you think
> that is the case please reply and explain.


Thanks, both are fair, and I should have carried this over from v6.

Found by manual code inspection, LLM-assisted, while backporting
844c9db7f7f5 ("net: use llist for sd->defer_list") to a 6.1 vendor
kernel.

Not triggered in production. The absorbing state is reachable with no
race at all, and was reproduced deterministically in a VM: set
net.core.skb_defer_max=1, drive cross-CPU receive traffic until
defer_count climbs past the old limit, then restore it.

There is no crash or splat — the failure is silent. On an unpatched
7.3-rc6 kernel defer_count reached 2036497 at the lowered limit and
3995713 after restoring 128, still climbing, and zero skbs were queued
over the following 794847 skb_attempt_defer_free() calls: deferred
freeing was off for that (cpu, node) and cross-CPU frees fell back to
the page allocator. With this patch the counter peaks at 1, returns to
0, and 4282 purges were requested over 797687 calls.

If another revision is needed for other reasons I will fold this into
the commit message.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-29 21:22 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-29 21:11 [PATCH net v7] net: stop defer_count outliving the deferred-free list Joseph Kain
2026-10-29 21:13 ` netdev-bot+sinfo
2026-10-29 21:21   ` Joseph Kain

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®