Re: [PATCH v3 0/7] mm/page_owner: add bpf_iter and kfuncs

From: Alexei Starovoitov

Date: Sat Oct 24 2026 - 15:09:43 EST


On Sat, Oct 24, 2026 at 10:19 AM zhen.ni <zhen.ni@xxxxxxxxxxxx> wrote:
> For this one node alone, about 97% of spanned is holes. With
> bpf_for(pfn, start, end) plus a bpf_page_owner_read() per iteration,
> that is at least 16,712,944 kfunc calls, and bpf_for has no scheduling
> point inside, and all of them are wasted work. The gap grows with memory

Right. spanned includes the holes. So don't pass them.
/sys/devices/system/memory/ has memoryN only for present blocks.
/sys/devices/system/node/nodeN/ links to the blocks of that node.
/proc/iomem has "System RAM" ranges.
523024 pages in a 32G node looks like 64K pages.
Then the whole 256G box is 4M pfns.
When a hole is passed anyway the call ends at !online_section() in
pfn_to_online_page(). /proc/kpageflags does that plus put_user()
for every pfn, holes included.
Syscall progs run under migrate_disable() only.

> front. The spanned of this node is already 17.23M, so a single bpf_for
> cannot cover it; you have to split it into N chunks and poll, with the
> chunking state kept in a prog map, i.e. a loop nested in a loop.

The loop over chunks is in user space. One bpf_prog_test_run_opts()
per range with start and nr in ctx_in. No map, no nested loop.

> for 52-bit PA. A 32-bit PFN range will overflow here.

The snippet was:
bpf_for(i, 0, ctx->nr) {
pfn = ctx->start + i;
i is an offset within the chunk. start and pfn are 64-bit.

> Solving all of this requires yet another, more complex kfunc—and it
> looks increasingly like bpf iter. So why not just use the iter?

Nothing of the above needs kernel code.
v3 is +474 -83 lines on the kernel side. The diff I sent is +55 -1
and it doesn't touch the debugfs path.