All of lore.kernel.org
 help / color / mirror / Atom feed
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>,
	Eric Dumazet <edumazet@google.com>,
	Waiman Long <longman@redhat.com>,
	Suren Baghdasaryan <surenb@google.com>,
	Oscar Salvador <osalvador@suse.de>
Subject: [PATCH 2/3] mm, page_owner: Add page_owner_stacks file to print out only stacks and their counter
Date: Thu,  1 Sep 2022 06:42:48 +0200	[thread overview]
Message-ID: <20220901044249.4624-3-osalvador@suse.de> (raw)
In-Reply-To: <20220901044249.4624-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 (allocated - freed times), so we can have a more specific
overview.

Signed-off-by: Oscar Salvador <osalvador@suse.de>
---
 include/linux/stackdepot.h |  2 ++
 lib/stackdepot.c           | 40 ++++++++++++++++++++++++++++++++++++++
 mm/page_owner.c            | 30 ++++++++++++++++++++++++++++
 3 files changed, 72 insertions(+)

diff --git a/include/linux/stackdepot.h b/include/linux/stackdepot.h
index 5ee0cf5be88f..20f62039f23a 100644
--- a/include/linux/stackdepot.h
+++ b/include/linux/stackdepot.h
@@ -25,6 +25,8 @@ depot_stack_handle_t __stack_depot_save(unsigned long *entries,
 					gfp_t gfp_flags, bool can_alloc,
 					stack_action_t action);
 void stack_depot_dec_count(depot_stack_handle_t handle);
+int stack_depot_print_stacks_threshold(char *buf, size_t size, loff_t *pos,
+				       unsigned long *last_stack);
 
 /*
  * Every user of stack depot has to call stack_depot_init() during its own init
diff --git a/lib/stackdepot.c b/lib/stackdepot.c
index aeb59d3557e2..3090ae0f3958 100644
--- a/lib/stackdepot.c
+++ b/lib/stackdepot.c
@@ -526,3 +526,43 @@ depot_stack_handle_t stack_depot_save_action(unsigned long *entries,
 	return __stack_depot_save(entries, nr_entries, alloc_flags, true, action);
 }
 EXPORT_SYMBOL_GPL(stack_depot_save_action);
+
+int stack_depot_print_stacks_threshold(char *buf, size_t size, loff_t *pos,
+				       unsigned long *last_stack)
+{
+	struct stack_record *stack = NULL, *last;
+	struct stack_record **stacks;
+	int i = *pos, ret = 0;
+
+	/* Continue from the last week if we have one */
+	if (*last_stack) {
+		last = (struct stack_record *)*last_stack;
+		stack = last->next;
+	} else {
+new_table:
+		stacks = &stack_table[i];
+		stack = (struct stack_record *)stacks;
+	}
+
+	for (; stack; stack = stack->next) {
+		if (!stack->size || stack->size < 0 ||
+		    stack->size > size || stack->handle.valid != 1 ||
+		    refcount_read(&stack->count) < 1)
+			continue;
+
+		ret += stack_trace_snprint(buf, size, stack->entries, stack->size, 0);
+		ret += scnprintf(buf + ret, size - ret, "stack count: %d\n\n",
+				 refcount_read(&stack->count));
+		*last_stack = (unsigned long)stack;
+		return ret;
+	}
+
+	i++;
+	*pos = i;
+
+	/* Keep looking all tables for valid stacks */
+	if (i < STACK_HASH_SIZE)
+		goto new_table;
+
+	return 0;
+}
diff --git a/mm/page_owner.c b/mm/page_owner.c
index 794f346d7520..8c67c7eb2451 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -43,6 +43,8 @@ static depot_stack_handle_t early_handle;
 
 static void init_early_allocated_pages(void);
 
+static unsigned long last_stack = 0;
+
 static int __init early_page_owner_param(char *buf)
 {
 	int ret = kstrtobool(buf, &page_owner_enabled);
@@ -663,6 +665,32 @@ static void init_early_allocated_pages(void)
 		init_zones_in_node(pgdat);
 }
 
+static ssize_t read_page_owner_stacks(struct file *file, char __user *buf,
+				      size_t count, loff_t *pos)
+{
+	char *kbuf;
+	int ret = 0;
+
+	count = min_t(size_t, count, PAGE_SIZE);
+	kbuf = kmalloc(count, GFP_KERNEL);
+	if (!kbuf)
+		return ENOMEM;
+
+	ret += stack_depot_print_stacks_threshold(kbuf, count, pos, &last_stack);
+	if (copy_to_user(buf, kbuf, ret))
+		ret = -EFAULT;
+
+	if (!ret)
+		last_stack = 0;
+
+	kfree(kbuf);
+	return ret;
+}
+
+static const struct file_operations proc_page_owner_stacks = {
+	.read = read_page_owner_stacks,
+};
+
 static const struct file_operations proc_page_owner_operations = {
 	.read		= read_page_owner,
 };
@@ -676,6 +704,8 @@ 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,
+			    &proc_page_owner_stacks);
 
 	return 0;
 }
-- 
2.35.3


  parent reply	other threads:[~2022-09-01  4:44 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-01  4:42 [PATCH 0/3] page_owner: print stacks and their counter Oscar Salvador
2022-09-01  4:42 ` [PATCH 1/3] lib/stackdepot: Add a refcount field in stack_record Oscar Salvador
2022-09-01  8:24   ` Marco Elver
2022-09-01  8:38     ` Michal Hocko
2022-09-01  9:18       ` Marco Elver
2022-09-01 10:01         ` Michal Hocko
2022-09-01 10:20           ` Marco Elver
2022-09-05 20:53         ` Andrey Konovalov
2022-09-02  3:27     ` Oscar Salvador
2022-09-01  4:42 ` Oscar Salvador [this message]
2022-09-01  8:16   ` [PATCH 2/3] mm, page_owner: Add page_owner_stacks file to print out only stacks and their counter Ammar Faizi
2022-09-02  3:33     ` Oscar Salvador
2022-09-01 19:29   ` kernel test robot
2022-09-02  0:56   ` kernel test robot
2022-09-01  4:42 ` [PATCH 3/3] mm,page_owner: Filter out stacks by a threshold counter Oscar Salvador
2022-09-01  8:31   ` Ammar Faizi
2022-09-02  3:36     ` Oscar Salvador
2022-09-01  8:40   ` Michal Hocko
2022-09-02  3:37     ` Oscar Salvador
2022-09-01  8:32 ` [PATCH 0/3] page_owner: print stacks and their counter 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=20220901044249.4624-3-osalvador@suse.de \
    --to=osalvador@suse.de \
    --cc=akpm@linux-foundation.org \
    --cc=edumazet@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.