1 /* SPDX-License-Identifier: GPL-2.0-or-later */
7 #ifndef _LINUX_SKBUFF_REF_H
8 #define _LINUX_SKBUFF_REF_H
10 #include <linux/skbuff.h>
11 #include <net/page_pool/helpers.h>
13 #ifdef CONFIG_PAGE_POOL
14 static inline bool is_pp_page(struct page *page)
16 return (page->pp_magic & ~0x3UL) == PP_SIGNATURE;
19 static inline bool napi_pp_get_page(struct page *page)
21 page = compound_head(page);
23 if (!is_pp_page(page))
26 page_pool_ref_page(page);
31 static inline void skb_page_ref(struct page *page, bool recycle)
33 #ifdef CONFIG_PAGE_POOL
34 if (recycle && napi_pp_get_page(page))
41 * __skb_frag_ref - take an addition reference on a paged fragment.
42 * @frag: the paged fragment
43 * @recycle: skb->pp_recycle param of the parent skb. False if no parent skb.
45 * Takes an additional reference on the paged fragment @frag. Obtains the
46 * correct reference count depending on whether skb->pp_recycle is set and
47 * whether the frag is a page pool frag.
49 static inline void __skb_frag_ref(skb_frag_t *frag, bool recycle)
51 skb_page_ref(skb_frag_page(frag), recycle);
55 * skb_frag_ref - take an addition reference on a paged fragment of an skb.
57 * @f: the fragment offset.
59 * Takes an additional reference on the @f'th paged fragment of @skb.
61 static inline void skb_frag_ref(struct sk_buff *skb, int f)
63 __skb_frag_ref(&skb_shinfo(skb)->frags[f], skb->pp_recycle);
66 bool napi_pp_put_page(struct page *page);
69 skb_page_unref(struct page *page, bool recycle)
71 #ifdef CONFIG_PAGE_POOL
72 if (recycle && napi_pp_put_page(page))
79 * __skb_frag_unref - release a reference on a paged fragment.
80 * @frag: the paged fragment
81 * @recycle: recycle the page if allocated via page_pool
83 * Releases a reference on the paged fragment @frag
84 * or recycles the page via the page_pool API.
86 static inline void __skb_frag_unref(skb_frag_t *frag, bool recycle)
88 skb_page_unref(skb_frag_page(frag), recycle);
92 * skb_frag_unref - release a reference on a paged fragment of an skb.
94 * @f: the fragment offset
96 * Releases a reference on the @f'th paged fragment of @skb.
98 static inline void skb_frag_unref(struct sk_buff *skb, int f)
100 struct skb_shared_info *shinfo = skb_shinfo(skb);
102 if (!skb_zcopy_managed(skb))
103 __skb_frag_unref(&shinfo->frags[f], skb->pp_recycle);
106 #endif /* _LINUX_SKBUFF_REF_H */