From: Zhen Ni <zhen.ni@easystack.cn>
To: akpm@linux-foundation.org, vbabka@kernel.org
Cc: surenb@google.com, mhocko@suse.com, jackmanb@google.com,
hannes@cmpxchg.org, ziy@nvidia.com, linux-mm@kvack.org,
linux-kernel@vger.kernel.org, Zhen Ni <zhen.ni@easystack.cn>,
SeongJae Park <sj@kernel.org>
Subject: [PATCH v6 1/3] mm/page_owner: add print_mode filter
Date: Mon, 11 May 2026 11:30:15 +0800 [thread overview]
Message-ID: <20260511033017.747781-2-zhen.ni@easystack.cn> (raw)
In-Reply-To: <20260511033017.747781-1-zhen.ni@easystack.cn>
Add a print_mode filter to page_owner that allows users to choose between
printing full stack traces or only stack handles, significantly reducing
output size for debugging and analysis.
The filter provides a string-based interface under
/sys/kernel/debug/page_owner_filter/:
- Reading shows the current mode with [] brackets around active option
- Writing accepts "full_stack" or "stack_handle" strings
The default full_stack mode maintains backward compatibility with existing
usage, displaying complete stack traces for each page allocation.
The stack_handle mode dramatically reduces log size by showing only
the handle number instead of the full stack trace. The mapping from
handles to actual stack traces can be obtained via the
show_stacks_handles interface.
Example usage:
# echo stack_handle > /sys/kernel/debug/page_owner_filter/print_mode
# cat /sys/kernel/debug/page_owner_filter/print_mode
full_stack [stack_handle]
# cat /sys/kernel/debug/page_owner
Page allocated via order 0, migratetype Unmovable, gfp_mask 0x1100ca,
pid 1, tgid 1 (systemd), ts 123456789 ns
PFN 0x1000 type Unmovable Block 1 type Unmovable
Flags 0x3fffe800000084(referenced|lru|active|private|node=0|zone=1)
handle: 17432583
...
Reviewed-by: SeongJae Park <sj@kernel.org>
Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
---
Changes in v6:
- Remove unnecessary braces in if/else statement (coding style)
- Use stack array (char kbuf[33]) instead of kmalloc for input buffer
Changes in v5:
- No code changes
Changes in v4:
- Change from numeric (0/1) to string-based interface ("full_stack"/"stack_handle")
- Merge infrastructure patch into this patch
Changes in v3:
- No code changes
Changes in v2:
- Renamed from 'compact mode' to 'print_mode' for better clarity
- Use enum values (0=full_stack, 1=stack_handle) instead of boolean
- Update debugfs filename from 'compact' to 'print_mode'
v5: https://lore.kernel.org/linux-mm/20260507064643.179187-2-zhen.ni@easystack.cn/
v4: https://lore.kernel.org/linux-mm/20260430163247.13628-2-zhen.ni@easystack.cn/
v3: https://lore.kernel.org/linux-mm/20260428071112.1420380-2-zhen.ni@easystack.cn/
https://lore.kernel.org/linux-mm/20260428071112.1420380-3-zhen.ni@easystack.cn/
v2: https://lore.kernel.org/linux-mm/20260419155540.376847-2-zhen.ni@easystack.cn/
https://lore.kernel.org/linux-mm/20260419155540.376847-3-zhen.ni@easystack.cn/
v1: https://lore.kernel.org/linux-mm/20260417154638.22370-2-zhen.ni@easystack.cn/
https://lore.kernel.org/linux-mm/20260417154638.22370-3-zhen.ni@easystack.cn/
---
mm/page_owner.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 80 insertions(+), 2 deletions(-)
diff --git a/mm/page_owner.c b/mm/page_owner.c
index 8178e0be557f..27a412c52d41 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/debugfs.h>
+#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
@@ -54,6 +55,24 @@ struct stack_print_ctx {
u8 flags;
};
+enum page_owner_print_mode {
+ PAGE_OWNER_PRINT_FULL_STACK,
+ PAGE_OWNER_PRINT_STACK_HANDLE,
+};
+
+static const char * const page_owner_print_mode_strings[] = {
+ [PAGE_OWNER_PRINT_FULL_STACK] = "full_stack",
+ [PAGE_OWNER_PRINT_STACK_HANDLE] = "stack_handle",
+};
+
+struct page_owner_filter {
+ enum page_owner_print_mode print_mode;
+};
+
+static struct page_owner_filter owner_filter = {
+ .print_mode = PAGE_OWNER_PRINT_FULL_STACK,
+};
+
static bool page_owner_enabled __initdata;
DEFINE_STATIC_KEY_FALSE(page_owner_inited);
@@ -575,7 +594,11 @@ 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);
+ if (READ_ONCE(owner_filter.print_mode) == PAGE_OWNER_PRINT_STACK_HANDLE)
+ 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;
@@ -970,10 +993,60 @@ 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 ssize_t print_mode_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ const char *output;
+ int mode;
+
+ mode = READ_ONCE(owner_filter.print_mode);
+
+ if (mode == PAGE_OWNER_PRINT_FULL_STACK)
+ output = "[full_stack] stack_handle\n";
+ else
+ output = "full_stack [stack_handle]\n";
+
+ return simple_read_from_buffer(buf, count, ppos, output, strlen(output));
+}
+
+static ssize_t print_mode_write(struct file *file,
+ const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ char kbuf[32 + 1];
+ int mode;
+
+ /*
+ * Limit input size. Maximum valid input is "stack_handle" (12 chars)
+ * plus newline and null terminator. Use 32 bytes as a reasonable limit.
+ */
+ if (count > 32)
+ return -EINVAL;
+
+ if (strncpy_from_user(kbuf, buf, count) < 0)
+ return -EFAULT;
+ kbuf[count] = '\0';
+
+ mode = sysfs_match_string(page_owner_print_mode_strings, kbuf);
+ if (mode < 0)
+ return -EINVAL;
+
+ WRITE_ONCE(owner_filter.print_mode, mode);
+
+ return count;
+}
+
+static const struct file_operations page_owner_print_mode_fops = {
+ .owner = THIS_MODULE,
+ .read = print_mode_read,
+ .write = print_mode_write,
+ .llseek = default_llseek,
+};
+
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 +1054,11 @@ 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("print_mode", 0600, filter_dir, NULL,
+ &page_owner_print_mode_fops);
+
dir = debugfs_create_dir("page_owner_stacks", NULL);
debugfs_create_file("show_stacks", 0400, dir,
(void *)(STACK_PRINT_FLAG_STACK |
--
2.20.1
next prev parent reply other threads:[~2026-05-11 3:35 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-11 3:30 [PATCH v6 0/3] mm/page_owner: add filter infrastructure for print_mode and NUMA filtering Zhen Ni
2026-05-11 3:30 ` Zhen Ni [this message]
2026-05-11 8:29 ` [PATCH v6 1/3] mm/page_owner: add print_mode filter Oscar Salvador
2026-05-11 11:54 ` zhen.ni
2026-05-11 3:30 ` [PATCH v6 2/3] mm/page_owner: add NUMA node filter with nodelist support Zhen Ni
2026-05-11 8:54 ` Oscar Salvador
2026-05-11 12:24 ` zhen.ni
2026-05-11 3:30 ` [PATCH v6 3/3] mm/page_owner: document page_owner filter features Zhen Ni
2026-05-11 8:33 ` Oscar Salvador
2026-05-11 12:23 ` [PATCH v6 0/3] mm/page_owner: add filter infrastructure for print_mode and NUMA filtering Michal Hocko
2026-05-11 12:40 ` zhen.ni
2026-05-11 12:54 ` Michal Hocko
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=20260511033017.747781-2-zhen.ni@easystack.cn \
--to=zhen.ni@easystack.cn \
--cc=akpm@linux-foundation.org \
--cc=hannes@cmpxchg.org \
--cc=jackmanb@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mhocko@suse.com \
--cc=sj@kernel.org \
--cc=surenb@google.com \
--cc=vbabka@kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox