mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Stanislav Fomichev <sdf.kernel@gmail.com>
To: Mina Almasry <almasrymina@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>,
	Kaiyuan Zhang <kaiyuanz@google.com>,
	 Eric Dumazet <edumazet@kernel.org>,
	Willem de Bruijn <willemb@google.com>,
	netdev@vger.kernel.org,  linux-kernel@vger.kernel.org,
	Paolo Abeni <pabeni@redhat.com>,
	 Stanislav Fomichev <sdf@fomichev.me>,
	"David S. Miller" <davem@davemloft.net>,
	 Simon Horman <horms@kernel.org>,
	Neal Cardwell <ncardwell@google.com>,
	 Kuniyuki Iwashima <kuniyu@google.com>,
	Bobby Eshleman <bobbyeshleman@meta.com>,
	 Pavel Begunkov <asml.silence@gmail.com>,
	Daniel Borkmann <daniel@iogearbox.net>
Subject: Re: [PATCH net-next v3 2/2] net: prevent mixing frags from different memory providers or bindings
Date: Mon, 9 Nov 2026 09:21:14 -0800	[thread overview]
Message-ID: <avIAOgCLksqW-ZNP@devvm16445.scu0.facebook.com> (raw)
In-Reply-To: <CAHS8izNXwhTybUHk3Zkh-cmp9CXz2m9kXt-NoB2huu5co1rGAg@mail.gmail.com>

