* [PATCH v2 1/3] mm/page_owner: add filter infrastructure
2026-04-19 15:55 [PATCH v2 0/3] mm/page_owner: add filter infrastructure for print_mode and NUMA filtering Zhen Ni
@ 2026-04-19 15:55 ` Zhen Ni
2026-04-27 15:35 ` Zi Yan
2026-04-19 15:55 ` [PATCH v2 2/3] mm/page_owner: add print_mode filter Zhen Ni
` (3 subsequent siblings)
4 siblings, 1 reply; 18+ messages in thread
From: Zhen Ni @ 2026-04-19 15:55 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:
- enum page_owner_print_mode with values for full_stack and stack_handle
- struct page_owner_filter with print_mode and nid_mask fields
- Static owner_filter instance initialized with default values
- page_owner_filter debugfs directory
The filter infrastructure will be used to add print_mode and NUMA node
filtering capabilities in subsequent commits.
Link: https://lore.kernel.org/linux-mm/20260417154638.22370-2-zhen.ni@easystack.cn/
Suggested-by: Zi Yan <ziy@nvidia.com>
Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
---
Changes in v2:
- Use enum page_owner_print_mode instead of bool 'compact' for better clarity
- Use nodemask_t instead of int 'nid' to support multi-node filtering
---
mm/page_owner.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/mm/page_owner.c b/mm/page_owner.c
index 8178e0be557f..5884d883837e 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -54,6 +54,21 @@ struct stack_print_ctx {
u8 flags;
};
+enum page_owner_print_mode {
+ PAGE_OWNER_PRINT_FULL_STACK,
+ PAGE_OWNER_PRINT_STACK_HANDLE,
+};
+
+struct page_owner_filter {
+ enum page_owner_print_mode print_mode;
+ nodemask_t nid_mask;
+};
+
+static struct page_owner_filter owner_filter = {
+ .print_mode = PAGE_OWNER_PRINT_FULL_STACK,
+ .nid_mask = NODE_MASK_NONE,
+};
+
static bool page_owner_enabled __initdata;
DEFINE_STATIC_KEY_FALSE(page_owner_inited);
@@ -973,7 +988,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 +996,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 related [flat|nested] 18+ messages in thread* Re: [PATCH v2 1/3] mm/page_owner: add filter infrastructure
2026-04-19 15:55 ` [PATCH v2 1/3] mm/page_owner: add filter infrastructure Zhen Ni
@ 2026-04-27 15:35 ` Zi Yan
2026-04-28 3:33 ` zhen.ni
0 siblings, 1 reply; 18+ messages in thread
From: Zi Yan @ 2026-04-27 15:35 UTC (permalink / raw)
To: Zhen Ni
Cc: akpm, vbabka, surenb, mhocko, jackmanb, hannes, linux-mm,
linux-kernel
On 19 Apr 2026, at 11:55, Zhen Ni wrote:
> Add data structure for page_owner filtering functionality and create
> debugfs directory for filter controls.
>
> This adds:
> - enum page_owner_print_mode with values for full_stack and stack_handle
> - struct page_owner_filter with print_mode and nid_mask fields
> - Static owner_filter instance initialized with default values
> - page_owner_filter debugfs directory
>
> The filter infrastructure will be used to add print_mode and NUMA node
> filtering capabilities in subsequent commits.
>
> Link: https://lore.kernel.org/linux-mm/20260417154638.22370-2-zhen.ni@easystack.cn/
> Suggested-by: Zi Yan <ziy@nvidia.com>
> Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
> ---
>
> Changes in v2:
> - Use enum page_owner_print_mode instead of bool 'compact' for better clarity
> - Use nodemask_t instead of int 'nid' to support multi-node filtering
> ---
> mm/page_owner.c | 20 +++++++++++++++++++-
> 1 file changed, 19 insertions(+), 1 deletion(-)
The patch can be folded into Patch 2. Otherwise, these new types are not
used and page_owner_filter folder is just empty.
>
> diff --git a/mm/page_owner.c b/mm/page_owner.c
> index 8178e0be557f..5884d883837e 100644
> --- a/mm/page_owner.c
> +++ b/mm/page_owner.c
> @@ -54,6 +54,21 @@ struct stack_print_ctx {
> u8 flags;
> };
>
> +enum page_owner_print_mode {
> + PAGE_OWNER_PRINT_FULL_STACK,
> + PAGE_OWNER_PRINT_STACK_HANDLE,
> +};
> +
> +struct page_owner_filter {
> + enum page_owner_print_mode print_mode;
> + nodemask_t nid_mask;
> +};
> +
> +static struct page_owner_filter owner_filter = {
> + .print_mode = PAGE_OWNER_PRINT_FULL_STACK,
> + .nid_mask = NODE_MASK_NONE,
> +};
> +
> static bool page_owner_enabled __initdata;
> DEFINE_STATIC_KEY_FALSE(page_owner_inited);
>
> @@ -973,7 +988,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 +996,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
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 1/3] mm/page_owner: add filter infrastructure
2026-04-27 15:35 ` Zi Yan
@ 2026-04-28 3:33 ` zhen.ni
2026-04-28 13:13 ` Zi Yan
0 siblings, 1 reply; 18+ messages in thread
From: zhen.ni @ 2026-04-28 3:33 UTC (permalink / raw)
To: Zi Yan
Cc: akpm, vbabka, surenb, mhocko, jackmanb, hannes, linux-mm,
linux-kernel
在 2026/4/27 23:35, Zi Yan 写道:
> On 19 Apr 2026, at 11:55, Zhen Ni wrote:
>
>> Add data structure for page_owner filtering functionality and create
>> debugfs directory for filter controls.
>>
>> This adds:
>> - enum page_owner_print_mode with values for full_stack and stack_handle
>> - struct page_owner_filter with print_mode and nid_mask fields
>> - Static owner_filter instance initialized with default values
>> - page_owner_filter debugfs directory
>>
>> The filter infrastructure will be used to add print_mode and NUMA node
>> filtering capabilities in subsequent commits.
>>
>> Link: https://lore.kernel.org/linux-mm/20260417154638.22370-2-zhen.ni@easystack.cn/
>> Suggested-by: Zi Yan <ziy@nvidia.com>
>> Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
>> ---
>>
>> Changes in v2:
>> - Use enum page_owner_print_mode instead of bool 'compact' for better clarity
>> - Use nodemask_t instead of int 'nid' to support multi-node filtering
>> ---
>> mm/page_owner.c | 20 +++++++++++++++++++-
>> 1 file changed, 19 insertions(+), 1 deletion(-)
>
> The patch can be folded into Patch 2. Otherwise, these new types are not
> used and page_owner_filter folder is just empty.
>
Thanks for your review and suggestion.
I kept the 3-patch structure mainly for clear functional separation,
which also makes review easier. Patch 1 adds the infrastructure,
patch 2 adds print_mode filter, and patch 3 adds NUMA filter.
I discussed this with Andrew and he has already accepted the
current 3-patch structure into mm-new for testing. Since he's okay
with it and mentioned that bisection holes are acceptable in this
case, I'll keep the current structure in v3.
>>
>> diff --git a/mm/page_owner.c b/mm/page_owner.c
>> index 8178e0be557f..5884d883837e 100644
>> --- a/mm/page_owner.c
>> +++ b/mm/page_owner.c
>> @@ -54,6 +54,21 @@ struct stack_print_ctx {
>> u8 flags;
>> };
>>
>> +enum page_owner_print_mode {
>> + PAGE_OWNER_PRINT_FULL_STACK,
>> + PAGE_OWNER_PRINT_STACK_HANDLE,
>> +};
>> +
>> +struct page_owner_filter {
>> + enum page_owner_print_mode print_mode;
>> + nodemask_t nid_mask;
>> +};
>> +
>> +static struct page_owner_filter owner_filter = {
>> + .print_mode = PAGE_OWNER_PRINT_FULL_STACK,
>> + .nid_mask = NODE_MASK_NONE,
>> +};
>> +
>> static bool page_owner_enabled __initdata;
>> DEFINE_STATIC_KEY_FALSE(page_owner_inited);
>>
>> @@ -973,7 +988,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 +996,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
>
>
> Best Regards,
> Yan, Zi
>
>
Best regards,
Zhen
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 1/3] mm/page_owner: add filter infrastructure
2026-04-28 3:33 ` zhen.ni
@ 2026-04-28 13:13 ` Zi Yan
2026-04-29 1:39 ` SeongJae Park
2026-04-29 11:22 ` zhen.ni
0 siblings, 2 replies; 18+ messages in thread
From: Zi Yan @ 2026-04-28 13:13 UTC (permalink / raw)
To: zhen.ni
Cc: akpm, vbabka, surenb, mhocko, jackmanb, hannes, linux-mm,
linux-kernel
On 27 Apr 2026, at 23:33, zhen.ni wrote:
> 在 2026/4/27 23:35, Zi Yan 写道:
>> On 19 Apr 2026, at 11:55, Zhen Ni wrote:
>>
>>> Add data structure for page_owner filtering functionality and create
>>> debugfs directory for filter controls.
>>>
>>> This adds:
>>> - enum page_owner_print_mode with values for full_stack and stack_handle
>>> - struct page_owner_filter with print_mode and nid_mask fields
>>> - Static owner_filter instance initialized with default values
>>> - page_owner_filter debugfs directory
>>>
>>> The filter infrastructure will be used to add print_mode and NUMA node
>>> filtering capabilities in subsequent commits.
>>>
>>> Link: https://lore.kernel.org/linux-mm/20260417154638.22370-2-zhen.ni@easystack.cn/
>>> Suggested-by: Zi Yan <ziy@nvidia.com>
>>> Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
>>> ---
>>>
>>> Changes in v2:
>>> - Use enum page_owner_print_mode instead of bool 'compact' for better clarity
>>> - Use nodemask_t instead of int 'nid' to support multi-node filtering
>>> ---
>>> mm/page_owner.c | 20 +++++++++++++++++++-
>>> 1 file changed, 19 insertions(+), 1 deletion(-)
>>
>> The patch can be folded into Patch 2. Otherwise, these new types are not
>> used and page_owner_filter folder is just empty.
>>
>
>
> Thanks for your review and suggestion.
>
> I kept the 3-patch structure mainly for clear functional separation,
> which also makes review easier. Patch 1 adds the infrastructure,
What is the point of adding unused code in a separate patch?
Patch 1 has no functional addition and should be part of Patch 2.
> patch 2 adds print_mode filter, and patch 3 adds NUMA filter.
>
> I discussed this with Andrew and he has already accepted the
> current 3-patch structure into mm-new for testing. Since he's okay
> with it and mentioned that bisection holes are acceptable in this
The patches are still in mm-new, not mm-stable. It is totally acceptable
to reorganize them.
> case, I'll keep the current structure in v3.
Please refrain from posting a new version when the discussion is still
going on.
>
>>>
>>> diff --git a/mm/page_owner.c b/mm/page_owner.c
>>> index 8178e0be557f..5884d883837e 100644
>>> --- a/mm/page_owner.c
>>> +++ b/mm/page_owner.c
>>> @@ -54,6 +54,21 @@ struct stack_print_ctx {
>>> u8 flags;
>>> };
>>>
>>> +enum page_owner_print_mode {
>>> + PAGE_OWNER_PRINT_FULL_STACK,
>>> + PAGE_OWNER_PRINT_STACK_HANDLE,
>>> +};
>>> +
>>> +struct page_owner_filter {
>>> + enum page_owner_print_mode print_mode;
>>> + nodemask_t nid_mask;
>>> +};
>>> +
>>> +static struct page_owner_filter owner_filter = {
>>> + .print_mode = PAGE_OWNER_PRINT_FULL_STACK,
>>> + .nid_mask = NODE_MASK_NONE,
>>> +};
>>> +
>>> static bool page_owner_enabled __initdata;
>>> DEFINE_STATIC_KEY_FALSE(page_owner_inited);
>>>
>>> @@ -973,7 +988,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 +996,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
>>
>>
>> Best Regards,
>> Yan, Zi
>>
>>
> Best regards,
> Zhen
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 1/3] mm/page_owner: add filter infrastructure
2026-04-28 13:13 ` Zi Yan
@ 2026-04-29 1:39 ` SeongJae Park
2026-04-29 11:22 ` zhen.ni
1 sibling, 0 replies; 18+ messages in thread
From: SeongJae Park @ 2026-04-29 1:39 UTC (permalink / raw)
To: Zi Yan
Cc: SeongJae Park, zhen.ni, akpm, vbabka, surenb, mhocko, jackmanb,
hannes, linux-mm, linux-kernel
On Tue, 28 Apr 2026 09:13:03 -0400 Zi Yan <ziy@nvidia.com> wrote:
> On 27 Apr 2026, at 23:33, zhen.ni wrote:
>
> > 在 2026/4/27 23:35, Zi Yan 写道:
> >> On 19 Apr 2026, at 11:55, Zhen Ni wrote:
> >>
> >>> Add data structure for page_owner filtering functionality and create
> >>> debugfs directory for filter controls.
> >>>
> >>> This adds:
> >>> - enum page_owner_print_mode with values for full_stack and stack_handle
> >>> - struct page_owner_filter with print_mode and nid_mask fields
> >>> - Static owner_filter instance initialized with default values
> >>> - page_owner_filter debugfs directory
> >>>
> >>> The filter infrastructure will be used to add print_mode and NUMA node
> >>> filtering capabilities in subsequent commits.
> >>>
> >>> Link: https://lore.kernel.org/linux-mm/20260417154638.22370-2-zhen.ni@easystack.cn/
> >>> Suggested-by: Zi Yan <ziy@nvidia.com>
> >>> Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
> >>> ---
> >>>
> >>> Changes in v2:
> >>> - Use enum page_owner_print_mode instead of bool 'compact' for better clarity
> >>> - Use nodemask_t instead of int 'nid' to support multi-node filtering
> >>> ---
> >>> mm/page_owner.c | 20 +++++++++++++++++++-
> >>> 1 file changed, 19 insertions(+), 1 deletion(-)
> >>
> >> The patch can be folded into Patch 2. Otherwise, these new types are not
> >> used and page_owner_filter folder is just empty.
> >>
> >
> >
> > Thanks for your review and suggestion.
> >
> > I kept the 3-patch structure mainly for clear functional separation,
> > which also makes review easier. Patch 1 adds the infrastructure,
>
> What is the point of adding unused code in a separate patch?
> Patch 1 has no functional addition and should be part of Patch 2.
I agree.
While I was reviewing the v3 of this series, I had to move between the patch 2
and patch 1 to check the value of the print_mode enum. Having those on single
patch will be easier to read for people like me.
Thanks,
SJ
[...]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 1/3] mm/page_owner: add filter infrastructure
2026-04-28 13:13 ` Zi Yan
2026-04-29 1:39 ` SeongJae Park
@ 2026-04-29 11:22 ` zhen.ni
2026-04-29 11:28 ` Zi Yan
1 sibling, 1 reply; 18+ messages in thread
From: zhen.ni @ 2026-04-29 11:22 UTC (permalink / raw)
To: Zi Yan
Cc: akpm, vbabka, surenb, mhocko, jackmanb, hannes, linux-mm,
linux-kernel
在 2026/4/28 21:13, Zi Yan 写道:
> On 27 Apr 2026, at 23:33, zhen.ni wrote:
>
>> 在 2026/4/27 23:35, Zi Yan 写道:
>>> On 19 Apr 2026, at 11:55, Zhen Ni wrote:
>>>
>>>> Add data structure for page_owner filtering functionality and create
>>>> debugfs directory for filter controls.
>>>>
>>>> This adds:
>>>> - enum page_owner_print_mode with values for full_stack and stack_handle
>>>> - struct page_owner_filter with print_mode and nid_mask fields
>>>> - Static owner_filter instance initialized with default values
>>>> - page_owner_filter debugfs directory
>>>>
>>>> The filter infrastructure will be used to add print_mode and NUMA node
>>>> filtering capabilities in subsequent commits.
>>>>
>>>> Link: https://lore.kernel.org/linux-mm/20260417154638.22370-2-zhen.ni@easystack.cn/
>>>> Suggested-by: Zi Yan <ziy@nvidia.com>
>>>> Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
>>>> ---
>>>>
>>>> Changes in v2:
>>>> - Use enum page_owner_print_mode instead of bool 'compact' for better clarity
>>>> - Use nodemask_t instead of int 'nid' to support multi-node filtering
>>>> ---
>>>> mm/page_owner.c | 20 +++++++++++++++++++-
>>>> 1 file changed, 19 insertions(+), 1 deletion(-)
>>>
>>> The patch can be folded into Patch 2. Otherwise, these new types are not
>>> used and page_owner_filter folder is just empty.
>>>
>>
>>
>> Thanks for your review and suggestion.
>>
>> I kept the 3-patch structure mainly for clear functional separation,
>> which also makes review easier. Patch 1 adds the infrastructure,
>
> What is the point of adding unused code in a separate patch?
> Patch 1 has no functional addition and should be part of Patch 2.
>
>> patch 2 adds print_mode filter, and patch 3 adds NUMA filter.
>>
>> I discussed this with Andrew and he has already accepted the
>> current 3-patch structure into mm-new for testing. Since he's okay
>> with it and mentioned that bisection holes are acceptable in this
>
> The patches are still in mm-new, not mm-stable. It is totally acceptable
> to reorganize them.
>
>> case, I'll keep the current structure in v3.
>
> Please refrain from posting a new version when the discussion is still
> going on.
>
>>
>>>>
>>>> diff --git a/mm/page_owner.c b/mm/page_owner.c
>>>> index 8178e0be557f..5884d883837e 100644
>>>> --- a/mm/page_owner.c
>>>> +++ b/mm/page_owner.c
>>>> @@ -54,6 +54,21 @@ struct stack_print_ctx {
>>>> u8 flags;
>>>> };
>>>>
>>>> +enum page_owner_print_mode {
>>>> + PAGE_OWNER_PRINT_FULL_STACK,
>>>> + PAGE_OWNER_PRINT_STACK_HANDLE,
>>>> +};
>>>> +
>>>> +struct page_owner_filter {
>>>> + enum page_owner_print_mode print_mode;
>>>> + nodemask_t nid_mask;
>>>> +};
>>>> +
>>>> +static struct page_owner_filter owner_filter = {
>>>> + .print_mode = PAGE_OWNER_PRINT_FULL_STACK,
>>>> + .nid_mask = NODE_MASK_NONE,
>>>> +};
>>>> +
>>>> static bool page_owner_enabled __initdata;
>>>> DEFINE_STATIC_KEY_FALSE(page_owner_inited);
>>>>
>>>> @@ -973,7 +988,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 +996,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
>>>
>>>
>>> Best Regards,
>>> Yan, Zi
>>>
>>>
>> Best regards,
>> Zhen
>
>
> Best Regards,
> Yan, Zi
>
>
Regarding your suggestion to fold patch 1 into patch 2:
I understand your point that patch 1 adds unused code and creates
an empty page_owner_filter folder. While a single patch should not have
unused variables, in a patch series it's sometimes acceptable to have
preparatory patches that add infrastructure for subsequent patches to use.
I found many examples in the kernel where "prepare" or "preparatory"
patches add code that is only fully utilized in later patches
If you and other reviewers strongly prefer merging patches 1 and 2 to
follow the guidance more strictly, I can do that in v4. I'm open to this
change if the community feels it's the better approach.
Best regards,
Zhen
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 1/3] mm/page_owner: add filter infrastructure
2026-04-29 11:22 ` zhen.ni
@ 2026-04-29 11:28 ` Zi Yan
0 siblings, 0 replies; 18+ messages in thread
From: Zi Yan @ 2026-04-29 11:28 UTC (permalink / raw)
To: zhen.ni
Cc: akpm, vbabka, surenb, mhocko, jackmanb, hannes, linux-mm,
linux-kernel
On 29 Apr 2026, at 7:22, zhen.ni wrote:
> 在 2026/4/28 21:13, Zi Yan 写道:
>> On 27 Apr 2026, at 23:33, zhen.ni wrote:
>>
>>> 在 2026/4/27 23:35, Zi Yan 写道:
>>>> On 19 Apr 2026, at 11:55, Zhen Ni wrote:
>>>>
>>>>> Add data structure for page_owner filtering functionality and create
>>>>> debugfs directory for filter controls.
>>>>>
>>>>> This adds:
>>>>> - enum page_owner_print_mode with values for full_stack and stack_handle
>>>>> - struct page_owner_filter with print_mode and nid_mask fields
>>>>> - Static owner_filter instance initialized with default values
>>>>> - page_owner_filter debugfs directory
>>>>>
>>>>> The filter infrastructure will be used to add print_mode and NUMA node
>>>>> filtering capabilities in subsequent commits.
>>>>>
>>>>> Link: https://lore.kernel.org/linux-mm/20260417154638.22370-2-zhen.ni@easystack.cn/
>>>>> Suggested-by: Zi Yan <ziy@nvidia.com>
>>>>> Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
>>>>> ---
>>>>>
>>>>> Changes in v2:
>>>>> - Use enum page_owner_print_mode instead of bool 'compact' for better clarity
>>>>> - Use nodemask_t instead of int 'nid' to support multi-node filtering
>>>>> ---
>>>>> mm/page_owner.c | 20 +++++++++++++++++++-
>>>>> 1 file changed, 19 insertions(+), 1 deletion(-)
>>>>
>>>> The patch can be folded into Patch 2. Otherwise, these new types are not
>>>> used and page_owner_filter folder is just empty.
>>>>
>>>
>>>
>>> Thanks for your review and suggestion.
>>>
>>> I kept the 3-patch structure mainly for clear functional separation,
>>> which also makes review easier. Patch 1 adds the infrastructure,
>>
>> What is the point of adding unused code in a separate patch?
>> Patch 1 has no functional addition and should be part of Patch 2.
>>
>>> patch 2 adds print_mode filter, and patch 3 adds NUMA filter.
>>>
>>> I discussed this with Andrew and he has already accepted the
>>> current 3-patch structure into mm-new for testing. Since he's okay
>>> with it and mentioned that bisection holes are acceptable in this
>>
>> The patches are still in mm-new, not mm-stable. It is totally acceptable
>> to reorganize them.
>>
>>> case, I'll keep the current structure in v3.
>>
>> Please refrain from posting a new version when the discussion is still
>> going on.
>>
>>>
>>>>>
>>>>> diff --git a/mm/page_owner.c b/mm/page_owner.c
>>>>> index 8178e0be557f..5884d883837e 100644
>>>>> --- a/mm/page_owner.c
>>>>> +++ b/mm/page_owner.c
>>>>> @@ -54,6 +54,21 @@ struct stack_print_ctx {
>>>>> u8 flags;
>>>>> };
>>>>>
>>>>> +enum page_owner_print_mode {
>>>>> + PAGE_OWNER_PRINT_FULL_STACK,
>>>>> + PAGE_OWNER_PRINT_STACK_HANDLE,
>>>>> +};
>>>>> +
>>>>> +struct page_owner_filter {
>>>>> + enum page_owner_print_mode print_mode;
>>>>> + nodemask_t nid_mask;
>>>>> +};
>>>>> +
>>>>> +static struct page_owner_filter owner_filter = {
>>>>> + .print_mode = PAGE_OWNER_PRINT_FULL_STACK,
>>>>> + .nid_mask = NODE_MASK_NONE,
>>>>> +};
>>>>> +
>>>>> static bool page_owner_enabled __initdata;
>>>>> DEFINE_STATIC_KEY_FALSE(page_owner_inited);
>>>>>
>>>>> @@ -973,7 +988,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 +996,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
>>>>
>>>>
>>>> Best Regards,
>>>> Yan, Zi
>>>>
>>>>
>>> Best regards,
>>> Zhen
>>
>>
>> Best Regards,
>> Yan, Zi
>>
>>
> Regarding your suggestion to fold patch 1 into patch 2:
>
> I understand your point that patch 1 adds unused code and creates
> an empty page_owner_filter folder. While a single patch should not have unused variables, in a patch series it's sometimes acceptable to have preparatory patches that add infrastructure for subsequent patches to use.
>
> I found many examples in the kernel where "prepare" or "preparatory" patches add code that is only fully utilized in later patches
Those preparatory patches usually add actual functions, not just types.
This patch also adds a user visible folder that has no function.
I do not see any reason this standalone patch is necessary.
>
> If you and other reviewers strongly prefer merging patches 1 and 2 to follow the guidance more strictly, I can do that in v4. I'm open to this change if the community feels it's the better approach.
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 2/3] mm/page_owner: add print_mode filter
2026-04-19 15:55 [PATCH v2 0/3] mm/page_owner: add filter infrastructure for print_mode and NUMA filtering Zhen Ni
2026-04-19 15:55 ` [PATCH v2 1/3] mm/page_owner: add filter infrastructure Zhen Ni
@ 2026-04-19 15:55 ` Zhen Ni
2026-04-27 15:43 ` Zi Yan
2026-04-19 15:55 ` [PATCH v2 3/3] mm/page_owner: add NUMA node filter with nodelist support Zhen Ni
` (2 subsequent siblings)
4 siblings, 1 reply; 18+ messages in thread
From: Zhen Ni @ 2026-04-19 15:55 UTC (permalink / raw)
To: akpm, vbabka
Cc: surenb, mhocko, jackmanb, hannes, ziy, linux-mm, linux-kernel,
Zhen Ni
Add print_mode functionality to reduce page_owner output size by
printing only the stack handle instead of the full stack trace.
Example output with print_mode enabled:
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 /
Print mode significantly reduces output size while preserving all
other page allocation information. The correspondence between handles
and stack traces can be obtained through the show_stacks_handles interface.
Link: https://lore.kernel.org/linux-mm/20260417154638.22370-3-zhen.ni@easystack.cn/
Suggested-by: Zi Yan <ziy@nvidia.com>
Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
---
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'
---
mm/page_owner.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/mm/page_owner.c b/mm/page_owner.c
index 5884d883837e..6d87b6948cfa 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -590,7 +590,13 @@ 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);
+ /* Print mode: full stack or stack handle */
+ 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;
@@ -985,6 +991,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_print_mode_get(void *data, u64 *val)
+{
+ *val = READ_ONCE(owner_filter.print_mode);
+ return 0;
+}
+
+static int page_owner_print_mode_set(void *data, u64 val)
+{
+ if (val > PAGE_OWNER_PRINT_STACK_HANDLE)
+ return -EINVAL;
+ WRITE_ONCE(owner_filter.print_mode, val);
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(page_owner_print_mode_fops,
+ &page_owner_print_mode_get,
+ &page_owner_print_mode_set, "%lld");
+
static int __init pageowner_init(void)
{
@@ -998,6 +1022,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("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,
--
2.20.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v2 2/3] mm/page_owner: add print_mode filter
2026-04-19 15:55 ` [PATCH v2 2/3] mm/page_owner: add print_mode filter Zhen Ni
@ 2026-04-27 15:43 ` Zi Yan
2026-04-28 3:36 ` zhen.ni
0 siblings, 1 reply; 18+ messages in thread
From: Zi Yan @ 2026-04-27 15:43 UTC (permalink / raw)
To: Zhen Ni
Cc: akpm, vbabka, surenb, mhocko, jackmanb, hannes, linux-mm,
linux-kernel
On 19 Apr 2026, at 11:55, Zhen Ni wrote:
> Add print_mode functionality to reduce page_owner output size by
> printing only the stack handle instead of the full stack trace.
>
> Example output with print_mode enabled:
> 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 /
>
> Print mode significantly reduces output size while preserving all
> other page allocation information. The correspondence between handles
> and stack traces can be obtained through the show_stacks_handles interface.
>
> Link: https://lore.kernel.org/linux-mm/20260417154638.22370-3-zhen.ni@easystack.cn/
> Suggested-by: Zi Yan <ziy@nvidia.com>
> Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
> ---
>
> 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'
> ---
> mm/page_owner.c | 28 +++++++++++++++++++++++++++-
> 1 file changed, 27 insertions(+), 1 deletion(-)
>
> diff --git a/mm/page_owner.c b/mm/page_owner.c
> index 5884d883837e..6d87b6948cfa 100644
> --- a/mm/page_owner.c
> +++ b/mm/page_owner.c
> @@ -590,7 +590,13 @@ 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);
> + /* Print mode: full stack or stack handle */
> + 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;
>
> @@ -985,6 +991,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_print_mode_get(void *data, u64 *val)
> +{
> + *val = READ_ONCE(owner_filter.print_mode);
> + return 0;
> +}
> +
> +static int page_owner_print_mode_set(void *data, u64 val)
> +{
> + if (val > PAGE_OWNER_PRINT_STACK_HANDLE)
> + return -EINVAL;
> + WRITE_ONCE(owner_filter.print_mode, val);
> + return 0;
> +}
> +
> +DEFINE_SIMPLE_ATTRIBUTE(page_owner_print_mode_fops,
> + &page_owner_print_mode_get,
> + &page_owner_print_mode_set, "%lld");
> +
>
> static int __init pageowner_init(void)
> {
> @@ -998,6 +1022,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("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,
> --
> 2.20.1
I think it is more user-friendly to use “full_stack” and “stack_handle”
instead of 0 and 1. You can refer to [1] to sysfs_match_string() to
do that. I was testing the interface, but needed to look at your code
to know which print_mode I am using. ;)
[1] https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git/tree/mm/huge_memory.c?h=mm-everything#n380
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 2/3] mm/page_owner: add print_mode filter
2026-04-27 15:43 ` Zi Yan
@ 2026-04-28 3:36 ` zhen.ni
2026-04-28 13:20 ` Zi Yan
0 siblings, 1 reply; 18+ messages in thread
From: zhen.ni @ 2026-04-28 3:36 UTC (permalink / raw)
To: Zi Yan
Cc: akpm, vbabka, surenb, mhocko, jackmanb, hannes, linux-mm,
linux-kernel
在 2026/4/27 23:43, Zi Yan 写道:
> On 19 Apr 2026, at 11:55, Zhen Ni wrote:
>
>> Add print_mode functionality to reduce page_owner output size by
>> printing only the stack handle instead of the full stack trace.
>>
>> Example output with print_mode enabled:
>> 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 /
>>
>> Print mode significantly reduces output size while preserving all
>> other page allocation information. The correspondence between handles
>> and stack traces can be obtained through the show_stacks_handles interface.
>>
>> Link: https://lore.kernel.org/linux-mm/20260417154638.22370-3-zhen.ni@easystack.cn/
>> Suggested-by: Zi Yan <ziy@nvidia.com>
>> Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
>> ---
>>
>> 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'
>> ---
>> mm/page_owner.c | 28 +++++++++++++++++++++++++++-
>> 1 file changed, 27 insertions(+), 1 deletion(-)
>>
>> diff --git a/mm/page_owner.c b/mm/page_owner.c
>> index 5884d883837e..6d87b6948cfa 100644
>> --- a/mm/page_owner.c
>> +++ b/mm/page_owner.c
>> @@ -590,7 +590,13 @@ 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);
>> + /* Print mode: full stack or stack handle */
>> + 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;
>>
>> @@ -985,6 +991,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_print_mode_get(void *data, u64 *val)
>> +{
>> + *val = READ_ONCE(owner_filter.print_mode);
>> + return 0;
>> +}
>> +
>> +static int page_owner_print_mode_set(void *data, u64 val)
>> +{
>> + if (val > PAGE_OWNER_PRINT_STACK_HANDLE)
>> + return -EINVAL;
>> + WRITE_ONCE(owner_filter.print_mode, val);
>> + return 0;
>> +}
>> +
>> +DEFINE_SIMPLE_ATTRIBUTE(page_owner_print_mode_fops,
>> + &page_owner_print_mode_get,
>> + &page_owner_print_mode_set, "%lld");
>> +
>>
>> static int __init pageowner_init(void)
>> {
>> @@ -998,6 +1022,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("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,
>> --
>> 2.20.1
>
> I think it is more user-friendly to use “full_stack” and “stack_handle”
> instead of 0 and 1. You can refer to [1] to sysfs_match_string() to
> do that. I was testing the interface, but needed to look at your code
> to know which print_mode I am using. ;)
>
>
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git/tree/mm/huge_memory.c?h=mm-everything#n380
>
>
Thanks for the suggestion!
I considered using "full_stack" and "stack_handle" strings, but
I think the numeric values (0/1) are more concise and easier to type
for users.
The v3 documentation will clarify the meaning:
- 0 (default): Print full stack traces
- 1: Print only stack handles
Do you think this is sufficient, or would you still prefer using
string values instead?
> Best Regards,
> Yan, Zi
>
>
Best regards,
Zhen
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 2/3] mm/page_owner: add print_mode filter
2026-04-28 3:36 ` zhen.ni
@ 2026-04-28 13:20 ` Zi Yan
2026-04-29 11:42 ` zhen.ni
0 siblings, 1 reply; 18+ messages in thread
From: Zi Yan @ 2026-04-28 13:20 UTC (permalink / raw)
To: zhen.ni
Cc: akpm, vbabka, surenb, mhocko, jackmanb, hannes, linux-mm,
linux-kernel
On 27 Apr 2026, at 23:36, zhen.ni wrote:
> 在 2026/4/27 23:43, Zi Yan 写道:
>> On 19 Apr 2026, at 11:55, Zhen Ni wrote:
>>
>>> Add print_mode functionality to reduce page_owner output size by
>>> printing only the stack handle instead of the full stack trace.
>>>
>>> Example output with print_mode enabled:
>>> 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 /
>>>
>>> Print mode significantly reduces output size while preserving all
>>> other page allocation information. The correspondence between handles
>>> and stack traces can be obtained through the show_stacks_handles interface.
>>>
>>> Link: https://lore.kernel.org/linux-mm/20260417154638.22370-3-zhen.ni@easystack.cn/
>>> Suggested-by: Zi Yan <ziy@nvidia.com>
>>> Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
>>> ---
>>>
>>> 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'
>>> ---
>>> mm/page_owner.c | 28 +++++++++++++++++++++++++++-
>>> 1 file changed, 27 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/mm/page_owner.c b/mm/page_owner.c
>>> index 5884d883837e..6d87b6948cfa 100644
>>> --- a/mm/page_owner.c
>>> +++ b/mm/page_owner.c
>>> @@ -590,7 +590,13 @@ 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);
>>> + /* Print mode: full stack or stack handle */
>>> + 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;
>>>
>>> @@ -985,6 +991,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_print_mode_get(void *data, u64 *val)
>>> +{
>>> + *val = READ_ONCE(owner_filter.print_mode);
>>> + return 0;
>>> +}
>>> +
>>> +static int page_owner_print_mode_set(void *data, u64 val)
>>> +{
>>> + if (val > PAGE_OWNER_PRINT_STACK_HANDLE)
>>> + return -EINVAL;
>>> + WRITE_ONCE(owner_filter.print_mode, val);
>>> + return 0;
>>> +}
>>> +
>>> +DEFINE_SIMPLE_ATTRIBUTE(page_owner_print_mode_fops,
>>> + &page_owner_print_mode_get,
>>> + &page_owner_print_mode_set, "%lld");
>>> +
>>>
>>> static int __init pageowner_init(void)
>>> {
>>> @@ -998,6 +1022,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("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,
>>> --
>>> 2.20.1
>>
>> I think it is more user-friendly to use “full_stack” and “stack_handle”
>> instead of 0 and 1. You can refer to [1] to sysfs_match_string() to
>> do that. I was testing the interface, but needed to look at your code
>> to know which print_mode I am using. ;)
>>
>>
>> [1] https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git/tree/mm/huge_memory.c?h=mm-everything#n380
>>
>>
>
> Thanks for the suggestion!
>
> I considered using "full_stack" and "stack_handle" strings, but
> I think the numeric values (0/1) are more concise and easier to type
> for users.
I disagree. It is hard for user to know what the current print mode
is and what available modes are. 0 or 1 is usually for boolean input.
Something like:
[full_stack] stack_handle
full_stack [stack_handle]
is much easier for user to read and use.
>
> The v3 documentation will clarify the meaning:
> - 0 (default): Print full stack traces
> - 1: Print only stack handles
>
> Do you think this is sufficient, or would you still prefer using
> string values instead?
>
>
>> Best Regards,
>> Yan, Zi
>>
>>
> Best regards,
> Zhen
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 2/3] mm/page_owner: add print_mode filter
2026-04-28 13:20 ` Zi Yan
@ 2026-04-29 11:42 ` zhen.ni
0 siblings, 0 replies; 18+ messages in thread
From: zhen.ni @ 2026-04-29 11:42 UTC (permalink / raw)
To: Zi Yan
Cc: akpm, vbabka, surenb, mhocko, jackmanb, hannes, linux-mm,
linux-kernel
在 2026/4/28 21:20, Zi Yan 写道:
> On 27 Apr 2026, at 23:36, zhen.ni wrote:
>
>> 在 2026/4/27 23:43, Zi Yan 写道:
>>> On 19 Apr 2026, at 11:55, Zhen Ni wrote:
>>>
>>>> Add print_mode functionality to reduce page_owner output size by
>>>> printing only the stack handle instead of the full stack trace.
>>>>
>>>> Example output with print_mode enabled:
>>>> 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 /
>>>>
>>>> Print mode significantly reduces output size while preserving all
>>>> other page allocation information. The correspondence between handles
>>>> and stack traces can be obtained through the show_stacks_handles interface.
>>>>
>>>> Link: https://lore.kernel.org/linux-mm/20260417154638.22370-3-zhen.ni@easystack.cn/
>>>> Suggested-by: Zi Yan <ziy@nvidia.com>
>>>> Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
>>>> ---
>>>>
>>>> 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'
>>>> ---
>>>> mm/page_owner.c | 28 +++++++++++++++++++++++++++-
>>>> 1 file changed, 27 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/mm/page_owner.c b/mm/page_owner.c
>>>> index 5884d883837e..6d87b6948cfa 100644
>>>> --- a/mm/page_owner.c
>>>> +++ b/mm/page_owner.c
>>>> @@ -590,7 +590,13 @@ 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);
>>>> + /* Print mode: full stack or stack handle */
>>>> + 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;
>>>>
>>>> @@ -985,6 +991,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_print_mode_get(void *data, u64 *val)
>>>> +{
>>>> + *val = READ_ONCE(owner_filter.print_mode);
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static int page_owner_print_mode_set(void *data, u64 val)
>>>> +{
>>>> + if (val > PAGE_OWNER_PRINT_STACK_HANDLE)
>>>> + return -EINVAL;
>>>> + WRITE_ONCE(owner_filter.print_mode, val);
>>>> + return 0;
>>>> +}
>>>> +
>>>> +DEFINE_SIMPLE_ATTRIBUTE(page_owner_print_mode_fops,
>>>> + &page_owner_print_mode_get,
>>>> + &page_owner_print_mode_set, "%lld");
>>>> +
>>>>
>>>> static int __init pageowner_init(void)
>>>> {
>>>> @@ -998,6 +1022,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("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,
>>>> --
>>>> 2.20.1
>>>
>>> I think it is more user-friendly to use “full_stack” and “stack_handle”
>>> instead of 0 and 1. You can refer to [1] to sysfs_match_string() to
>>> do that. I was testing the interface, but needed to look at your code
>>> to know which print_mode I am using. ;)
>>>
>>>
>>> [1] https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git/tree/mm/huge_memory.c?h=mm-everything#n380
>>>
>>>
>>
>> Thanks for the suggestion!
>>
>> I considered using "full_stack" and "stack_handle" strings, but
>> I think the numeric values (0/1) are more concise and easier to type
>> for users.
>
> I disagree. It is hard for user to know what the current print mode
> is and what available modes are. 0 or 1 is usually for boolean input.
>
> Something like:
> [full_stack] stack_handle
> full_stack [stack_handle]
>
> is much easier for user to read and use.
>
The string-based interface is more user-friendly
I'll switch to using string values "full_stack" and "stack_handle"
with sysfs_match_string() in v4, implementing the show function to
display them with [] brackets around the current selection.
>>
>> The v3 documentation will clarify the meaning:
>> - 0 (default): Print full stack traces
>> - 1: Print only stack handles
>>
>> Do you think this is sufficient, or would you still prefer using
>> string values instead?
>>
>>
>>> Best Regards,
>>> Yan, Zi
>>>
>>>
>> Best regards,
>> Zhen
>
>
> Best Regards,
> Yan, Zi
>
>
Best regards,
Zhen
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 3/3] mm/page_owner: add NUMA node filter with nodelist support
2026-04-19 15:55 [PATCH v2 0/3] mm/page_owner: add filter infrastructure for print_mode and NUMA filtering Zhen Ni
2026-04-19 15:55 ` [PATCH v2 1/3] mm/page_owner: add filter infrastructure Zhen Ni
2026-04-19 15:55 ` [PATCH v2 2/3] mm/page_owner: add print_mode filter Zhen Ni
@ 2026-04-19 15:55 ` Zhen Ni
2026-04-24 11:26 ` Andrew Morton
2026-04-24 20:15 ` Andrew Morton
2026-04-24 11:27 ` [PATCH v2 0/3] mm/page_owner: add filter infrastructure for print_mode and NUMA filtering Andrew Morton
2026-04-24 14:09 ` Andrew Morton
4 siblings, 2 replies; 18+ messages in thread
From: Zhen Ni @ 2026-04-19 15:55 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(s) using nodelist format.
The filter allows users to focus on pages from specific NUMA nodes,
which is useful for NUMA-aware memory allocation analysis and debugging.
Supported input formats:
- Single node: echo "2" > nid
- Multiple nodes: echo "0,2,3" > nid
- Node range: echo "0-3" > nid
- Mixed format: echo "0,2-4,7" > nid
- Disable filter: echo "-1" > nid
Link: https://lore.kernel.org/linux-mm/20260417154638.22370-4-zhen.ni@easystack.cn/
Suggested-by: Zi Yan <ziy@nvidia.com>
Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
---
Changes in v2:
- Use nodemask_t instead of int to support multiple nodes
- Implement nodelist_parse() to support flexible input formats
* Single node: "0", "2"
* Multiple nodes: "0,2,3"
* Ranges: "0-3"
* Mixed: "0,2-4,7"
- Use %*pbl format for output (e.g., "0-2", "0,2-4,7")
- Use dynamic memory allocation (kmalloc) to handle variable-length input
- Follow cpuset's max_write_len pattern: (100 + 6 * MAX_NUMNODES)
---
mm/page_owner.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/mm/page_owner.c b/mm/page_owner.c
index 6d87b6948cfa..8c13bb3798d8 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -707,6 +707,7 @@ read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos)
* user through copy_to_user() or GFP_KERNEL allocations.
*/
struct page_owner page_owner_tmp;
+ nodemask_t mask;
/*
* If the new page is in a new MAX_ORDER_NR_PAGES area,
@@ -730,6 +731,15 @@ read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos)
if (unlikely(!page_ext))
continue;
+ /* NUMA node filter using bitmask */
+ mask = READ_ONCE(owner_filter.nid_mask);
+ if (!nodes_empty(mask)) {
+ int nid = page_to_nid(page);
+
+ if (!node_isset(nid, mask))
+ goto ext_put_continue;
+ }
+
/*
* Some pages could be missed by concurrent allocation or free,
* because we don't hold the zone lock.
@@ -1009,6 +1019,70 @@ DEFINE_SIMPLE_ATTRIBUTE(page_owner_print_mode_fops,
&page_owner_print_mode_get,
&page_owner_print_mode_set, "%lld");
+static ssize_t nid_filter_write(struct file *file,
+ const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ char *kbuf;
+ nodemask_t mask;
+ int ret;
+
+ /* Limit input size to handle worst-case nodelist (all nodes) */
+ if (count > (100 + 6 * MAX_NUMNODES))
+ return -EINVAL;
+
+ kbuf = kmalloc(count + 1, GFP_KERNEL);
+ if (!kbuf)
+ return -ENOMEM;
+
+ if (copy_from_user(kbuf, buf, count)) {
+ ret = -EFAULT;
+ goto out_free;
+ }
+ kbuf[count] = '\0';
+
+ /* Support: "-1" to clear, or nodelist format like "0", "0,2", "0-3" */
+ if (strcmp(kbuf, "-1\n") == 0 || strcmp(kbuf, "-1") == 0)
+ nodes_clear(mask);
+ else if (nodelist_parse(kbuf, mask)) {
+ ret = -EINVAL;
+ goto out_free;
+ }
+
+ WRITE_ONCE(owner_filter.nid_mask, mask);
+ ret = count;
+
+out_free:
+ kfree(kbuf);
+ return ret;
+}
+
+static int nid_filter_show(struct seq_file *m, void *v)
+{
+ nodemask_t mask = READ_ONCE(owner_filter.nid_mask);
+
+ if (nodes_empty(mask))
+ seq_puts(m, "-1\n");
+ else
+ seq_printf(m, "%*pbl\n", nodemask_pr_args(&mask));
+
+ return 0;
+}
+
+static int nid_filter_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, nid_filter_show, NULL);
+}
+
+static const struct file_operations nid_filter_fops = {
+ .owner = THIS_MODULE,
+ .open = nid_filter_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .write = nid_filter_write,
+ .release = single_release,
+};
+
static int __init pageowner_init(void)
{
@@ -1024,6 +1098,8 @@ static int __init pageowner_init(void)
filter_dir = debugfs_create_dir("page_owner_filter", NULL);
debugfs_create_file("print_mode", 0600, filter_dir, NULL,
&page_owner_print_mode_fops);
+ debugfs_create_file("nid", 0600, filter_dir, NULL,
+ &nid_filter_fops);
dir = debugfs_create_dir("page_owner_stacks", NULL);
debugfs_create_file("show_stacks", 0400, dir,
--
2.20.1
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v2 3/3] mm/page_owner: add NUMA node filter with nodelist support
2026-04-19 15:55 ` [PATCH v2 3/3] mm/page_owner: add NUMA node filter with nodelist support Zhen Ni
@ 2026-04-24 11:26 ` Andrew Morton
2026-04-24 20:15 ` Andrew Morton
1 sibling, 0 replies; 18+ messages in thread
From: Andrew Morton @ 2026-04-24 11:26 UTC (permalink / raw)
To: Zhen Ni
Cc: vbabka, surenb, mhocko, jackmanb, hannes, ziy, linux-mm,
linux-kernel
On Sun, 19 Apr 2026 23:55:40 +0800 Zhen Ni <zhen.ni@easystack.cn> wrote:
> Add NUMA node filtering functionality to page_owner to allow
> filtering pages by specific NUMA node(s) using nodelist format.
>
> The filter allows users to focus on pages from specific NUMA nodes,
> which is useful for NUMA-aware memory allocation analysis and debugging.
>
> Supported input formats:
> - Single node: echo "2" > nid
> - Multiple nodes: echo "0,2,3" > nid
> - Node range: echo "0-3" > nid
> - Mixed format: echo "0,2-4,7" > nid
> - Disable filter: echo "-1" > nid
>
> ...
>
> --- a/mm/page_owner.c
> +++ b/mm/page_owner.c
> @@ -707,6 +707,7 @@ read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos)
> * user through copy_to_user() or GFP_KERNEL allocations.
> */
> struct page_owner page_owner_tmp;
> + nodemask_t mask;
>
> /*
> * If the new page is in a new MAX_ORDER_NR_PAGES area,
> @@ -730,6 +731,15 @@ read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos)
> if (unlikely(!page_ext))
> continue;
>
> + /* NUMA node filter using bitmask */
> + mask = READ_ONCE(owner_filter.nid_mask);
> + if (!nodes_empty(mask)) {
> + int nid = page_to_nid(page);
> +
> + if (!node_isset(nid, mask))
> + goto ext_put_continue;
> + }
> +
> /*
> * Some pages could be missed by concurrent allocation or free,
> * because we don't hold the zone lock.
> @@ -1009,6 +1019,70 @@ DEFINE_SIMPLE_ATTRIBUTE(page_owner_print_mode_fops,
> &page_owner_print_mode_get,
> &page_owner_print_mode_set, "%lld");
>
> +static ssize_t nid_filter_write(struct file *file,
> + const char __user *buf,
> + size_t count, loff_t *ppos)
> +{
> + char *kbuf;
> + nodemask_t mask;
> + int ret;
> +
> + /* Limit input size to handle worst-case nodelist (all nodes) */
> + if (count > (100 + 6 * MAX_NUMNODES))
> + return -EINVAL;
I'm wondering how that expression was arrived at ;) Perhaps a little
comment explaining? Or can we simply use strnlen_user() here?
> + kbuf = kmalloc(count + 1, GFP_KERNEL);
> + if (!kbuf)
> + return -ENOMEM;
> +
> + if (copy_from_user(kbuf, buf, count)) {
> + ret = -EFAULT;
> + goto out_free;
> + }
> + kbuf[count] = '\0';
Can we use strncpy_from_user() here?
In fact I thought that we had a strdup_from_user() thing which does the
kmalloc also, but maybe I dreamed it.
And memdup_user_nul() could perhaps be used in here.
Nothing really fits. We need a
char *strdup_user(const void __user *src);
(Probably it's OK to assume GFP_KERNEL)
(Maybe needs a size_t max_len arg)
> + /* Support: "-1" to clear, or nodelist format like "0", "0,2", "0-3" */
> + if (strcmp(kbuf, "-1\n") == 0 || strcmp(kbuf, "-1") == 0)
Maybe
if (kstrtoll(kbuf) == -1)
(we have lots of goodies in /lib!)
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 3/3] mm/page_owner: add NUMA node filter with nodelist support
2026-04-19 15:55 ` [PATCH v2 3/3] mm/page_owner: add NUMA node filter with nodelist support Zhen Ni
2026-04-24 11:26 ` Andrew Morton
@ 2026-04-24 20:15 ` Andrew Morton
1 sibling, 0 replies; 18+ messages in thread
From: Andrew Morton @ 2026-04-24 20:15 UTC (permalink / raw)
To: Zhen Ni
Cc: vbabka, surenb, mhocko, jackmanb, hannes, ziy, linux-mm,
linux-kernel
On Sun, 19 Apr 2026 23:55:40 +0800 Zhen Ni <zhen.ni@easystack.cn> wrote:
> Add NUMA node filtering functionality to page_owner to allow
> filtering pages by specific NUMA node(s) using nodelist format.
>
> The filter allows users to focus on pages from specific NUMA nodes,
> which is useful for NUMA-aware memory allocation analysis and debugging.
AI review
(https://sashiko.dev/#/patchset/20260419155540.376847-1-zhen.ni@easystack.cn)
wonders if it's legitimate to use READ_ONCE/WRITE_ONCE against a
nodemask_t. And indeed, my x86_64 allmodconfig hit compile time
asserts over this.
So I took them out:
--- a/mm/page_owner.c~mm-page_owner-add-numa-node-filter-with-nodelist-support-fix
+++ a/mm/page_owner.c
@@ -732,7 +732,7 @@ read_page_owner(struct file *file, char
continue;
/* NUMA node filter using bitmask */
- mask = READ_ONCE(owner_filter.nid_mask);
+ mask = owner_filter.nid_mask;
if (!nodes_empty(mask)) {
int nid = page_to_nid(page);
@@ -1049,7 +1049,7 @@ static ssize_t nid_filter_write(struct f
goto out_free;
}
- WRITE_ONCE(owner_filter.nid_mask, mask);
+ owner_filter.nid_mask = mask;
ret = count;
out_free:
@@ -1059,7 +1059,7 @@ out_free:
static int nid_filter_show(struct seq_file *m, void *v)
{
- nodemask_t mask = READ_ONCE(owner_filter.nid_mask);
+ nodemask_t mask = owner_filter.nid_mask;
if (nodes_empty(mask))
seq_puts(m, "-1\n");
_
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 0/3] mm/page_owner: add filter infrastructure for print_mode and NUMA filtering
2026-04-19 15:55 [PATCH v2 0/3] mm/page_owner: add filter infrastructure for print_mode and NUMA filtering Zhen Ni
` (2 preceding siblings ...)
2026-04-19 15:55 ` [PATCH v2 3/3] mm/page_owner: add NUMA node filter with nodelist support Zhen Ni
@ 2026-04-24 11:27 ` Andrew Morton
2026-04-24 14:09 ` Andrew Morton
4 siblings, 0 replies; 18+ messages in thread
From: Andrew Morton @ 2026-04-24 11:27 UTC (permalink / raw)
To: Zhen Ni
Cc: vbabka, surenb, mhocko, jackmanb, hannes, ziy, linux-mm,
linux-kernel
On Sun, 19 Apr 2026 23:55:37 +0800 Zhen Ni <zhen.ni@easystack.cn> wrote:
> This patch series introduces filtering capabilities to the page_owner
> feature to address storage and performance challenges in production
> environments.
Nice patchset, thanks. I'm glad to hear that page_owner is being
useful in such environments.
I'll add this to mm.git for some testing and review. Meanwhile...
> mm/page_owner.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 122 insertions(+), 2 deletions(-)
Could you please add appropriate updates to
Documentation/mm/page_owner.rst?
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 0/3] mm/page_owner: add filter infrastructure for print_mode and NUMA filtering
2026-04-19 15:55 [PATCH v2 0/3] mm/page_owner: add filter infrastructure for print_mode and NUMA filtering Zhen Ni
` (3 preceding siblings ...)
2026-04-24 11:27 ` [PATCH v2 0/3] mm/page_owner: add filter infrastructure for print_mode and NUMA filtering Andrew Morton
@ 2026-04-24 14:09 ` Andrew Morton
4 siblings, 0 replies; 18+ messages in thread
From: Andrew Morton @ 2026-04-24 14:09 UTC (permalink / raw)
To: Zhen Ni
Cc: vbabka, surenb, mhocko, jackmanb, hannes, ziy, linux-mm,
linux-kernel
On Sun, 19 Apr 2026 23:55:37 +0800 Zhen Ni <zhen.ni@easystack.cn> wrote:
> This patch series introduces filtering capabilities to the page_owner
> feature to address storage and performance challenges in production
> environments.
AI review asks some good questions:
https://sashiko.dev/#/patchset/20260419155540.376847-1-zhen.ni@easystack.cn
(I'd be OK with ignoring the bisection hole issues)
^ permalink raw reply [flat|nested] 18+ messages in thread