[PATCH net-next v1 0/6] net: unify symmetric netmem and page_pool refcounting
From: Mina Almasry
Date: Sat Oct 10 2026 - 04:40:46 EST
netmems (pages and net_iovs) have two independent refcounts: a non-pp
refcount (page._refcount or binding->ref) governing backing memory
lifetime, and pp_ref_count governing recycling within a page_pool while
page_pool holds a single backing non-pp reference. SKBs with
pp_recycle=1 own pp_ref_count references on page_pool fragments; SKBs
with pp_recycle=0 own non-pp references.
Core helpers currently mix these two refcounts asymmetrically:
skb_frag_ref() always increments the non-pp refcount via get_netmem(),
whereas skb_frag_unref() decrements pp_ref_count when skb->pp_recycle
is set. Any path that refs a fragment on a pp_recycle=1 SKB (or unrefs
with a hardcoded recycle=false) increments one counter and decrements
the other, leaking the backing memory while underflowing pp_ref_count
(e.g., IP-TFS [1], skb_split(), skb_shift(), and cloned SKB uncloning).
Unclear core APIs also led drivers and ULPs to open-code pp_ref_count
manipulations or add one-off helpers like skb_pp_frag_ref().
Unify fragment refcounting into symmetric pairs where each layer clearly
specifies which refcount it touches:
- Non-PP refcount: get/put_page(), get/put_net_iov(), get/put_netmem()
- PP refcount: napi_pp_get/put_page()
- SKB netmem: skb_netmem_ref/unref(netmem, recycle)
- SKB fragment: skb_frag_ref/unref(skb, f)
[1] https://lore.kernel.org/netdev/xfrm-iptfs-pp_ref_count-underflow-v4-1-912fa72106f0@xxxxxxxxxxx/
Mina Almasry (6):
netmem: rename __get/__put_netmem() to get/put_net_iov()
net: skbuff: add napi_pp_get_page() and use it in tcp_recvmsg_dmabuf()
net: skbuff: replace skb_page_unref() and __skb_frag_unref() with
skb_netmem_unref()
net: skbuff: replace __skb_frag_ref() with symmetric skb_netmem_ref()
net: skbuff: use skb_frag_ref() in skb_try_coalesce()
net: kunit: test netmem, page_pool, and skb frag refcounting
.../chelsio/inline_crypto/ch_ktls/chcr_ktls.c | 2 +-
drivers/net/ethernet/marvell/sky2.c | 2 +-
drivers/net/ethernet/mellanox/mlx4/en_rx.c | 2 +-
drivers/net/ethernet/sun/cassini.c | 4 +-
drivers/net/veth.c | 2 +-
include/linux/skbuff_ref.h | 64 +-
include/net/netmem.h | 24 +-
net/core/net_test.c | 747 ++++++++++++++++++
net/core/skbuff.c | 145 ++--
net/ipv4/esp4.c | 4 +-
net/ipv4/tcp.c | 6 +-
net/ipv6/esp6.c | 4 +-
net/tls/tls_device.c | 2 +-
net/tls/tls_device_fallback.c | 2 +-
net/tls/tls_strp.c | 2 +-
net/xfrm/xfrm_iptfs.c | 3 +-
16 files changed, 900 insertions(+), 115 deletions(-)
base-commit: d8674294aefef02266c4d47ad10131f1bffbe534
--
2.56.0.385.gd3acb90ef8-goog