1f6d827b1SMina Almasry /* SPDX-License-Identifier: GPL-2.0-or-later */
2f6d827b1SMina Almasry /*
3f6d827b1SMina Almasry * Skb ref helpers.
4f6d827b1SMina Almasry *
5f6d827b1SMina Almasry */
6f6d827b1SMina Almasry
7f6d827b1SMina Almasry #ifndef _LINUX_SKBUFF_REF_H
8f6d827b1SMina Almasry #define _LINUX_SKBUFF_REF_H
9f6d827b1SMina Almasry
10f6d827b1SMina Almasry #include <linux/skbuff.h>
11f6d827b1SMina Almasry
12f6d827b1SMina Almasry /**
13f6d827b1SMina Almasry * __skb_frag_ref - take an addition reference on a paged fragment.
14f6d827b1SMina Almasry * @frag: the paged fragment
15f6d827b1SMina Almasry *
16173e7622SMina Almasry * Takes an additional reference on the paged fragment @frag.
17f6d827b1SMina Almasry */
__skb_frag_ref(skb_frag_t * frag)18173e7622SMina Almasry static inline void __skb_frag_ref(skb_frag_t *frag)
19f6d827b1SMina Almasry {
20173e7622SMina Almasry get_page(skb_frag_page(frag));
21f6d827b1SMina Almasry }
22f6d827b1SMina Almasry
23f6d827b1SMina Almasry /**
24f6d827b1SMina Almasry * skb_frag_ref - take an addition reference on a paged fragment of an skb.
25f6d827b1SMina Almasry * @skb: the buffer
26f6d827b1SMina Almasry * @f: the fragment offset.
27f6d827b1SMina Almasry *
28f6d827b1SMina Almasry * Takes an additional reference on the @f'th paged fragment of @skb.
29f6d827b1SMina Almasry */
skb_frag_ref(struct sk_buff * skb,int f)30f6d827b1SMina Almasry static inline void skb_frag_ref(struct sk_buff *skb, int f)
31f6d827b1SMina Almasry {
32173e7622SMina Almasry __skb_frag_ref(&skb_shinfo(skb)->frags[f]);
33f6d827b1SMina Almasry }
34f6d827b1SMina Almasry
354dec64c5SMina Almasry bool napi_pp_put_page(netmem_ref netmem);
36f6d827b1SMina Almasry
skb_page_unref(netmem_ref netmem,bool recycle)37*9f6b619eSMina Almasry static inline void skb_page_unref(netmem_ref netmem, bool recycle)
38f6d827b1SMina Almasry {
39f6d827b1SMina Almasry #ifdef CONFIG_PAGE_POOL
40*9f6b619eSMina Almasry if (recycle && napi_pp_put_page(netmem))
41f6d827b1SMina Almasry return;
42f6d827b1SMina Almasry #endif
43*9f6b619eSMina Almasry put_page(netmem_to_page(netmem));
44f6d827b1SMina Almasry }
45f6d827b1SMina Almasry
46f6d827b1SMina Almasry /**
47f6d827b1SMina Almasry * __skb_frag_unref - release a reference on a paged fragment.
48f6d827b1SMina Almasry * @frag: the paged fragment
49f6d827b1SMina Almasry * @recycle: recycle the page if allocated via page_pool
50f6d827b1SMina Almasry *
51f6d827b1SMina Almasry * Releases a reference on the paged fragment @frag
52f6d827b1SMina Almasry * or recycles the page via the page_pool API.
53f6d827b1SMina Almasry */
__skb_frag_unref(skb_frag_t * frag,bool recycle)54f6d827b1SMina Almasry static inline void __skb_frag_unref(skb_frag_t *frag, bool recycle)
55f6d827b1SMina Almasry {
56*9f6b619eSMina Almasry skb_page_unref(skb_frag_netmem(frag), recycle);
57f6d827b1SMina Almasry }
58f6d827b1SMina Almasry
59f6d827b1SMina Almasry /**
60f6d827b1SMina Almasry * skb_frag_unref - release a reference on a paged fragment of an skb.
61f6d827b1SMina Almasry * @skb: the buffer
62f6d827b1SMina Almasry * @f: the fragment offset
63f6d827b1SMina Almasry *
64f6d827b1SMina Almasry * Releases a reference on the @f'th paged fragment of @skb.
65f6d827b1SMina Almasry */
skb_frag_unref(struct sk_buff * skb,int f)66f6d827b1SMina Almasry static inline void skb_frag_unref(struct sk_buff *skb, int f)
67f6d827b1SMina Almasry {
68f6d827b1SMina Almasry struct skb_shared_info *shinfo = skb_shinfo(skb);
69f6d827b1SMina Almasry
70f6d827b1SMina Almasry if (!skb_zcopy_managed(skb))
71f6d827b1SMina Almasry __skb_frag_unref(&shinfo->frags[f], skb->pp_recycle);
72f6d827b1SMina Almasry }
73f6d827b1SMina Almasry
74f6d827b1SMina Almasry #endif /* _LINUX_SKBUFF_REF_H */
75