summaryrefslogtreecommitdiff
path: root/include/linux/skbuff_ref.h
AgeCommit message (Collapse)Author
3 daysnetmem: rename get/put_netmem() to netmem_inc/dec_ref()Mina Almasry
Follow the object_action() naming convention for netmem non-page_pool reference helpers by renaming get_netmem() and put_netmem() to netmem_inc_ref() and netmem_dec_ref(). Use netmem_inc_ref() and netmem_dec_ref() rather than netmem_ref() and netmem_unref() because netmem_ref is already a typedef (typedef unsigned long __bitwise netmem_ref). Suggested-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://patch.msgid.link/20261021015558.4124825-3-almasrymina@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
4 daysnet: skbuff: replace __skb_frag_ref() with symmetric skb_netmem_ref()Mina Almasry
Previously, __skb_frag_ref() and skb_frag_ref() unconditionally incremented the non-pp backing refcount via get_netmem(), while skb_frag_unref() decremented pp_ref_count whenever skb->pp_recycle was set. Ref-ing a page_pool fragment into a pp_recycle=1 SKB (or clearing pp_recycle=0 on an uncloned SKB while clones still held pp_recycle=1) leaked the backing non-pp refcount and underflowed pp_ref_count across IP-TFS, skb_split(), skb_shift(), and cloned unclone paths. Replace __skb_frag_ref() with skb_netmem_ref(netmem, recycle) as the exact counterpart to skb_netmem_unref(netmem, recycle): - Keep skb->pp_recycle intact in skb_release_data() so uncloning paths (pskb_expand_head() and pskb_carve_inside_{header,nonlinear}()) keep trading pp_ref_count references symmetrically across clones. - Propagate pp_recycle and call skb_frag_ref() on the destination SKB in __pskb_copy_fclone(), skb_zerocopy(), skb_split(), skb_shift(), and skb_segment(). - Linearize an output segment's existing frags in skb_segment() before attaching frags from a frag_list SKB with a different pp_recycle bit, since each output segment carries a single pp_recycle bit. - Use skb_frag_ref() in xfrm_iptfs, chcr_ktls, and cassini, and call get_netmem() directly in veth and tls_device_fallback where callers explicitly take a raw non-pp reference. Found by code inspection while reviewing the IP-TFS pp_ref_count fix [1] and confirmed with the KUnit tests added later in this series; not observed in production. The xfrm_iptfs, chcr_ktls, cassini, veth, and tls_device_fallback changes are compile-tested only. Link: https://lore.kernel.org/netdev/xfrm-iptfs-pp_ref_count-underflow-v4-1-912fa72106f0@secunet.com/ [1] Cc: Antony Antony <antony.antony@secunet.com> Cc: Stanislav Fomichev <sdf@fomichev.me> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Jesper Dangaard Brouer <hawk@kernel.org> Cc: bpf@vger.kernel.org Assisted-by: LLM Signed-off-by: Mina Almasry <almasrymina@google.com> Tested-by: Antony Antony <antony.antony@secunet.com> Link: https://patch.msgid.link/20261014173945.373295-5-almasrymina@google.com Acked-by: Stanislav Fomichev <sdf@fomichev.me> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysnet: skbuff: replace skb_page_unref() and __skb_frag_unref() with ↵Mina Almasry
skb_netmem_unref() Unreferencing a page_pool fragment with recycle=false decrements the non-pp backing refcount instead of pp_ref_count, underflowing the page refcount when the fragment was owned via page_pool (as on mlx4's RX error path). Having both skb_page_unref() and __skb_frag_unref(frag, recycle) made it easy for callers to pass hardcoded recycle=false on SKB-owned fragments. Replace skb_page_unref() and __skb_frag_unref() with skb_netmem_unref(netmem, recycle), which dispatches to napi_pp_put_page() when recycle is true and put_netmem() otherwise: - Use skb_frag_unref(skb, ...) on SKB-owned fragments in mlx4, sky2, tls_strp, and skb_shift() so unrefs always match skb->pp_recycle. - Use put_netmem() directly in tls_device's destroy_record(), which releases raw non-pp page references outside an SKB. Found by code inspection and confirmed with the KUnit tests added later in this series; not observed in production. The mlx4, sky2, and TLS call-site changes are compile-tested only. Assisted-by: LLM Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://patch.msgid.link/20261014173945.373295-4-almasrymina@google.com Acked-by: Stanislav Fomichev <sdf@fomichev.me> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysnet: skbuff: add napi_pp_get_page() and use it in tcp_recvmsg_dmabuf()Mina Almasry
While napi_pp_put_page() releases a page_pool pp_ref_count reference on a netmem, no symmetric helper existed to acquire one, forcing callers like tcp_recvmsg_dmabuf() to open-code atomic_long_inc() on niov->desc.pp_ref_count. Add napi_pp_get_page() to pair symmetrically with napi_pp_put_page(), and use WARN_ON_ONCE(!napi_pp_get_page(netmem)) in tcp_recvmsg_dmabuf() to match WARN_ON_ONCE(!napi_pp_put_page(netmem)) in tcp_release_user_frags(). Assisted-by: LLM Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://patch.msgid.link/20261014173945.373295-3-almasrymina@google.com Acked-by: Stanislav Fomichev <sdf@fomichev.me> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-01-25net: always inline skb_frag_unref() and __skb_frag_unref()Eric Dumazet
clang is not inlining skb_frag_unref() and __skb_frag_unref() in gro fast path. It also does not inline gro_try_pull_from_frag0(). Using __always_inline fixes this issue, makes the kernel faster _and_ smaller. Also change __skb_frag_ref(), skb_frag_ref() and skb_page_unref() to let them inlined for the last patch in this series. $ scripts/bloat-o-meter -t vmlinux.0 vmlinux.1 add/remove: 2/6 grow/shrink: 1/2 up/down: 218/-511 (-293) Function old new delta gro_pull_from_frag0 - 188 +188 __pfx_gro_pull_from_frag0 - 16 +16 skb_shift 1125 1139 +14 __pfx_skb_frag_unref 16 - -16 __pfx_gro_try_pull_from_frag0 16 - -16 __pfx___skb_frag_unref 16 - -16 __skb_frag_unref 36 - -36 skb_frag_unref 59 - -59 dev_gro_receive 1608 1514 -94 napi_gro_frags 892 771 -121 gro_try_pull_from_frag0 153 - -153 Total: Before=22566192, After=22565899, chg -0.00% Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260122045720.1221017-2-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-05-13net: add get_netmem/put_netmem supportMina Almasry
Currently net_iovs support only pp ref counts, and do not support a page ref equivalent. This is fine for the RX path as net_iovs are used exclusively with the pp and only pp refcounting is needed there. The TX path however does not use pp ref counts, thus, support for get_page/put_page equivalent is needed for netmem. Support get_netmem/put_netmem. Check the type of the netmem before passing it to page or net_iov specific code to obtain a page ref equivalent. For dmabuf net_iovs, we obtain a ref on the underlying binding. This ensures the entire binding doesn't disappear until all the net_iovs have been put_netmem'ed. We do not need to track the refcount of individual dmabuf net_iovs as we don't allocate/free them from a pool similar to what the buddy allocator does for pages. This code is written to be extensible by other net_iov implementers. get_netmem/put_netmem will check the type of the netmem and route it to the correct helper: pages -> [get|put]_page() dmabuf net_iovs -> net_devmem_[get|put]_net_iov() new net_iovs -> new helpers Signed-off-by: Mina Almasry <almasrymina@google.com> Acked-by: Stanislav Fomichev <sdf@fomichev.me> Link: https://patch.msgid.link/20250508004830.4100853-3-almasrymina@google.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2024-09-11net: support non paged skb fragsMina Almasry
Make skb_frag_page() fail in the case where the frag is not backed by a page, and fix its relevant callers to handle this case. Signed-off-by: Mina Almasry <almasrymina@google.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Jakub Kicinski <kuba@kernel.org> Link: https://patch.msgid.link/20240910171458.219195-8-almasrymina@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2024-07-02page_pool: convert to use netmemMina Almasry
Abstract the memory type from the page_pool so we can later add support for new memory types. Convert the page_pool to use the new netmem type abstraction, rather than use struct page directly. As of this patch the netmem type is a no-op abstraction: it's always a struct page underneath. All the page pool internals are converted to use struct netmem instead of struct page, and the page pool now exports 2 APIs: 1. The existing struct page API. 2. The new struct netmem API. Keeping the existing API is transitional; we do not want to refactor all the current drivers using the page pool at once. The netmem abstraction is currently a no-op. The page_pool uses page_to_netmem() to convert allocated pages to netmem, and uses netmem_to_page() to convert the netmem back to pages to pass to mm APIs, Follow up patches to this series add non-paged netmem support to the page_pool. This change is factored out on its own to limit the code churn to this 1 patch, for ease of code review. Signed-off-by: Mina Almasry <almasrymina@google.com> Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> Link: https://patch.msgid.link/20240628003253.1694510-6-almasrymina@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2024-05-03Revert "net: mirror skb frag ref/unref helpers"Mina Almasry
This reverts commit a580ea994fd37f4105028f5a85c38ff6508a2b25. This revert is to resolve Dragos's report of page_pool leak here: https://lore.kernel.org/lkml/20240424165646.1625690-2-dtatulea@nvidia.com/ The reverted patch interacts very badly with commit 2cc3aeb5eccc ("skbuff: Fix a potential race while recycling page_pool packets"). The reverted commit hopes that the pp_recycle + is_pp_page variables do not change between the skb_frag_ref and skb_frag_unref operation. If such a change occurs, the skb_frag_ref/unref will not operate on the same reference type. In the case of Dragos's report, the grabbed ref was a pp ref, but the unref was a page ref, because the pp_recycle setting on the skb was changed. Attempting to fix this issue on the fly is risky. Lets revert and I hope to reland this with better understanding and testing to ensure we don't regress some edge case while streamlining skb reffing. Fixes: a580ea994fd3 ("net: mirror skb frag ref/unref helpers") Reported-by: Dragos Tatulea <dtatulea@nvidia.com> Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://lore.kernel.org/r/20240502175423.2456544-1-almasrymina@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2024-04-11net: mirror skb frag ref/unref helpersMina Almasry
Refactor some of the skb frag ref/unref helpers for improved clarity. Implement napi_pp_get_page() to be the mirror counterpart of napi_pp_put_page(). Implement skb_page_ref() to be the mirror of skb_page_unref(). Improve __skb_frag_ref() to become a mirror counterpart of __skb_frag_unref(). Previously unref could handle pp & non-pp pages, while the ref could only handle non-pp pages. Now both the ref & unref helpers can correctly handle both pp & non-pp pages. Now that __skb_frag_ref() can handle both pp & non-pp pages, remove skb_pp_frag_ref(), and use __skb_frag_ref() instead. This lets us remove pp specific handling from skb_try_coalesce. Additionally, since __skb_frag_ref() can now handle both pp & non-pp pages, a latent issue in skb_shift() should now be fixed. Previously this function would do a non-pp ref & pp unref on potential pp frags (fragfrom). After this patch, skb_shift() should correctly do a pp ref/unref on pp frags. Signed-off-by: Mina Almasry <almasrymina@google.com> Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com> Reviewed-by: Jacob Keller <jacob.e.keller@intel.com> Link: https://lore.kernel.org/r/20240410190505.1225848-3-almasrymina@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2024-04-11net: move skb ref helpers to new headerMina Almasry
Add a new header, linux/skbuff_ref.h, which contains all the skb_*_ref() helpers. Many of the consumers of skbuff.h do not actually use any of the skb ref helpers, and we can speed up compilation a bit by minimizing this header file. Additionally in the later patch in the series we add page_pool support to skb_frag_ref(), which requires some page_pool dependencies. We can now add these dependencies to skbuff_ref.h instead of a very ubiquitous skbuff.h Signed-off-by: Mina Almasry <almasrymina@google.com> Link: https://lore.kernel.org/r/20240410190505.1225848-2-almasrymina@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>