xref: /linux-6.15/include/linux/skbuff_ref.h (revision ff39eefd)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  *	Skb ref helpers.
4  *
5  */
6 
7 #ifndef _LINUX_SKBUFF_REF_H
8 #define _LINUX_SKBUFF_REF_H
9 
10 #include <linux/skbuff.h>
11 #include <net/page_pool/helpers.h>
12 
13 #ifdef CONFIG_PAGE_POOL
14 static inline bool is_pp_page(struct page *page)
15 {
16 	return (page->pp_magic & ~0x3UL) == PP_SIGNATURE;
17 }
18 
19 static inline bool napi_pp_get_page(struct page *page)
20 {
21 	page = compound_head(page);
22 
23 	if (!is_pp_page(page))
24 		return false;
25 
26 	page_pool_ref_page(page);
27 	return true;
28 }
29 #endif
30 
31 static inline void skb_page_ref(struct page *page, bool recycle)
32 {
33 #ifdef CONFIG_PAGE_POOL
34 	if (recycle && napi_pp_get_page(page))
35 		return;
36 #endif
37 	get_page(page);
38 }
39 
40 /**
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.
44  *
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.
48  */
49 static inline void __skb_frag_ref(skb_frag_t *frag, bool recycle)
50 {
51 	skb_page_ref(skb_frag_page(frag), recycle);
52 }
53 
54 /**
55  * skb_frag_ref - take an addition reference on a paged fragment of an skb.
56  * @skb: the buffer
57  * @f: the fragment offset.
58  *
59  * Takes an additional reference on the @f'th paged fragment of @skb.
60  */
61 static inline void skb_frag_ref(struct sk_buff *skb, int f)
62 {
63 	__skb_frag_ref(&skb_shinfo(skb)->frags[f], skb->pp_recycle);
64 }
65 
66 bool napi_pp_put_page(struct page *page);
67 
68 static inline void
69 skb_page_unref(struct page *page, bool recycle)
70 {
71 #ifdef CONFIG_PAGE_POOL
72 	if (recycle && napi_pp_put_page(page))
73 		return;
74 #endif
75 	put_page(page);
76 }
77 
78 /**
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
82  *
83  * Releases a reference on the paged fragment @frag
84  * or recycles the page via the page_pool API.
85  */
86 static inline void __skb_frag_unref(skb_frag_t *frag, bool recycle)
87 {
88 	skb_page_unref(skb_frag_page(frag), recycle);
89 }
90 
91 /**
92  * skb_frag_unref - release a reference on a paged fragment of an skb.
93  * @skb: the buffer
94  * @f: the fragment offset
95  *
96  * Releases a reference on the @f'th paged fragment of @skb.
97  */
98 static inline void skb_frag_unref(struct sk_buff *skb, int f)
99 {
100 	struct skb_shared_info *shinfo = skb_shinfo(skb);
101 
102 	if (!skb_zcopy_managed(skb))
103 		__skb_frag_unref(&shinfo->frags[f], skb->pp_recycle);
104 }
105 
106 #endif	/* _LINUX_SKBUFF_REF_H */
107