On 11/07, Mina Almasry wrote:
> On Fri, Nov 6, 2026 at 2:22 PM Stanislav Fomichev <sdf.kernel@gmail.com> wrote:
> >
> > On 11/06, Mina Almasry wrote:
> > > On Thu, Nov 5, 2026 at 8:59 AM Stanislav Fomichev <sdf.kernel@gmail.com> wrote:
> > > > > +static inline void *skb_net_iov_provider(const struct sk_buff *skb)
> > > > > +{
> > > > > +     struct net_iov *niov;
> > > > > +
> > > >
> > > > [..]
> > > >
> > > > > +     if (!skb_has_net_iovs(skb) || !skb_shinfo(skb)->nr_frags)
> > > > > +             return NULL;
> > > >
> > > > (a few nits/questions)
> > > >
> > > > Why !skb_has_net_iovs is not enough? (and if !nr_frags is required,
> > > > maybe fold it into skb_has_net_iovs?)
> > > >
> > >
> > > Well skb_has_net_iovs only checks skb->unreadable, which is not
> > > actually enough. The skb doesn't necessarily have net_iovs if it's
> > > unreadable, it technically could be that it has no frags, right?
> > >
> > > Technically we should never have the edge case where
> > > skb->unreadable==true && skb_shinfo->nr_frags==0, but I don't think
> > > the code is careful about that today, and I don't know that I want to
> > > do a global refactor everywhere we remove frags, which skb-> flags
> > > need to be updated.
> > >
> > > but you're right that it can be folded.
> >
> > Not sure I'm buying that, but happy to look again if you disagree. I think
> > the only way to make an skb unreadable right now is to add at least
> > one niov frag? Don't think this is (ever?) gonna change? What does
> > and unreadable skb without frags even means?
> 
> I have no doubt that we set skb->unreadable correctly when we add an
> unreadable frag. I have doubt that we unset it correctly when we
> remove the last unreadable frag (or we do it correctly for other skb
> flags like pfmemalloc). If you can trust it, my LLM confirmed my
> suspicion:
> 
> ```
>   1. skb->pfmemalloc is NEVER cleared (or recomputed) when nr_frags
> becomes 0 on an sk_buff—and isn't even propagated in skb_split() /
> skb_shift():
>       • None of ___pskb_trim(), __pskb_pull_tail(), skb_split(),
> skb_shift(), skb_condense(), gro_pull_from_frag0(), or
> __pskb_trim_head() touch skb->pfmemalloc.
>       • Why it's fundamentally broken to just clear skb->pfmemalloc =
> 0 on nr_frags == 0: Unlike struct xdp_buff (which has a separate
> XDP_FLAGS_FRAGS_PF_MEMALLOC flag that BPF helpers clear via
>       xdp_buff_clear_frag_pfmemalloc() in filter.c:4441-4444 and
> filter.c:12740-12743 when !sinfo->nr_frags), struct sk_buff has a
> single sticky skb->pfmemalloc:1 bit shared by both linear skb->head
>       (skbuff.c:515-885) and frags[] (skbuff.h:2631-2632). Clearing
> skb->pfmemalloc when nr_frags == 0 would wrongly clear pfmemalloc when
> skb->head itself was allocated from PFMEMALLOC reserves.
>   2. skb->unreadable is cleared in some nr_frags -> 0 paths, but still
> missed in a few others:
>       • Unlike pfmemalloc, skb->unreadable only applies to frags[] /
> frag_list (linear skb->head is always CPU-readable).
>       • Where we DO clear skb->unreadable when nr_frags == 0:
>           • ___pskb_trim() (skbuff.c:2810-2811): if
> (!skb_shinfo(skb)->nr_frags && !skb_has_frag_list(skb))
> skb->unreadable = 0;
>           • skb_split_inside_header(), skb_split_no_header(), and
> skb_shift() (skbuff.c:4228-4454): cleared by Patch 1/2 in this series.
>       • Where nr_frags can drop to 0 and skb->unreadable is NOT cleared:
>           • pskb_carve_inside_nonlinear() (skbuff.c:7139-7167): if
> pskb_extract() carves past all frags[] (k == 0, e.g., into frag_list),
> shinfo->nr_frags = 0 on the clone without clearing skb->unreadable (if
>           !skb_has_frag_list(skb) or if the remaining frag_list is readable).
>           • __pskb_trim_head() (tcp_output.c:2020): sets
> shinfo->nr_frags = k without checking !k (in practice tcp_trim_head()
> is only called when len < skb->len and skb_headlen(skb) == 0, so k > 0
> unless a
>           frag_list is present).
>           • skb_try_coalesce() (skbuff.c:6365) and skb_gro_receive()
> (gro.c:131): zero from_shinfo->nr_frags = 0 when stealing frags
> without clearing from->unreadable (benign because from is immediately
> freed
>           via stolen-head free).
>           • __pskb_pull_tail() (skbuff.c:2894) and
> gro_pull_from_frag0() (gro.c:416): cannot be entered with
> skb->unreadable == 1 (__pskb_pull_tail() bails on
> !skb_frags_readable(skb), and
>           skb_gro_reset_offset() requires skb_frag_page(frag0) != NULL).
> ```
> 
> I already have 1 ambitious refactor on list to try to remove
> pp_recycle. I think maybe I want to do the nr_frags checks in this
> patch rather than do a global cleanup of setting skb flags correctly
> so that skb->unread is 100% accurate. WDTY?

Hard to say how real the above are and when they happen. But if they
are, let's fix them separately instead of defensively sprinkling nr_frags
checks everywhere?

      reply	other threads:[~2026-11-09 17:21 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-04  4:25 [PATCH net-next v3 0/2] net: prevent mixing incompatible memory providers in skbs Mina Almasry
2026-11-04  4:25 ` [PATCH net-next v3 1/2] net: fix skb->unreadable propagation in skb_split() and skb_shift() Mina Almasry
2026-11-04  4:25 ` [PATCH net-next v3 2/2] net: prevent mixing frags from different memory providers or bindings Mina Almasry
2026-11-05 16:57   ` Stanislav Fomichev
2026-11-06 19:34     ` Mina Almasry
2026-11-06 22:22       ` Stanislav Fomichev
2026-11-07 13:41         ` Mina Almasry
2026-11-09 17:21           ` Stanislav Fomichev [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=avIAOgCLksqW-ZNP@devvm16445.scu0.facebook.com \
    --to=sdf.kernel@gmail.com \
    --cc=almasrymina@google.com \
    --cc=asml.silence@gmail.com \
    --cc=bobbyeshleman@meta.com \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=horms@kernel.org \
    --cc=kaiyuanz@google.com \
    --cc=kuba@kernel.org \
    --cc=kuniyu@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ncardwell@google.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=sdf@fomichev.me \
    --cc=willemb@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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®