Message ID | 20230516182537.3139-4-osalvador@suse.de (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | None | expand |
On Tue, May 16, 2023 at 8:25 PM Oscar Salvador <osalvador@suse.de> wrote: > > We want to be able to filter out the output on a threshold basis, > in this way we can get rid of a lot of noise and focus only on those > stacks which have an allegedly high counter. > > We can control the threshold value by a new file called > 'page_owner_threshold', which is 0 by default. > > Signed-off-by: Oscar Salvador <osalvador@suse.de> Nack. We must decouple stackdepot from page_owner as much as possible, not add extra dependencies by sharing variables between the two. What you need here is a pair of xxx_iter_start()/xxx_iter_next() functions in stackdepot.c that will hold the iteration state in a struct and return the next stack trace. The threshold value can also be part of that struct.
On 5/22/23 10:40, Alexander Potapenko wrote: > On Tue, May 16, 2023 at 8:25 PM Oscar Salvador <osalvador@suse.de> wrote: >> We want to be able to filter out the output on a threshold basis, >> in this way we can get rid of a lot of noise and focus only on those >> stacks which have an allegedly high counter. >> >> We can control the threshold value by a new file called >> 'page_owner_threshold', which is 0 by default. >> >> Signed-off-by: Oscar Salvador <osalvador@suse.de> > Nack. > We must decouple stackdepot from page_owner as much as possible, not > add extra dependencies by sharing variables between the two. > > What you need here is a pair of xxx_iter_start()/xxx_iter_next() > functions in stackdepot.c that will hold the iteration state in a > struct and return the next stack trace. > The threshold value can also be part of that struct. Agreed, that should be a much cleaner approach.
diff --git a/lib/stackdepot.c b/lib/stackdepot.c index c4af2e946500..7053221ce1d8 100644 --- a/lib/stackdepot.c +++ b/lib/stackdepot.c @@ -488,6 +488,9 @@ static struct stack_record *stack_depot_getstack(depot_stack_handle_t handle) } #ifdef CONFIG_PAGE_OWNER + +extern unsigned long page_owner_stack_threshold; + void *stack_start(struct seq_file *m, loff_t *ppos) { unsigned long *table = m->private; @@ -543,7 +546,7 @@ int stack_print(struct seq_file *m, void *v) if (!stack->size || stack->size < 0 || stack->size > PAGE_SIZE || stack->handle.valid != 1 || - refcount_read(&stack->count) < 1) + refcount_read(&stack->count) < page_owner_stack_threshold) return 0; buf = kzalloc(PAGE_SIZE, GFP_KERNEL); diff --git a/mm/page_owner.c b/mm/page_owner.c index 2d97f6b34ea6..28c519fc9372 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -743,6 +743,23 @@ const struct file_operations page_owner_stack_operations = { .release = seq_release, }; +unsigned long page_owner_stack_threshold; + +int page_owner_threshold_get(void *data, u64 *val) +{ + *val = page_owner_stack_threshold; + return 0; +} + +int page_owner_threshold_set(void *data, u64 val) +{ + page_owner_stack_threshold = val; + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(proc_page_owner_threshold, &page_owner_threshold_get, + &page_owner_threshold_set, "%llu"); + static int __init pageowner_init(void) { if (!static_branch_unlikely(&page_owner_inited)) { @@ -755,6 +772,10 @@ static int __init pageowner_init(void) debugfs_create_file("page_owner_stacks", 0400, NULL, NULL, &page_owner_stack_operations); + debugfs_create_file("page_owner_threshold", 0600, NULL, NULL, + &proc_page_owner_threshold); + + page_owner_stack_threshold = 0; return 0; }
We want to be able to filter out the output on a threshold basis, in this way we can get rid of a lot of noise and focus only on those stacks which have an allegedly high counter. We can control the threshold value by a new file called 'page_owner_threshold', which is 0 by default. Signed-off-by: Oscar Salvador <osalvador@suse.de> --- lib/stackdepot.c | 5 ++++- mm/page_owner.c | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-)