| 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 | |
| 12 | /** |
| 13 | * __skb_frag_ref - take an addition reference on a paged fragment. |
| 14 | * @frag: the paged fragment |
| 15 | * |
| 16 | * Takes an additional reference on the paged fragment @frag. |
| 17 | */ |
| 18 | static inline void __skb_frag_ref(skb_frag_t *frag) |
| 19 | { |
| 20 | get_netmem(netmem: skb_frag_netmem(frag)); |
| 21 | } |
| 22 | |
| 23 | /** |
| 24 | * skb_frag_ref - take an addition reference on a paged fragment of an skb. |
| 25 | * @skb: the buffer |
| 26 | * @f: the fragment offset. |
| 27 | * |
| 28 | * Takes an additional reference on the @f'th paged fragment of @skb. |
| 29 | */ |
| 30 | static inline void skb_frag_ref(struct sk_buff *skb, int f) |
| 31 | { |
| 32 | __skb_frag_ref(frag: &skb_shinfo(skb)->frags[f]); |
| 33 | } |
| 34 | |
| 35 | bool napi_pp_put_page(netmem_ref netmem); |
| 36 | |
| 37 | static inline void skb_page_unref(netmem_ref netmem, bool recycle) |
| 38 | { |
| 39 | #ifdef CONFIG_PAGE_POOL |
| 40 | if (recycle && napi_pp_put_page(netmem)) |
| 41 | return; |
| 42 | #endif |
| 43 | put_netmem(netmem); |
| 44 | } |
| 45 | |
| 46 | /** |
| 47 | * __skb_frag_unref - release a reference on a paged fragment. |
| 48 | * @frag: the paged fragment |
| 49 | * @recycle: recycle the page if allocated via page_pool |
| 50 | * |
| 51 | * Releases a reference on the paged fragment @frag |
| 52 | * or recycles the page via the page_pool API. |
| 53 | */ |
| 54 | static inline void __skb_frag_unref(skb_frag_t *frag, bool recycle) |
| 55 | { |
| 56 | skb_page_unref(netmem: skb_frag_netmem(frag), recycle); |
| 57 | } |
| 58 | |
| 59 | /** |
| 60 | * skb_frag_unref - release a reference on a paged fragment of an skb. |
| 61 | * @skb: the buffer |
| 62 | * @f: the fragment offset |
| 63 | * |
| 64 | * Releases a reference on the @f'th paged fragment of @skb. |
| 65 | */ |
| 66 | static inline void skb_frag_unref(struct sk_buff *skb, int f) |
| 67 | { |
| 68 | struct skb_shared_info *shinfo = skb_shinfo(skb); |
| 69 | |
| 70 | if (!skb_zcopy_managed(skb)) |
| 71 | __skb_frag_unref(frag: &shinfo->frags[f], recycle: skb->pp_recycle); |
| 72 | } |
| 73 | |
| 74 | #endif /* _LINUX_SKBUFF_REF_H */ |
| 75 | |