From: Zhen Ni <zhen.ni@easystack.cn>
To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
eddyz87@gmail.com, memxor@gmail.com, martin.lau@linux.dev,
song@kernel.org, yonghong.song@linux.dev, jolsa@kernel.org,
emil@etsalapatis.com, ihor.solodrai@linux.dev,
akpm@linux-foundation.org, vbabka@kernel.org, surenb@google.com,
mhocko@suse.com, brendan.jackman@linux.dev, hannes@cmpxchg.org,
ziy@nvidia.com, shuah@kernel.org
Cc: bpf@vger.kernel.org, linux-mm@kvack.org,
linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org,
Zhen Ni <zhen.ni@easystack.cn>
Subject: [PATCH v2 4/6] mm/page_owner: record the NUMA node in the scan cursor
Date: Tue, 13 Oct 2026 20:21:23 +0800 [thread overview]
Message-ID: <20261013122125.843451-5-zhen.ni@easystack.cn> (raw)
In-Reply-To: <20261013122125.843451-1-zhen.ni@easystack.cn>
Compute the page's NUMA node in page_owner_next_eligible() while the
page is still valid, and store it in scan->nid.
The debugfs nid filter reads scan->nid instead of recomputing it, and a
BPF program iterating the cursor reads the node straight from scan->nid.
Resolve nid at scan time to avoid dereferencing a possibly-unmapped page.
Keep it in the transient scan cursor rather than struct page_owner, so
nid does not add per-page memory overhead.
Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
---
Changes in v2:
- Removes the v1 get_nid() kfunc. The node is now stored in scan->nid.
v1: https://lore.kernel.org/linux-mm/20261009112308.240769-5-zhen.ni@easystack.cn/
---
mm/page_owner.c | 28 ++++++++++++++++------------
mm/page_owner.h | 1 +
mm/page_owner_iter.c | 5 ++++-
3 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/mm/page_owner.c b/mm/page_owner.c
index 617346a4ab22..113e4e7e0b3a 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -711,6 +711,19 @@ void __dump_page_owner(const struct page *page)
page_ext_put(page_ext);
}
+/*
+ * NUMA node of @page, bypassing PF_POISONED_CHECK() in page_to_nid() to
+ * avoid VM_BUG_ON on poisoned pages; -1 for poisoned pages.
+ */
+static int page_owner_get_nid(struct page *page)
+{
+ memdesc_flags_t page_flags = READ_ONCE(page->flags);
+
+ if (page_flags.f == PAGE_POISON_PATTERN)
+ return -1;
+ return memdesc_nid(&page_flags);
+}
+
/*
* Advance @scan to the next page eligible for page_owner output.
* On a hit, fill scan->pfn/page/po_snap and return true; the caller
@@ -782,6 +795,7 @@ bool page_owner_next_eligible(struct page_owner_scan *scan)
if (!scan->po_snap.handle)
goto ext_put_continue;
+ scan->nid = page_owner_get_nid(page);
page_ext_put(page_ext);
return true;
@@ -810,18 +824,8 @@ read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos)
/* Find an allocated page */
while (page_owner_next_eligible(&scan)) {
if (state->nid_filter_enabled) {
- int nid;
- memdesc_flags_t page_flags =
- READ_ONCE(scan.page->flags);
-
- /*
- * Bypass PF_POISONED_CHECK() in page_to_nid() to avoid
- * VM_BUG_ON when accessing poisoned pages.
- */
- if (page_flags.f == PAGE_POISON_PATTERN)
- goto skip_continue;
- nid = memdesc_nid(&page_flags);
- if (!node_isset(nid, state->nid_filter))
+ if (scan.nid < 0 ||
+ !node_isset(scan.nid, state->nid_filter))
goto skip_continue;
}
diff --git a/mm/page_owner.h b/mm/page_owner.h
index fda83be69275..e8e52d22abed 100644
--- a/mm/page_owner.h
+++ b/mm/page_owner.h
@@ -36,6 +36,7 @@ struct page_owner_scan {
unsigned long pfn;
struct page *page;
struct page_owner po_snap;
+ int nid;
};
bool page_owner_next_eligible(struct page_owner_scan *scan);
diff --git a/mm/page_owner_iter.c b/mm/page_owner_iter.c
index ac7e69ba0cef..a2b90c874852 100644
--- a/mm/page_owner_iter.c
+++ b/mm/page_owner_iter.c
@@ -13,10 +13,12 @@ struct bpf_iter__page_owner {
__bpf_md_ptr(struct page *, page);
__bpf_md_ptr(struct page_owner *, po);
u64 pfn;
+ int nid;
};
DEFINE_BPF_ITER_FUNC(page_owner, struct bpf_iter_meta *meta,
- struct page *page, struct page_owner *po, u64 pfn)
+ struct page *page, struct page_owner *po, u64 pfn,
+ int nid)
static void *page_owner_seq_start(struct seq_file *seq, loff_t *posp)
{
@@ -54,6 +56,7 @@ static int page_owner_prog_seq_show(struct bpf_prog *prog,
/* @po: hit-time snapshot, no RCU window needed. */
ctx.po = &scan->po_snap;
ctx.pfn = scan->pfn;
+ ctx.nid = scan->nid;
}
return bpf_iter_run_prog(prog, &ctx);
--
2.20.1
next prev parent reply other threads:[~2026-10-13 12:21 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-13 12:21 [PATCH v2 0/6] mm/page_owner: add bpf_iter and kfuncs Zhen Ni
2026-10-13 12:21 ` [PATCH v2 1/6] mm/page_owner: extract page_owner_next_eligible() from read loop Zhen Ni
2026-10-13 12:21 ` [PATCH v2 2/6] mm/page_owner: add bpf_iter target "page_owner" Zhen Ni
2026-10-13 13:51 ` bot+bpf-ci
2026-10-13 12:21 ` [PATCH v2 3/6] mm/page_owner: add open-coded page_owner iterator Zhen Ni
2026-10-13 12:49 ` sashiko-bot
2026-10-13 13:51 ` bot+bpf-ci
2026-10-13 12:21 ` Zhen Ni [this message]
2026-10-13 12:36 ` [PATCH v2 4/6] mm/page_owner: record the NUMA node in the scan cursor sashiko-bot
2026-10-13 12:21 ` [PATCH v2 5/6] mm/page_owner: add bpf_page_owner_get_memcg_info() kfunc Zhen Ni
2026-10-13 12:49 ` sashiko-bot
2026-10-13 12:21 ` [PATCH v2 6/6] selftests/bpf: add tests for the page_owner bpf_iter target Zhen Ni
2026-10-13 12:38 ` sashiko-bot
2026-10-13 17:17 ` [PATCH v2 0/6] mm/page_owner: add bpf_iter and kfuncs Zi Yan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261013122125.843451-5-zhen.ni@easystack.cn \
--to=zhen.ni@easystack.cn \
--cc=akpm@linux-foundation.org \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=brendan.jackman@linux.dev \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=hannes@cmpxchg.org \
--cc=ihor.solodrai@linux.dev \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=mhocko@suse.com \
--cc=shuah@kernel.org \
--cc=song@kernel.org \
--cc=surenb@google.com \
--cc=vbabka@kernel.org \
--cc=yonghong.song@linux.dev \
--cc=ziy@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.