On 2024/3/7 7:59, Mina Almasry wrote: ... > > int skb_pp_cow_data(struct page_pool *pool, struct sk_buff **pskb, > diff --git a/net/core/skbuff.c b/net/core/skbuff.c > index 1f918e602bc4..6d234faa9d9e 100644 > --- a/net/core/skbuff.c > +++ b/net/core/skbuff.c > @@ -1006,6 +1006,21 @@ int skb_cow_data_for_xdp(struct page_pool *pool, struct sk_buff **pskb, > EXPORT_SYMBOL(skb_cow_data_for_xdp); > > #if IS_ENABLED(CONFIG_PAGE_POOL) > +bool napi_pp_get_page(struct page *page) > +{ > + > + struct page *head_page; > + > + head_page = compound_head(page); > + > + if (!is_pp_page(page)) I would use the head_page for is_pp_page(), I am not sure it matters that much, but I believe it is the precedent. Maybe do the below and remove head_page varible: page = compound_head(page); > + return false; > + > + page_pool_ref_page(head_page); > + return true; > +} > +EXPORT_SYMBOL(napi_pp_get_page); > + ... > - > static void skb_kfree_head(void *head, unsigned int end_offset) > { > if (end_offset == SKB_SMALL_HEAD_HEADROOM) > @@ -4199,7 +4183,7 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen) > to++; > > } else { > - __skb_frag_ref(fragfrom); > + __skb_frag_ref(fragfrom, skb->pp_recycle); > skb_frag_page_copy(fragto, fragfrom); > skb_frag_off_copy(fragto, fragfrom); > skb_frag_size_set(fragto, todo); > @@ -4849,7 +4833,7 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, > } > > *nskb_frag = (i < 0) ? skb_head_frag_to_page_desc(frag_skb) : *frag; > - __skb_frag_ref(nskb_frag); > + __skb_frag_ref(nskb_frag, nskb->pp_recycle); > size = skb_frag_size(nskb_frag); > > if (pos < offset) { > @@ -5980,10 +5964,8 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from, > /* if the skb is not cloned this does nothing > * since we set nr_frags to 0. > */ > - if (skb_pp_frag_ref(from)) { I guess it worth mentioning that skb->pp_recycle is only checked once, and skb->pp_recycle is checked for every frag after this patch. > - for (i = 0; i < from_shinfo->nr_frags; i++) > - __skb_frag_ref(&from_shinfo->frags[i]); > - } > + for (i = 0; i < from_shinfo->nr_frags; i++) > + __skb_frag_ref(&from_shinfo->frags[i], from->pp_recycle); > > to->truesize += delta; > to->len += len; >