[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <04e27096-9ace-07eb-aa51-1663714a586d@nbd.name>
Date: Thu, 26 Jan 2023 19:43:22 +0100
From: Felix Fietkau <nbd@....name>
To: Alexander H Duyck <alexander.duyck@...il.com>
Cc: Ilias Apalodimas <ilias.apalodimas@...aro.org>,
netdev@...r.kernel.org, Jesper Dangaard Brouer <hawk@...nel.org>,
"David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
Lorenzo Bianconi <lorenzo@...nel.org>,
linux-kernel@...r.kernel.org, Yunsheng Lin <linyunsheng@...wei.com>
Subject: Re: [PATCH] net: page_pool: fix refcounting issues with fragmented
allocation
On 26.01.23 19:38, Alexander H Duyck wrote:
> Okay, I think that tells me exactly what is going on. Can you give the
> change below a try and see if it solves the problem for you.
>
> I think what is happening is that after you are reassigning the frags
> they are getting merged into GRO frames where the head may have
> pp_recycle set. As a result I think the pages are getting recycled when
> they should be just freed via put_page.
>
> I'm suspecting this wasn't an issue up until now as I don't believe
> there are any that are running in a mixed mode where they have both
> pp_recycle and non-pp_recycle skbs coming from the same device.
>
> diff --git a/net/core/gro.c b/net/core/gro.c
> index 506f83d715f8..4bac7ea6e025 100644
> --- a/net/core/gro.c
> +++ b/net/core/gro.c
> @@ -162,6 +162,15 @@ int skb_gro_receive(struct sk_buff *p, struct
> sk_buff *skb)
> struct sk_buff *lp;
> int segs;
>
> + /* Do not splice page pool based packets w/ non-page pool
> + * packets. This can result in reference count issues as page
> + * pool pages will not decrement the reference count and will
> + * instead be immediately returned to the pool or have frag
> + * count decremented.
> + */
> + if (p->pp_recycle != skb->pp_recycle)
> + return -ETOOMANYREFS;
> +
> /* pairs with WRITE_ONCE() in netif_set_gro_max_size() */
> gro_max_size = READ_ONCE(p->dev->gro_max_size);
>
That works, thanks!
- Felix
Powered by blists - more mailing lists