RFC turns AF_XDP UMEM into a page-pool memory provider
Björn Töpel proposes letting zero-copy sockets supply RX buffers through page_pool so modern drivers stop maintaining a second receive path.
Björn Töpel has posted an RFC on the BPF list that would make AF_XDP zero-copy UMEM act as a page-pool memory provider, so drivers no longer need a separate XSK receive allocator beside their normal page_pool path.
Today, AF_XDP zero copy forces every driver to pull xdp_buff_xsk objects from an XSK buffer pool, own their lifetime, and wire a second RX path. Drivers already built on page_pool and the queue management API (the same foundation that supports devmem and io_uring zero-copy receive) must duplicate allocation, DMA sync, recycling, and refill logic just for AF_XDP.
Under the RFC, each aligned 4 KiB UMEM chunk becomes a NET_IOV_XSK net_iov. Binding a zero-copy socket installs that pool as the queue's memory provider. The driver keeps its existing page_pool code. The provider consumes the FILL ring in batches, drops invalid or repeated addresses, and owns RX need-wakeup, keeping NAPI scheduled while FILL has entries and setting the wakeup flag when it is empty.
Readable providers get a new capability so they can back header and regular pools and run XDP, unlike unreadable providers such as devmem and io_uring. Providers can request RX headroom through queue configuration. XSKMAP redirects publish UMEM addresses when every buffer of a frame belongs to the target socket's provider; XDP_PASS and other redirect targets copy into ordinary page-backed memory first so provider buffers never outlive the NAPI that allocated them. TX is unchanged.
The design is intentionally narrow for now: only 4 KiB pages and aligned 4 KiB chunks bind successfully; other layouts get -EOPNOTSUPP. Generic XDP and synthetic queues such as CPUMAP cannot deliver into a provider-backed socket. Classic zero-copy is left alone. The series does not convert existing XSK drivers; it targets page_pool drivers that still lack zero copy. Meta's fbnic is the first driver wired up, including XDP_REDIRECT support and header-split rules so one UMEM frame holds one packet.
Along the way Töpel fixed two related bugs. Generic conversion from an XSK frame into an skb sized the head from the full frame size and could overwrite skb_shared_info on full frames (caught by an AI review agent and covered by a new selftest). fbnic also registered the wrong queue index for XDP, so programs always saw queue 0 and AF_XDP socket lookups failed on non-zero queues.
If accepted, the work would give new page_pool NICs a single RX path for ordinary traffic, devmem, io_uring, and AF_XDP zero copy, at the cost of the layout and redirect limits above.