* [PATCH 0/2] mm: kmemleak: Usability improvements
@ 2025-02-06 11:45 Catalin Marinas
2025-02-06 11:45 ` [PATCH 1/2] mm: kmemleak: Add support for dumping physical and __percpu object info Catalin Marinas
2025-02-06 11:45 ` [PATCH 2/2] samples: kmemleak: Print the raw pointers for debugging purposes Catalin Marinas
0 siblings, 2 replies; 3+ messages in thread
From: Catalin Marinas @ 2025-02-06 11:45 UTC (permalink / raw)
To: linux-mm; +Cc: linux-kernel, Andrew Morton
Following a recent false positive tracking that led to commit
488b5b9eca68 ("mm: kmemleak: fix upper boundary check for physical
address objects"), I needed kmemleak to give me more debug information
about the objects it is tracking. This lead to the first patch of this
series. The second patch changes the kmemleak-test module to show the
raw pointers for debugging purposes.
Thanks.
Catalin Marinas (2):
mm: kmemleak: Add support for dumping physical and __percpu object
info
samples: kmemleak: Print the raw pointers for debugging purposes
mm/kmemleak.c | 54 +++++++++++++++++++++++---------
samples/kmemleak/kmemleak-test.c | 36 ++++++++++-----------
2 files changed, 58 insertions(+), 32 deletions(-)
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/2] mm: kmemleak: Add support for dumping physical and __percpu object info
2025-02-06 11:45 [PATCH 0/2] mm: kmemleak: Usability improvements Catalin Marinas
@ 2025-02-06 11:45 ` Catalin Marinas
2025-02-06 11:45 ` [PATCH 2/2] samples: kmemleak: Print the raw pointers for debugging purposes Catalin Marinas
1 sibling, 0 replies; 3+ messages in thread
From: Catalin Marinas @ 2025-02-06 11:45 UTC (permalink / raw)
To: linux-mm; +Cc: linux-kernel, Andrew Morton
Currently, echo dump=... > /sys/kernel/debug/kmemleak only looks up the
main virtual address object tree. However, for debugging, it's useful to
dump information about physical address and __percpu objects.
Search all three object trees for the dump= command and also print the
type of the object if not virtual: "(phys)" or "(percpu)". In addition,
allow search by alias (pointer within the object).
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
mm/kmemleak.c | 54 ++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 40 insertions(+), 14 deletions(-)
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index c6ed68604136..c12cef3eeb32 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -352,6 +352,15 @@ static bool unreferenced_object(struct kmemleak_object *object)
jiffies_last_scan);
}
+static const char *__object_type_str(struct kmemleak_object *object)
+{
+ if (object->flags & OBJECT_PHYS)
+ return " (phys)";
+ if (object->flags & OBJECT_PERCPU)
+ return " (percpu)";
+ return "";
+}
+
/*
* Printing of the unreferenced objects information to the seq file. The
* print_unreferenced function must be called with the object->lock held.
@@ -364,8 +373,9 @@ static void print_unreferenced(struct seq_file *seq,
unsigned int nr_entries;
nr_entries = stack_depot_fetch(object->trace_handle, &entries);
- warn_or_seq_printf(seq, "unreferenced object 0x%08lx (size %zu):\n",
- object->pointer, object->size);
+ warn_or_seq_printf(seq, "unreferenced object%s 0x%08lx (size %zu):\n",
+ __object_type_str(object),
+ object->pointer, object->size);
warn_or_seq_printf(seq, " comm \"%s\", pid %d, jiffies %lu\n",
object->comm, object->pid, object->jiffies);
hex_dump_object(seq, object);
@@ -384,10 +394,10 @@ static void print_unreferenced(struct seq_file *seq,
*/
static void dump_object_info(struct kmemleak_object *object)
{
- pr_notice("Object 0x%08lx (size %zu):\n",
- object->pointer, object->size);
+ pr_notice("Object%s 0x%08lx (size %zu):\n",
+ __object_type_str(object), object->pointer, object->size);
pr_notice(" comm \"%s\", pid %d, jiffies %lu\n",
- object->comm, object->pid, object->jiffies);
+ object->comm, object->pid, object->jiffies);
pr_notice(" min_count = %d\n", object->min_count);
pr_notice(" count = %d\n", object->count);
pr_notice(" flags = 0x%x\n", object->flags);
@@ -1998,25 +2008,41 @@ static int kmemleak_open(struct inode *inode, struct file *file)
return seq_open(file, &kmemleak_seq_ops);
}
-static int dump_str_object_info(const char *str)
+static bool __dump_str_object_info(unsigned long addr, unsigned int objflags)
{
unsigned long flags;
struct kmemleak_object *object;
- unsigned long addr;
- if (kstrtoul(str, 0, &addr))
- return -EINVAL;
- object = find_and_get_object(addr, 0);
- if (!object) {
- pr_info("Unknown object at 0x%08lx\n", addr);
- return -EINVAL;
- }
+ object = __find_and_get_object(addr, 1, objflags);
+ if (!object)
+ return false;
raw_spin_lock_irqsave(&object->lock, flags);
dump_object_info(object);
raw_spin_unlock_irqrestore(&object->lock, flags);
put_object(object);
+
+ return true;
+}
+
+static int dump_str_object_info(const char *str)
+{
+ unsigned long addr;
+ bool found = false;
+
+ if (kstrtoul(str, 0, &addr))
+ return -EINVAL;
+
+ found |= __dump_str_object_info(addr, 0);
+ found |= __dump_str_object_info(addr, OBJECT_PHYS);
+ found |= __dump_str_object_info(addr, OBJECT_PERCPU);
+
+ if (!found) {
+ pr_info("Unknown object at 0x%08lx\n", addr);
+ return -EINVAL;
+ }
+
return 0;
}
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 2/2] samples: kmemleak: Print the raw pointers for debugging purposes
2025-02-06 11:45 [PATCH 0/2] mm: kmemleak: Usability improvements Catalin Marinas
2025-02-06 11:45 ` [PATCH 1/2] mm: kmemleak: Add support for dumping physical and __percpu object info Catalin Marinas
@ 2025-02-06 11:45 ` Catalin Marinas
1 sibling, 0 replies; 3+ messages in thread
From: Catalin Marinas @ 2025-02-06 11:45 UTC (permalink / raw)
To: linux-mm; +Cc: linux-kernel, Andrew Morton
The kmemleak-test.c module is meant to leak some pointers for debugging
the kmemleak detection, pointer information dumping. It's no use if it
prints the hashed values of such pointers.
Change the printk() format from %p to %px. While at it, also display the
raw __percpu pointer rather than this_cpu_ptr() since kmemleak now
tracks such pointers independently of the standard allocations.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
samples/kmemleak/kmemleak-test.c | 36 ++++++++++++++++----------------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/samples/kmemleak/kmemleak-test.c b/samples/kmemleak/kmemleak-test.c
index 544c36d51d56..8609812a37eb 100644
--- a/samples/kmemleak/kmemleak-test.c
+++ b/samples/kmemleak/kmemleak-test.c
@@ -40,25 +40,25 @@ static int kmemleak_test_init(void)
pr_info("Kmemleak testing\n");
/* make some orphan objects */
- pr_info("kmalloc(32) = %p\n", kmalloc(32, GFP_KERNEL));
- pr_info("kmalloc(32) = %p\n", kmalloc(32, GFP_KERNEL));
- pr_info("kmalloc(1024) = %p\n", kmalloc(1024, GFP_KERNEL));
- pr_info("kmalloc(1024) = %p\n", kmalloc(1024, GFP_KERNEL));
- pr_info("kmalloc(2048) = %p\n", kmalloc(2048, GFP_KERNEL));
- pr_info("kmalloc(2048) = %p\n", kmalloc(2048, GFP_KERNEL));
- pr_info("kmalloc(4096) = %p\n", kmalloc(4096, GFP_KERNEL));
- pr_info("kmalloc(4096) = %p\n", kmalloc(4096, GFP_KERNEL));
+ pr_info("kmalloc(32) = 0x%px\n", kmalloc(32, GFP_KERNEL));
+ pr_info("kmalloc(32) = 0x%px\n", kmalloc(32, GFP_KERNEL));
+ pr_info("kmalloc(1024) = 0x%px\n", kmalloc(1024, GFP_KERNEL));
+ pr_info("kmalloc(1024) = 0x%px\n", kmalloc(1024, GFP_KERNEL));
+ pr_info("kmalloc(2048) = 0x%px\n", kmalloc(2048, GFP_KERNEL));
+ pr_info("kmalloc(2048) = 0x%px\n", kmalloc(2048, GFP_KERNEL));
+ pr_info("kmalloc(4096) = 0x%px\n", kmalloc(4096, GFP_KERNEL));
+ pr_info("kmalloc(4096) = 0x%px\n", kmalloc(4096, GFP_KERNEL));
#ifndef CONFIG_MODULES
- pr_info("kmem_cache_alloc(files_cachep) = %p\n",
+ pr_info("kmem_cache_alloc(files_cachep) = 0x%px\n",
kmem_cache_alloc(files_cachep, GFP_KERNEL));
- pr_info("kmem_cache_alloc(files_cachep) = %p\n",
+ pr_info("kmem_cache_alloc(files_cachep) = 0x%px\n",
kmem_cache_alloc(files_cachep, GFP_KERNEL));
#endif
- pr_info("vmalloc(64) = %p\n", vmalloc(64));
- pr_info("vmalloc(64) = %p\n", vmalloc(64));
- pr_info("vmalloc(64) = %p\n", vmalloc(64));
- pr_info("vmalloc(64) = %p\n", vmalloc(64));
- pr_info("vmalloc(64) = %p\n", vmalloc(64));
+ pr_info("vmalloc(64) = 0x%px\n", vmalloc(64));
+ pr_info("vmalloc(64) = 0x%px\n", vmalloc(64));
+ pr_info("vmalloc(64) = 0x%px\n", vmalloc(64));
+ pr_info("vmalloc(64) = 0x%px\n", vmalloc(64));
+ pr_info("vmalloc(64) = 0x%px\n", vmalloc(64));
/*
* Add elements to a list. They should only appear as orphan
@@ -66,7 +66,7 @@ static int kmemleak_test_init(void)
*/
for (i = 0; i < 10; i++) {
elem = kzalloc(sizeof(*elem), GFP_KERNEL);
- pr_info("kzalloc(sizeof(*elem)) = %p\n", elem);
+ pr_info("kzalloc(sizeof(*elem)) = 0x%px\n", elem);
if (!elem)
return -ENOMEM;
INIT_LIST_HEAD(&elem->list);
@@ -75,11 +75,11 @@ static int kmemleak_test_init(void)
for_each_possible_cpu(i) {
per_cpu(kmemleak_test_pointer, i) = kmalloc(129, GFP_KERNEL);
- pr_info("kmalloc(129) = %p\n",
+ pr_info("kmalloc(129) = 0x%px\n",
per_cpu(kmemleak_test_pointer, i));
}
- pr_info("__alloc_percpu(64, 4) = %p\n", __alloc_percpu(64, 4));
+ pr_info("__alloc_percpu(64, 4) = 0x%px\n", __alloc_percpu(64, 4));
return 0;
}
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-02-06 11:46 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-02-06 11:45 [PATCH 0/2] mm: kmemleak: Usability improvements Catalin Marinas
2025-02-06 11:45 ` [PATCH 1/2] mm: kmemleak: Add support for dumping physical and __percpu object info Catalin Marinas
2025-02-06 11:45 ` [PATCH 2/2] samples: kmemleak: Print the raw pointers for debugging purposes Catalin Marinas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox