* [PATCH 0/3] mm/page_owner: add filter infrastructure for compact mode and NUMA filtering
@ 2026-04-17 15:46 Zhen Ni
2026-04-17 15:46 ` [PATCH 1/3] mm/page_owner: add filter infrastructure Zhen Ni
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Zhen Ni @ 2026-04-17 15:46 UTC (permalink / raw)
To: akpm, vbabka
Cc: surenb, mhocko, jackmanb, hannes, ziy, linux-mm, linux-kernel, Zhen Ni
This patch series introduces filtering capabilities to the page_owner
feature to address storage and performance challenges in production
environments.
Problem Statement
=================
In production environments with large memory configurations (e.g., 250GB+),
collecting page_owner information often results in files ranging from
several gigabytes to over 10GB. This creates significant challenges:
1. Storage pressure on production systems
2. Difficulty transferring large files from production environments
3. Post-processing overhead with tools/mm/page_owner_sort.c
The primary contributor to file size is redundant stack trace
information. While the kernel already deduplicates stacks via
stackdepot, page_owner retrieves and stores full stack traces for
each page, only to deduplicate them again during post-processing.
Additionally, in NUMA-aware environments (e.g., DPDK-based cloud
deployments where QEMU processes are bound to specific NUMA nodes),
OOM events are often node-specific rather than system-wide.
Currently, page_owner cannot filter by NUMA node, forcing users to
collect and analyze data for all nodes.
Solution
========
This patch series introduces a flexible filter infrastructure with
two initial filters:
1. **Compact Mode Filter**: Outputs only stack handles instead of
full stack traces. The handle-to-stack mapping can be retrieved
from the existing show_stacks_handles interface. This dramatically
reduces output size while preserving all allocation metadata.
2. **NUMA Node Filter**: Allows filtering pages by specific NUMA node ID,
enabling targeted analysis of memory issues in NUMA-aware deployments.
Implementation
==============
The series is structured as follows:
- Patch 1: Add filter infrastructure (data structures and
debugfs directory)
- Patch 2: Implement compact mode filter
- Patch 3: Implement NUMA node filter
Usage Example
=============
Enable compact mode and filter for NUMA node 2:
# cd /sys/kernel/debug/page_owner_filter/
# echo 1 > compact
# echo 2 > nid
# cat /sys/kernel/debug/page_owner > page_owner_0417.txt
Sample compact mode output:
Page allocated via order 0, mask 0x0(), pid 0, tgid 0 (swapper),
ts 0 ns PFN 0x80000 type Unmovable Block 1024 type Unmovable
Flags 0x23fffe0000000000(node=2|zone=0|lastcpupid=0x1ffff)
handle: 1048577
Page allocated via order 0, mask 0x252000(__GFP_NOWARN|
__GFP_NORETRY|__GFP_COMP|__GFP_THISNODE), pid 0, tgid 0 (swapper),
ts 0 ns PFN 0x80002 type Unmovable Block 1024 type Unmovable
Flags 0x23fffe0000000200(workingset|node=2|zone=0|lastcpupid=0x1ffff)
handle: 1048577
Future Enhancements
==================
The filter infrastructure is designed to be extensible. Potential
future filters could include:
- PID/TGID filtering
- Time range filtering (allocation timestamp windows)
- GFP flag filtering
- Migration type filtering
Testing
=======
Tested on a system with multiple NUMA nodes. Verified that:
- Filters work independently and in combination
- Compact mode output correlates correctly with show_stacks_handles
- Default behavior (filters disabled) remains unchanged
Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
---
Zhen Ni (3):
mm/page_owner: add filter infrastructure
mm/page_owner: add compact mode filter
mm/page_owner: add NUMA node filter
mm/page_owner.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 69 insertions(+), 2 deletions(-)
--
2.20.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/3] mm/page_owner: add filter infrastructure
2026-04-17 15:46 [PATCH 0/3] mm/page_owner: add filter infrastructure for compact mode and NUMA filtering Zhen Ni
@ 2026-04-17 15:46 ` Zhen Ni
2026-04-17 15:46 ` [PATCH 2/3] mm/page_owner: add compact mode filter Zhen Ni
2026-04-17 15:46 ` [PATCH 3/3] mm/page_owner: add NUMA node filter Zhen Ni
2 siblings, 0 replies; 6+ messages in thread
From: Zhen Ni @ 2026-04-17 15:46 UTC (permalink / raw)
To: akpm, vbabka
Cc: surenb, mhocko, jackmanb, hannes, ziy, linux-mm, linux-kernel, Zhen Ni
Add data structure for page_owner filtering functionality and create
debugfs directory for filter controls.
This adds:
- struct page_owner_filter with compact and nid fields
- Static owner_filter instance initialized with default values
- page_owner_filter debugfs directory
The filter infrastructure will be used to add compact mode and NUMA node
filtering capabilities in subsequent commits.
Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
---
mm/page_owner.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/mm/page_owner.c b/mm/page_owner.c
index 8178e0be557f..6811439bf9e4 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -54,6 +54,16 @@ struct stack_print_ctx {
u8 flags;
};
+struct page_owner_filter {
+ bool compact;
+ int nid;
+};
+
+static struct page_owner_filter owner_filter = {
+ .compact = false,
+ .nid = -1,
+};
+
static bool page_owner_enabled __initdata;
DEFINE_STATIC_KEY_FALSE(page_owner_inited);
@@ -973,7 +983,7 @@ DEFINE_SIMPLE_ATTRIBUTE(page_owner_threshold_fops, &page_owner_threshold_get,
static int __init pageowner_init(void)
{
- struct dentry *dir;
+ struct dentry *dir, *filter_dir;
if (!static_branch_unlikely(&page_owner_inited)) {
pr_info("page_owner is disabled\n");
@@ -981,6 +991,9 @@ static int __init pageowner_init(void)
}
debugfs_create_file("page_owner", 0400, NULL, NULL, &page_owner_fops);
+
+ filter_dir = debugfs_create_dir("page_owner_filter", NULL);
+
dir = debugfs_create_dir("page_owner_stacks", NULL);
debugfs_create_file("show_stacks", 0400, dir,
(void *)(STACK_PRINT_FLAG_STACK |
--
2.20.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/3] mm/page_owner: add compact mode filter
2026-04-17 15:46 [PATCH 0/3] mm/page_owner: add filter infrastructure for compact mode and NUMA filtering Zhen Ni
2026-04-17 15:46 ` [PATCH 1/3] mm/page_owner: add filter infrastructure Zhen Ni
@ 2026-04-17 15:46 ` Zhen Ni
2026-04-17 15:55 ` Zi Yan
2026-04-17 15:46 ` [PATCH 3/3] mm/page_owner: add NUMA node filter Zhen Ni
2 siblings, 1 reply; 6+ messages in thread
From: Zhen Ni @ 2026-04-17 15:46 UTC (permalink / raw)
To: akpm, vbabka
Cc: surenb, mhocko, jackmanb, hannes, ziy, linux-mm, linux-kernel, Zhen Ni
Add compact mode functionality to reduce page_owner output size by
printing only the stack handle instead of the full stack trace.
Example output:
Page allocated via order 0, mask 0x42800(GFP_NOWAIT|__GFP_COMP),
pid 1, tgid 1 (systemd), ts 349667370 ns
PFN 0xa00a2 type Unmovable Block 1280 type Unmovable
Flags 0x33fffe0000004124(referenced|lru|active|private|node=3|zone=0|
lastcpupid=0x1ffff)
handle: 17432583
Charged to memcg /
Compact mode significantly reduces output size while preserving all
other page allocation information, making it easier to analyze large
volumes of page owner data.The correspondence between handles and stack
traces can be obtained through the show_stacks_handles interface.
Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
---
mm/page_owner.c | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/mm/page_owner.c b/mm/page_owner.c
index 6811439bf9e4..214b58eef3d8 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -585,7 +585,14 @@ print_page_owner(char __user *buf, size_t count, unsigned long pfn,
migratetype_names[pageblock_mt],
&page->flags);
- ret += stack_depot_snprint(handle, kbuf + ret, count - ret, 0);
+ /* Compact mode: print handle instead of full stack trace */
+ if (READ_ONCE(owner_filter.compact)) {
+ ret += scnprintf(kbuf + ret, count - ret,
+ "handle: %d\n", handle);
+ } else {
+ ret += stack_depot_snprint(handle, kbuf + ret, count - ret, 0);
+ }
+
if (ret >= count)
goto err;
@@ -980,6 +987,24 @@ static int page_owner_threshold_set(void *data, u64 val)
DEFINE_SIMPLE_ATTRIBUTE(page_owner_threshold_fops, &page_owner_threshold_get,
&page_owner_threshold_set, "%llu");
+static int page_owner_compact_get(void *data, u64 *val)
+{
+ *val = READ_ONCE(owner_filter.compact);
+ return 0;
+}
+
+static int page_owner_compact_set(void *data, u64 val)
+{
+ if (val != 0 && val != 1)
+ return -EINVAL;
+ WRITE_ONCE(owner_filter.compact, val);
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(page_owner_compact_fops,
+ &page_owner_compact_get,
+ &page_owner_compact_set, "%lld");
+
static int __init pageowner_init(void)
{
@@ -993,6 +1018,8 @@ static int __init pageowner_init(void)
debugfs_create_file("page_owner", 0400, NULL, NULL, &page_owner_fops);
filter_dir = debugfs_create_dir("page_owner_filter", NULL);
+ debugfs_create_file("compact", 0600, filter_dir, NULL,
+ &page_owner_compact_fops);
dir = debugfs_create_dir("page_owner_stacks", NULL);
debugfs_create_file("show_stacks", 0400, dir,
--
2.20.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/3] mm/page_owner: add NUMA node filter
2026-04-17 15:46 [PATCH 0/3] mm/page_owner: add filter infrastructure for compact mode and NUMA filtering Zhen Ni
2026-04-17 15:46 ` [PATCH 1/3] mm/page_owner: add filter infrastructure Zhen Ni
2026-04-17 15:46 ` [PATCH 2/3] mm/page_owner: add compact mode filter Zhen Ni
@ 2026-04-17 15:46 ` Zhen Ni
2026-04-17 15:58 ` Zi Yan
2 siblings, 1 reply; 6+ messages in thread
From: Zhen Ni @ 2026-04-17 15:46 UTC (permalink / raw)
To: akpm, vbabka
Cc: surenb, mhocko, jackmanb, hannes, ziy, linux-mm, linux-kernel, Zhen Ni
Add NUMA node filtering functionality to page_owner to allow
filtering pages by specific NUMA node.
The filter allows users to focus on pages from a specific NUMA node,
which is useful for NUMA-aware memory allocation analysis and debugging.
Setting nid to -1 disables filtering (default behavior).
Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
---
mm/page_owner.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/mm/page_owner.c b/mm/page_owner.c
index 214b58eef3d8..ebc29f3f516d 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -726,6 +726,13 @@ read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos)
if (unlikely(!page_ext))
continue;
+ if (READ_ONCE(owner_filter.nid) >= 0) {
+ int nid = page_to_nid(page);
+
+ if (nid != READ_ONCE(owner_filter.nid))
+ goto ext_put_continue;
+ }
+
/*
* Some pages could be missed by concurrent allocation or free,
* because we don't hold the zone lock.
@@ -987,6 +994,24 @@ static int page_owner_threshold_set(void *data, u64 val)
DEFINE_SIMPLE_ATTRIBUTE(page_owner_threshold_fops, &page_owner_threshold_get,
&page_owner_threshold_set, "%llu");
+static int page_owner_nid_filter_get(void *data, u64 *val)
+{
+ *val = READ_ONCE(owner_filter.nid);
+ return 0;
+}
+
+static int page_owner_nid_filter_set(void *data, u64 val)
+{
+ if (val >= MAX_NUMNODES && val != (u64)-1)
+ return -EINVAL;
+ WRITE_ONCE(owner_filter.nid, val);
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(page_owner_nid_filter_fops,
+ &page_owner_nid_filter_get,
+ &page_owner_nid_filter_set, "%lld");
+
static int page_owner_compact_get(void *data, u64 *val)
{
*val = READ_ONCE(owner_filter.compact);
@@ -1018,6 +1043,8 @@ static int __init pageowner_init(void)
debugfs_create_file("page_owner", 0400, NULL, NULL, &page_owner_fops);
filter_dir = debugfs_create_dir("page_owner_filter", NULL);
+ debugfs_create_file("nid", 0600, filter_dir, NULL,
+ &page_owner_nid_filter_fops);
debugfs_create_file("compact", 0600, filter_dir, NULL,
&page_owner_compact_fops);
--
2.20.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/3] mm/page_owner: add compact mode filter
2026-04-17 15:46 ` [PATCH 2/3] mm/page_owner: add compact mode filter Zhen Ni
@ 2026-04-17 15:55 ` Zi Yan
0 siblings, 0 replies; 6+ messages in thread
From: Zi Yan @ 2026-04-17 15:55 UTC (permalink / raw)
To: Zhen Ni
Cc: akpm, vbabka, surenb, mhocko, jackmanb, hannes, linux-mm, linux-kernel
On 17 Apr 2026, at 11:46, Zhen Ni wrote:
> Add compact mode functionality to reduce page_owner output size by
> printing only the stack handle instead of the full stack trace.
Maybe you could add an enum type for what content is printed.
Something like PAGE_OWNER_PRINT_STACK_HANDLE and PAGE_OWNER_PRINT_FULL_STACK.
Since compact is a very vague name for what the code does.
For the sysfs interface, stack_handle vs full_stack would be used.
>
> Example output:
> Page allocated via order 0, mask 0x42800(GFP_NOWAIT|__GFP_COMP),
> pid 1, tgid 1 (systemd), ts 349667370 ns
> PFN 0xa00a2 type Unmovable Block 1280 type Unmovable
> Flags 0x33fffe0000004124(referenced|lru|active|private|node=3|zone=0|
> lastcpupid=0x1ffff)
> handle: 17432583
> Charged to memcg /
>
> Compact mode significantly reduces output size while preserving all
> other page allocation information, making it easier to analyze large
> volumes of page owner data.The correspondence between handles and stack
> traces can be obtained through the show_stacks_handles interface.
>
> Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
> ---
> mm/page_owner.c | 29 ++++++++++++++++++++++++++++-
> 1 file changed, 28 insertions(+), 1 deletion(-)
>
> diff --git a/mm/page_owner.c b/mm/page_owner.c
> index 6811439bf9e4..214b58eef3d8 100644
> --- a/mm/page_owner.c
> +++ b/mm/page_owner.c
> @@ -585,7 +585,14 @@ print_page_owner(char __user *buf, size_t count, unsigned long pfn,
> migratetype_names[pageblock_mt],
> &page->flags);
>
> - ret += stack_depot_snprint(handle, kbuf + ret, count - ret, 0);
> + /* Compact mode: print handle instead of full stack trace */
> + if (READ_ONCE(owner_filter.compact)) {
> + ret += scnprintf(kbuf + ret, count - ret,
> + "handle: %d\n", handle);
> + } else {
> + ret += stack_depot_snprint(handle, kbuf + ret, count - ret, 0);
> + }
> +
> if (ret >= count)
> goto err;
>
> @@ -980,6 +987,24 @@ static int page_owner_threshold_set(void *data, u64 val)
> DEFINE_SIMPLE_ATTRIBUTE(page_owner_threshold_fops, &page_owner_threshold_get,
> &page_owner_threshold_set, "%llu");
>
> +static int page_owner_compact_get(void *data, u64 *val)
> +{
> + *val = READ_ONCE(owner_filter.compact);
> + return 0;
> +}
> +
> +static int page_owner_compact_set(void *data, u64 val)
> +{
> + if (val != 0 && val != 1)
> + return -EINVAL;
> + WRITE_ONCE(owner_filter.compact, val);
> + return 0;
> +}
> +
> +DEFINE_SIMPLE_ATTRIBUTE(page_owner_compact_fops,
> + &page_owner_compact_get,
> + &page_owner_compact_set, "%lld");
> +
>
> static int __init pageowner_init(void)
> {
> @@ -993,6 +1018,8 @@ static int __init pageowner_init(void)
> debugfs_create_file("page_owner", 0400, NULL, NULL, &page_owner_fops);
>
> filter_dir = debugfs_create_dir("page_owner_filter", NULL);
> + debugfs_create_file("compact", 0600, filter_dir, NULL,
> + &page_owner_compact_fops);
>
> dir = debugfs_create_dir("page_owner_stacks", NULL);
> debugfs_create_file("show_stacks", 0400, dir,
> --
> 2.20.1
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 3/3] mm/page_owner: add NUMA node filter
2026-04-17 15:46 ` [PATCH 3/3] mm/page_owner: add NUMA node filter Zhen Ni
@ 2026-04-17 15:58 ` Zi Yan
0 siblings, 0 replies; 6+ messages in thread
From: Zi Yan @ 2026-04-17 15:58 UTC (permalink / raw)
To: Zhen Ni
Cc: akpm, vbabka, surenb, mhocko, jackmanb, hannes, linux-mm, linux-kernel
On 17 Apr 2026, at 11:46, Zhen Ni wrote:
> Add NUMA node filtering functionality to page_owner to allow
> filtering pages by specific NUMA node.
Would a NUMA node bitmask be more generally applicable?
For sysfs, input and output can be a list of NUMA nodes that will be printed.
>
> The filter allows users to focus on pages from a specific NUMA node,
> which is useful for NUMA-aware memory allocation analysis and debugging.
> Setting nid to -1 disables filtering (default behavior).
>
> Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
> ---
> mm/page_owner.c | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> diff --git a/mm/page_owner.c b/mm/page_owner.c
> index 214b58eef3d8..ebc29f3f516d 100644
> --- a/mm/page_owner.c
> +++ b/mm/page_owner.c
> @@ -726,6 +726,13 @@ read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos)
> if (unlikely(!page_ext))
> continue;
>
> + if (READ_ONCE(owner_filter.nid) >= 0) {
> + int nid = page_to_nid(page);
> +
> + if (nid != READ_ONCE(owner_filter.nid))
> + goto ext_put_continue;
> + }
> +
> /*
> * Some pages could be missed by concurrent allocation or free,
> * because we don't hold the zone lock.
> @@ -987,6 +994,24 @@ static int page_owner_threshold_set(void *data, u64 val)
> DEFINE_SIMPLE_ATTRIBUTE(page_owner_threshold_fops, &page_owner_threshold_get,
> &page_owner_threshold_set, "%llu");
>
> +static int page_owner_nid_filter_get(void *data, u64 *val)
> +{
> + *val = READ_ONCE(owner_filter.nid);
> + return 0;
> +}
> +
> +static int page_owner_nid_filter_set(void *data, u64 val)
> +{
> + if (val >= MAX_NUMNODES && val != (u64)-1)
> + return -EINVAL;
> + WRITE_ONCE(owner_filter.nid, val);
> + return 0;
> +}
> +
> +DEFINE_SIMPLE_ATTRIBUTE(page_owner_nid_filter_fops,
> + &page_owner_nid_filter_get,
> + &page_owner_nid_filter_set, "%lld");
> +
> static int page_owner_compact_get(void *data, u64 *val)
> {
> *val = READ_ONCE(owner_filter.compact);
> @@ -1018,6 +1043,8 @@ static int __init pageowner_init(void)
> debugfs_create_file("page_owner", 0400, NULL, NULL, &page_owner_fops);
>
> filter_dir = debugfs_create_dir("page_owner_filter", NULL);
> + debugfs_create_file("nid", 0600, filter_dir, NULL,
> + &page_owner_nid_filter_fops);
> debugfs_create_file("compact", 0600, filter_dir, NULL,
> &page_owner_compact_fops);
>
> --
> 2.20.1
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-04-17 15:58 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-04-17 15:46 [PATCH 0/3] mm/page_owner: add filter infrastructure for compact mode and NUMA filtering Zhen Ni
2026-04-17 15:46 ` [PATCH 1/3] mm/page_owner: add filter infrastructure Zhen Ni
2026-04-17 15:46 ` [PATCH 2/3] mm/page_owner: add compact mode filter Zhen Ni
2026-04-17 15:55 ` Zi Yan
2026-04-17 15:46 ` [PATCH 3/3] mm/page_owner: add NUMA node filter Zhen Ni
2026-04-17 15:58 ` Zi Yan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox