linux/include/net
Toke Høiland-Jørgensen ee62ce7a1d page_pool: Track DMA-mapped pages and unmap them when destroying the pool
When enabling DMA mapping in page_pool, pages are kept DMA mapped until
they are released from the pool, to avoid the overhead of re-mapping the
pages every time they are used. This causes resource leaks and/or
crashes when there are pages still outstanding while the device is torn
down, because page_pool will attempt an unmap through a non-existent DMA
device on the subsequent page return.

To fix this, implement a simple tracking of outstanding DMA-mapped pages
in page pool using an xarray. This was first suggested by Mina[0], and
turns out to be fairly straight forward: We simply store pointers to
pages directly in the xarray with xa_alloc() when they are first DMA
mapped, and remove them from the array on unmap. Then, when a page pool
is torn down, it can simply walk the xarray and unmap all pages still
present there before returning, which also allows us to get rid of the
get/put_device() calls in page_pool. Using xa_cmpxchg(), no additional
synchronisation is needed, as a page will only ever be unmapped once.

To avoid having to walk the entire xarray on unmap to find the page
reference, we stash the ID assigned by xa_alloc() into the page
structure itself, using the upper bits of the pp_magic field. This
requires a couple of defines to avoid conflicting with the
POINTER_POISON_DELTA define, but this is all evaluated at compile-time,
so does not affect run-time performance. The bitmap calculations in this
patch gives the following number of bits for different architectures:

- 23 bits on 32-bit architectures
- 21 bits on PPC64 (because of the definition of ILLEGAL_POINTER_VALUE)
- 32 bits on other 64-bit architectures

Stashing a value into the unused bits of pp_magic does have the effect
that it can make the value stored there lie outside the unmappable
range (as governed by the mmap_min_addr sysctl), for architectures that
don't define ILLEGAL_POINTER_VALUE. This means that if one of the
pointers that is aliased to the pp_magic field (such as page->lru.next)
is dereferenced while the page is owned by page_pool, that could lead to
a dereference into userspace, which is a security concern. The risk of
this is mitigated by the fact that (a) we always clear pp_magic before
releasing a page from page_pool, and (b) this would need a
use-after-free bug for struct page, which can have many other risks
since page->lru.next is used as a generic list pointer in multiple
places in the kernel. As such, with this patch we take the position that
this risk is negligible in practice. For more discussion, see[1].

Since all the tracking added in this patch is performed on DMA
map/unmap, no additional code is needed in the fast path, meaning the
performance overhead of this tracking is negligible there. A
micro-benchmark shows that the total overhead of the tracking itself is
about 400 ns (39 cycles(tsc) 395.218 ns; sum for both map and unmap[2]).
Since this cost is only paid on DMA map and unmap, it seems like an
acceptable cost to fix the late unmap issue. Further optimisation can
narrow the cases where this cost is paid (for instance by eliding the
tracking when DMA map/unmap is a no-op).

The extra memory needed to track the pages is neatly encapsulated inside
xarray, which uses the 'struct xa_node' structure to track items. This
structure is 576 bytes long, with slots for 64 items, meaning that a
full node occurs only 9 bytes of overhead per slot it tracks (in
practice, it probably won't be this efficient, but in any case it should
be an acceptable overhead).

[0] https://lore.kernel.org/all/CAHS8izPg7B5DwKfSuzz-iOop_YRbk3Sd6Y4rX7KBG9DcVJcyWg@mail.gmail.com/
[1] https://lore.kernel.org/r/20250320023202.GA25514@openwall.com
[2] https://lore.kernel.org/r/ae07144c-9295-4c9d-a400-153bb689fe9e@huawei.com

