From: Oscar Salvador <osalvador@suse.de>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org,
Michal Hocko <mhocko@suse.com>, Vlastimil Babka <vbabka@suse.cz>,
Waiman Long <longman@redhat.com>,
Suren Baghdasaryan <surenb@google.com>,
Marco Elver <elver@google.com>,
Andrey Konovalov <andreyknvl@gmail.com>,
Eric Dumazet <edumazet@google.com>,
Alexander Potapenko <glider@google.com>,
Oscar Salvador <osalvador@suse.de>
Subject: [PATCH v5 2/3] mm, page_owner: Add page_owner_stacks file to print out only stacks and their counte
Date: Tue, 16 May 2023 20:25:36 +0200 [thread overview]
Message-ID: <20230516182537.3139-3-osalvador@suse.de> (raw)
In-Reply-To: <20230516182537.3139-1-osalvador@suse.de>
We might be only interested in knowing about stacks <-> count
relationship, so instead of having to fiddle with page_owner
output and screen through pfns, let us add a new file called
'page_owner_stacks' that does just that.
By cating such file, we will get all the stacktraces followed by
its counter, so we can have a more global view.
Signed-off-by: Oscar Salvador <osalvador@suse.de>
---
include/linux/stackdepot.h | 6 ++++
lib/stackdepot.c | 72 ++++++++++++++++++++++++++++++++++++++
mm/page_owner.c | 27 ++++++++++++++
3 files changed, 105 insertions(+)
diff --git a/include/linux/stackdepot.h b/include/linux/stackdepot.h
index 6ba4fcdb0c5f..7e9d0e9ec66b 100644
--- a/include/linux/stackdepot.h
+++ b/include/linux/stackdepot.h
@@ -112,6 +112,12 @@ void stack_depot_dec_count(depot_stack_handle_t handle);
depot_stack_handle_t stack_depot_save(unsigned long *entries,
unsigned int nr_entries, gfp_t gfp_flags);
+#ifdef CONFIG_PAGE_OWNER
+void *stack_start(struct seq_file *m, loff_t *ppos);
+void *stack_next(struct seq_file *m, void *v, loff_t *ppos);
+int stack_print(struct seq_file *m, void *v);
+#endif
+
/**
* stack_depot_fetch - Fetch a stack trace from stack depot
*
diff --git a/lib/stackdepot.c b/lib/stackdepot.c
index bc4a9cd25834..c4af2e946500 100644
--- a/lib/stackdepot.c
+++ b/lib/stackdepot.c
@@ -29,6 +29,7 @@
#include <linux/types.h>
#include <linux/memblock.h>
#include <linux/kasan-enabled.h>
+#include <linux/seq_file.h>
#define DEPOT_HANDLE_BITS (sizeof(depot_stack_handle_t) * 8)
@@ -486,6 +487,77 @@ static struct stack_record *stack_depot_getstack(depot_stack_handle_t handle)
return stack;
}
+#ifdef CONFIG_PAGE_OWNER
+void *stack_start(struct seq_file *m, loff_t *ppos)
+{
+ unsigned long *table = m->private;
+ struct stack_record **stacks, *stack;
+
+ /* First time */
+ if (*ppos == 0)
+ *table = 0;
+
+ if (*ppos == -1UL)
+ return NULL;
+
+ stacks = &stack_table[*table];
+ stack = (struct stack_record *)stacks;
+
+ return stack;
+}
+
+void *stack_next(struct seq_file *m, void *v, loff_t *ppos)
+{
+ unsigned long *table = m->private;
+ unsigned long nr_table = *table;
+ struct stack_record *next = NULL, *stack = v, **stacks;
+ unsigned long stack_table_entries = stack_hash_mask + 1;
+
+ if (!stack) {
+new_table:
+ /* New table */
+ nr_table++;
+ if (nr_table >= stack_table_entries)
+ goto out;
+ stacks = &stack_table[nr_table];
+ stack = (struct stack_record *)stacks;
+ next = stack;
+ } else {
+ next = stack->next;
+ }
+
+ if (!next)
+ goto new_table;
+
+out:
+ *table = nr_table;
+ *ppos = (nr_table >= stack_table_entries) ? -1UL : *ppos + 1;
+ return next;
+}
+
+int stack_print(struct seq_file *m, void *v)
+{
+ char *buf;
+ int ret = 0;
+ struct stack_record *stack = v;
+
+ if (!stack->size || stack->size < 0 ||
+ stack->size > PAGE_SIZE || stack->handle.valid != 1 ||
+ refcount_read(&stack->count) < 1)
+ return 0;
+
+ buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ ret += stack_trace_snprint(buf, PAGE_SIZE, stack->entries, stack->size, 0);
+ scnprintf(buf + ret, PAGE_SIZE - ret, "stack count: %d\n\n",
+ refcount_read(&stack->count));
+ seq_printf(m, buf);
+ seq_puts(m, "\n\n");
+ kfree(buf);
+
+ return 0;
+}
+#endif
+
unsigned int stack_depot_fetch(depot_stack_handle_t handle,
unsigned long **entries)
{
diff --git a/mm/page_owner.c b/mm/page_owner.c
index 2d5d07013e4e..2d97f6b34ea6 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -719,6 +719,30 @@ static const struct file_operations proc_page_owner_operations = {
.llseek = lseek_page_owner,
};
+static void stack_stop(struct seq_file *m, void *v)
+{
+}
+
+static const struct seq_operations page_owner_stack_op = {
+ .start = stack_start,
+ .next = stack_next,
+ .stop = stack_stop,
+ .show = stack_print
+};
+
+static int page_owner_stack_open(struct inode *inode, struct file *file)
+{
+ return seq_open_private(file, &page_owner_stack_op,
+ sizeof(unsigned long));
+}
+
+const struct file_operations page_owner_stack_operations = {
+ .open = page_owner_stack_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
static int __init pageowner_init(void)
{
if (!static_branch_unlikely(&page_owner_inited)) {
@@ -729,6 +753,9 @@ static int __init pageowner_init(void)
debugfs_create_file("page_owner", 0400, NULL, NULL,
&proc_page_owner_operations);
+ debugfs_create_file("page_owner_stacks", 0400, NULL, NULL,
+ &page_owner_stack_operations);
+
return 0;
}
late_initcall(pageowner_init)
--
2.35.3
next parent reply other threads:[~2023-05-16 18:25 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20230516182537.3139-1-osalvador@suse.de>
2023-05-16 18:25 ` Oscar Salvador [this message]
2023-05-17 0:59 ` kernel test robot
2023-05-22 8:27 ` Alexander Potapenko
2023-05-16 18:25 ` [PATCH v5 3/3] mm,page_owner: Filter out stacks by a threshold counter Oscar Salvador
2023-05-22 8:40 ` Alexander Potapenko
2023-06-12 10:53 ` Vlastimil Babka
2023-05-16 21:12 ` [PATCH v5 0/3] page_owner: print stacks and their counter Andrew Morton
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=20230516182537.3139-3-osalvador@suse.de \
--to=osalvador@suse.de \
--cc=akpm@linux-foundation.org \
--cc=andreyknvl@gmail.com \
--cc=edumazet@google.com \
--cc=elver@google.com \
--cc=glider@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=longman@redhat.com \
--cc=mhocko@suse.com \
--cc=surenb@google.com \
--cc=vbabka@suse.cz \
/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