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