Reported-by: Yonglong Liu <liuyonglong@huawei.com>
Closes: https://lore.kernel.org/r/8743264a-9700-4227-a556-5f931c720211@huawei.com
Fixes: ff7d6b27f8 ("page_pool: refurbish version of page_pool code")
Suggested-by: Mina Almasry <almasrymina@google.com>
Reviewed-by: Mina Almasry <almasrymina@google.com>
Reviewed-by: Jesper Dangaard Brouer <hawk@kernel.org>
Tested-by: Jesper Dangaard Brouer <hawk@kernel.org>
Tested-by: Qiuling Ren <qren@redhat.com>
Tested-by: Yuying Ma <yuma@redhat.com>
Tested-by: Yonglong Liu <liuyonglong@huawei.com>
Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
Link: https://patch.msgid.link/20250409-page-pool-track-dma-v9-2-6a9ef2e0cba8@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-04-14 16:30:29 -07:00
..
9p netfs, 9p: Implement helpers for new write code 2024-05-01 18:07:37 +01:00
bluetooth Bluetooth: MGMT: Add LL Privacy Setting 2025-03-25 15:22:49 -04:00
caif caif: Remove unused cfsrvl_getphyid 2024-10-08 15:33:49 -07:00
iucv net: reformat kdoc return statements 2024-12-09 14:44:59 -08:00
libeth libeth: move idpf_rx_csum_decoded and idpf_rx_extracted 2025-02-14 10:58:08 -08:00
mana RDMA v6.15 merge window pull request 2025-03-29 11:12:28 -07:00
netfilter netfilter pull request 25-03-23 2025-03-25 08:29:13 -07:00
netns udp_tunnel: create a fastpath GRO lookup. 2025-04-08 18:19:41 -07:00
nfc net: nfc: Propagate ISO14443 type A target ATS to userspace via netlink 2024-11-07 10:21:58 +01:00
page_pool page_pool: Track DMA-mapped pages and unmap them when destroying the pool 2025-04-14 16:30:29 -07:00
phonet phonet: Convert phonet_routes.lock to spinlock_t. 2024-10-24 16:03:40 +02:00
sctp Including fixes from netfilter. 2025-04-10 08:52:18 -07:00
tc_act net/sched: Retire ipt action 2024-01-02 12:41:16 +00:00
6lowpan.h
act_api.h net/sched: act_api: unexport tcf_action_dump_1() 2024-10-23 11:43:47 +02:00
addrconf.h ipv6: Add __in6_dev_get_rtnl_net(). 2025-01-20 12:16:04 -08:00
af_ieee802154.h
af_rxrpc.h rxrpc: Allow the app to store private data on peer structs 2025-03-10 09:47:15 +00:00
af_unix.h unix: fix up for "apparmor: add fine grained af_unix mediation" 2025-03-26 09:31:18 -07:00
af_vsock.h Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2024-08-15 17:18:52 -07:00
ah.h
amt.h
arp.h
atmclip.h
ax25.h ax25: Remove broken autobind 2025-03-24 10:26:53 +00:00
ax88796.h
bareudp.h
bond_3ad.h bonding: Correct spelling in headers 2024-08-26 09:37:22 -07:00
bond_alb.h bonding: Correct spelling in headers 2024-08-26 09:37:22 -07:00
bond_options.h bonding: add ns target multicast address to slave device 2024-11-14 11:16:28 +01:00
bonding.h bonding: check xdp prog when set bond mode 2025-03-25 08:00:09 -07:00
bpf_sk_storage.h
busy_poll.h net: gro: decouple GRO from the NAPI layer 2025-02-27 14:03:14 +01:00
calipso.h move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
cfg80211-wext.h
cfg80211.h wifi: cfg80211: expose cfg80211_chandef_get_width() 2025-03-12 09:50:24 +01:00
cfg802154.h mac802154: fix llsec key resources release in mac802154_llsec_key_del 2024-03-06 21:01:26 +01:00
checksum.h net: checksum: Move from32to16() to generic header 2024-10-30 15:29:59 +01:00
cipso_ipv4.h move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
cls_cgroup.h
codel_impl.h
codel_qdisc.h
codel.h
compat.h
datalink.h
dcbevent.h
dcbnl.h
devlink.h devlink: add devl guard 2025-01-16 13:04:58 -08:00
dropreason-core.h tcp: add LINUX_MIB_PAWS_TW_REJECTED counter 2025-04-10 18:29:26 -07:00
dropreason.h wifi: mac80211: Drop cooked monitor support 2025-02-11 11:58:17 +01:00
dsa_stubs.h
dsa.h net: dsa: implement get_ts_stats ethtool operation for user ports 2025-01-17 20:01:09 -08:00
dscp.h net: add IEEE 802.1q specific helpers 2024-05-08 10:35:09 +01:00
dsfield.h
dst_cache.h net: Correct spelling in headers 2024-08-26 09:37:23 -07:00
dst_metadata.h net: Add options as a flexible array to struct ip_tunnel_info 2025-02-20 13:17:16 -08:00
dst_ops.h net: fix __dst_negative_advice() race 2024-05-29 17:34:49 -07:00
dst.h net: reformat kdoc return statements 2024-12-09 14:44:59 -08:00
eee.h net: simplify eeecfg_mac_can_tx_lpi 2024-11-13 18:49:50 -08:00
erspan.h net: Correct spelling in headers 2024-08-26 09:37:23 -07:00
esp.h
espintcp.h inet: preserve const qualifier in inet_csk() 2024-04-01 21:27:08 -07:00
ethoc.h
failover.h
fib_notifier.h net: do not acquire rtnl in fib_seq_sum() 2024-10-11 15:35:05 -07:00
fib_rules.h ipv4: fib_rules: Add port mask matching 2025-02-19 18:43:38 -08:00
firewire.h
flow_dissector.h flow_dissector: cleanup FLOW_DISSECTOR_KEY_ENC_FLAGS 2024-07-15 09:14:39 -07:00
flow_offload.h net: sched: propagate "skip_sw" flag to struct flow_cls_common_offload 2024-10-30 17:33:53 -07:00
flow.h
fou.h
fq_impl.h
fq.h
garp.h
gen_stats.h
genetlink.h net: reformat kdoc return statements 2024-12-09 14:44:59 -08:00
geneve.h
gre.h ip_tunnel: convert __be16 tunnel flags to bitmaps 2024-04-01 10:49:28 +01:00
gro_cells.h
gro.h net: gro: expose GRO init/cleanup to use outside of NAPI 2025-02-27 14:03:14 +01:00
gso.h
gtp.h gtp: properly parse extension headers 2024-05-07 01:35:55 +02:00
gue.h
handshake.h
hotdata.h net: introduce per netns packet chains 2025-03-24 13:58:22 -07:00
hwbm.h net: Correct spelling in headers 2024-08-26 09:37:23 -07:00
icmp.h
ieee8021q.h net: add IEEE 802.1q specific helpers 2024-05-08 10:35:09 +01:00
ieee80211_radiotap.h wireless fixes for v6.12-rc5 2024-10-25 10:44:41 +01:00
ieee802154_netdev.h mac802154: Handle association requests from peers 2023-11-20 11:43:03 +01:00
if_inet6.h ipv6: anycast: complete RCU handling of struct ifacaddr6 2024-02-26 18:40:34 -08:00
ife.h
inet_common.h net: change proto and proto_ops accept type 2024-05-13 18:19:09 -06:00
inet_connection_sock.h tcp/dccp: remove icsk->icsk_ack.timeout 2025-03-25 10:34:33 -07:00
inet_dscp.h
inet_ecn.h
inet_frag.h inet: frags: change inet_frag_kill() to defer refcount updates 2025-03-18 13:18:36 +01:00
inet_hashtables.h tcp: Rename tcp_or_dccp_get_hashinfo(). 2025-04-11 18:58:11 -07:00
inet_sock.h sctp: Prepare sctp_v4_get_dst() to dscp_t conversion. 2025-01-06 13:49:38 -08:00
inet_timewait_sock.h tcp: Measure TIME-WAIT reuse delay with millisecond precision 2024-12-11 20:17:33 -08:00
inet6_connection_sock.h tcp/dccp: Remove inet_connection_sock_af_ops.addr2sockaddr(). 2025-03-24 12:10:13 -07:00
inet6_hashtables.h tcp: convert to dev_net_rcu() 2025-03-03 15:44:19 -08:00
inetpeer.h inetpeer: remove create argument of inet_getpeer() 2024-12-17 19:37:00 -08:00
ioam6.h net: ioam6: multicast event 2024-02-28 11:19:41 +00:00
ip_fib.h ipv4: fib: Allocate fib_info_hash[] during netns initialisation. 2025-03-03 15:04:09 -08:00
ip_tunnels.h net: ip_tunnel: Use link netns in newlink() of rtnl_link_ops 2025-02-21 15:28:02 -08:00
ip_vs.h
ip.h net: use netif_disable_lro in ipv6_add_dev 2025-04-03 15:32:08 -07:00
ip6_checksum.h
ip6_fib.h ipv6: use READ_ONCE()/WRITE_ONCE() on fib6_table->fib_seq 2024-10-11 15:35:05 -07:00
ip6_route.h ipv6: fix source address selection with route leak 2024-07-14 07:34:16 -07:00
ip6_tunnel.h ip_tunnel: convert __be16 tunnel flags to bitmaps 2024-04-01 10:49:28 +01:00
ipcomp.h xfrm: ipcomp: Use crypto_acomp interface 2025-03-21 17:36:49 +08:00
ipconfig.h
ipv6_frag.h inet: frags: change inet_frag_kill() to defer refcount updates 2025-03-18 13:18:36 +01:00
ipv6_stubs.h ipv6: udp: constify 'struct net' parameter of socket lookups 2024-08-05 16:27:26 -07:00
ipv6.h ipv6: fix _DEVADD() and _DEVUPD() macros 2025-03-25 07:31:24 -07:00
iw_handler.h Revert "wifi: cfg80211: unexport wireless_nlevent_flush()" 2024-10-09 08:53:01 +02:00
kcm.h kcm: Serialise kcm_sendmsg() for the same socket. 2024-08-19 18:36:12 -07:00
l3mdev.h vrf: use RCU protection in l3mdev_l3_out() 2025-02-10 18:09:09 -08:00
lag.h
lapb.h net: lapb: increase LAPB_HEADER_LEN 2024-12-06 17:43:08 -08:00
llc_c_ac.h
llc_c_ev.h
llc_c_st.h llc: Constify struct llc_conn_state_trans 2024-07-15 08:51:01 -07:00
llc_conn.h
llc_if.h
llc_pdu.h net: Correct spelling in headers 2024-08-26 09:37:23 -07:00
llc_s_ac.h
llc_s_ev.h
llc_s_st.h llc: Constify struct llc_sap_state_trans 2024-07-15 08:51:19 -07:00
llc_sap.h
llc.h
lwtunnel.h inet: fix lwtunnel_valid_encap_type() lock imbalance 2025-03-05 19:16:56 -08:00
mac80211.h wifi: mac80211: add ieee80211_iter_chan_contexts_mtx 2025-02-26 15:48:47 +01:00
mac802154.h move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
macsec.h net: macsec: Add endianness annotations in salt struct 2025-01-20 12:20:42 +00:00
mctp.h net: mctp: Remove unnecessary cast in mctp_cb 2025-03-21 18:18:12 +01:00
mctpdevice.h net: mctp: Expose transport binding identifier via IFLA attribute 2024-11-09 09:04:54 -08:00
mip6.h
mld.h
mpls_iptunnel.h
mpls.h
mptcp.h mptcp: sysctl: add available_path_managers 2025-03-20 10:14:49 +01:00
mrp.h
ncsi.h
ndisc.h ipv6: eliminate ndisc_ops_is_useropt() 2024-08-12 17:23:57 -07:00
neighbour_tables.h neighbour: Create netdev->neighbour association 2024-11-09 13:22:57 -08:00
neighbour.h neighbour: Create netdev->neighbour association 2024-11-09 13:22:57 -08:00
net_debug.h Kbuild updates for v6.13 2024-11-30 13:41:50 -08:00
net_failover.h
net_namespace.h net: introduce per netns packet chains 2025-03-24 13:58:22 -07:00
net_ratelimit.h
net_shaper.h net-shapers: implement NL get operation 2024-10-10 08:30:22 -07:00
net_trackers.h
netdev_lock.h netdev: add "ops compat locking" helpers 2025-04-09 17:01:51 -07:00
netdev_netlink.h net: add granular lock for the netdev netlink socket 2025-03-12 13:32:35 -07:00
netdev_queues.h netdev: depend on netdev->lock for qstats in ops locked drivers 2025-04-09 17:01:52 -07:00
netdev_rx_queue.h net: designate XSK pool pointers in queues as "ops protected" 2025-04-09 17:01:51 -07:00
netevent.h
netkit.h bpf, netkit: Add indirect call wrapper for fetching peer dev 2023-11-20 10:15:16 -08:00
netlabel.h Networking changes for 6.13. 2024-11-21 08:28:08 -08:00
netlink.h netlink: Add nla_put_empty_nest helper 2025-02-17 16:46:03 -08:00
netmem.h net: generalise net_iov chunk owners 2025-02-06 16:27:30 -08:00
netprio_cgroup.h
netrom.h
nexthop.h net: nexthop: Increase weight to u16 2024-08-12 17:50:34 -07:00
nl802154.h ieee802154: Correct spelling in nl802154.h 2024-08-30 22:30:55 +02:00
nsh.h
p8022.h
pfcp.h pfcp: always set pfcp metadata 2024-04-01 10:49:28 +01:00
pie.h
ping.h
pkt_cls.h net: sched: refine software bypass handling in tc_run 2025-01-20 09:21:27 +00:00
pkt_sched.h net/sched: Add helper macros with module names 2024-02-02 10:57:55 -08:00
pptp.h
proto_memory.h net: move sysctl_mem_pcpu_rsv to net_hotdata 2024-04-30 18:46:52 -07:00
protocol.h ipv6: move tcp_ipv6_hash_secret and udp_ipv6_hash_secret to net_hotdata 2024-03-07 21:12:43 -08:00
psample.h net: psample: fix flag being set in wrong skb 2024-07-11 18:11:31 -07:00
psnap.h
raw.h
rawv6.h
red.h net: sched: Correct spelling in headers 2024-08-26 09:37:23 -07:00
regulatory.h net: Correct spelling in headers 2024-08-26 09:37:23 -07:00
request_sock.h tcp: move reqsk_alloc() to inet_connection_sock.c 2024-06-06 15:18:04 +02:00
rose.h
route.h ipv4: add RCU protection to ip4_dst_hoplimit() 2025-02-06 16:14:14 -08:00
rpl.h
rps.h net: rps: remove kfree_rcu_mightsleep() use 2025-04-08 12:30:55 -07:00
rsi_91x.h
rstreason.h net: Retire DCCP socket. 2025-04-11 18:58:10 -07:00
rtnetlink.h rtnetlink: Remove "net" from newlink params 2025-02-21 15:28:03 -08:00
rtnh.h
sch_generic.h net: sched: Fix truncation of offloaded action statistics 2025-02-05 18:32:06 -08:00
scm.h lsm: replace context+len with lsm_context 2024-12-04 14:42:31 -05:00
secure_seq.h net: Retire DCCP socket. 2025-04-11 18:58:10 -07:00
seg6_hmac.h ipv6: sr: restruct ifdefines 2024-05-30 18:29:38 -07:00
seg6_local.h seg6: Use nested-BH locking for seg6_bpf_srh_states. 2024-06-24 16:41:23 -07:00
seg6.h ipv6: sr: restruct ifdefines 2024-05-30 18:29:38 -07:00
selftests.h
slhc_vj.h
smc.h net/smc: add operations to merge sndbuf with peer DMB 2024-04-30 13:24:48 +02:00
snmp.h percpu: use TYPEOF_UNQUAL() in variable declarations 2025-03-16 22:05:53 -07:00
sock_reuseport.h net: core: annotate socks of struct sock_reuseport with __counted_by 2024-08-02 17:16:59 -07:00
sock.h net: Unexport shared functions for DCCP. 2025-04-11 18:58:11 -07:00
Space.h
stp.h
strparser.h strparser: Add read_sock callback 2025-01-29 13:32:08 -08:00
switchdev.h net: bridge: switchdev: Skip MDB replays of deferred events on offload 2024-02-16 09:36:37 +00:00
tc_wrapper.h Merge branch 'x86/bugs' into x86/core, to pick up pending changes before dependent patches 2024-02-14 10:49:37 +01:00
tcp_ao.h net/tcp: Add missing lockdep annotations for TCP-AO hlist traversals 2024-11-03 12:10:11 -08:00
tcp_states.h tcp: Dump bound-only sockets in inet_diag. 2023-12-04 14:45:26 -08:00
tcp.h tcp: add TCP_RFC7323_TW_PAWS drop reason 2025-04-10 18:29:26 -07:00
tcx.h bpf: Fix too early release of tcx_entry 2024-07-08 14:07:31 -07:00
timewait_sock.h tcp: get rid of twsk_unique() 2024-05-09 20:25:55 -07:00
tipc.h
tls_prot.h
tls_toe.h
tls.h tls: block decryption when a rekey is pending 2024-12-16 12:47:29 +00:00
transp_v6.h
tso.h
tun_proto.h
udp_tunnel.h udp: properly deal with xfrm encap and ADDRFORM 2025-04-14 14:29:01 -07:00
udp.h udp_tunnel: create a fastpath GRO lookup. 2025-04-08 18:19:41 -07:00
udplite.h
vsock_addr.h
vxlan.h vxlan: Track reserved bits explicitly as part of the configuration 2024-12-09 14:47:04 -08:00
wext.h
x25.h x25: Correct spelling in x25.h 2024-08-26 09:37:23 -07:00
x25device.h
xdp_priv.h
xdp_sock_drv.h xsk: Add launch time hardware offload support to XDP Tx metadata 2025-02-20 15:13:45 -08:00
xdp_sock.h xsk: Add launch time hardware offload support to XDP Tx metadata 2025-02-20 15:13:45 -08:00
xdp.h xdp: double protect netdev->xdp_flags with netdev->lock 2025-04-09 17:01:52 -07:00
xfrm.h xfrm: check for PMTU in tunnel mode for packet offload 2025-02-21 08:08:15 +01:00
xsk_buff_pool.h xsk: add helper to get &xdp_desc's DMA and meta pointer in one go 2025-02-10 17:54:43 -08:00