2021-11-24 14:11:40

by Chen Jun

[permalink] [raw]
Subject: [PATCH] trace: Fix a kmemleak noise

when run
echo 'hist:key=common_pid.execname,common_timestamp' >
/sys/kernel/debug/tracing/events/xxx/trigger

many kmemleak reported
unreferenced object 0xffff0000c7ea4980 (size 128):
comm "bash", pid 338, jiffies 4294912626 (age 9339.324s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<00000000f3469921>] kmem_cache_alloc_trace+0x4c0/0x6f0
[<0000000054ca40c3>] hist_trigger_elt_data_alloc+0x140/0x178
[<00000000633bd154>] tracing_map_init+0x1f8/0x268
[<000000007e814ab9>] event_hist_trigger_func+0xca0/0x1ad0
[<00000000bf8520ed>] trigger_process_regex+0xd4/0x128
[<00000000f549355a>] event_trigger_write+0x7c/0x120
[<00000000b80f898d>] vfs_write+0xc4/0x380
[<00000000823e1055>] ksys_write+0x74/0xf8
[<000000008a9374aa>] __arm64_sys_write+0x24/0x30
[<0000000087124017>] do_el0_svc+0x88/0x1c0
[<00000000efd0dcd1>] el0_svc+0x1c/0x28
[<00000000dbfba9b3>] el0_sync_handler+0x88/0xc0
[<00000000e7399680>] el0_sync+0x148/0x180
unreferenced object 0xffff0000c7ea4980 (size 128):
comm "bash", pid 338, jiffies 4294912626 (age 9339.324s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<00000000f3469921>] kmem_cache_alloc_trace+0x4c0/0x6f0
[<0000000054ca40c3>] hist_trigger_elt_data_alloc+0x140/0x178
[<00000000633bd154>] tracing_map_init+0x1f8/0x268
[<000000007e814ab9>] event_hist_trigger_func+0xca0/0x1ad0
[<00000000bf8520ed>] trigger_process_regex+0xd4/0x128
[<00000000f549355a>] event_trigger_write+0x7c/0x120
[<00000000b80f898d>] vfs_write+0xc4/0x380
[<00000000823e1055>] ksys_write+0x74/0xf8
[<000000008a9374aa>] __arm64_sys_write+0x24/0x30
[<0000000087124017>] do_el0_svc+0x88/0x1c0
[<00000000efd0dcd1>] el0_svc+0x1c/0x28
[<00000000dbfba9b3>] el0_sync_handler+0x88/0xc0
[<00000000e7399680>] el0_sync+0x148/0x180

The reason is elts->pages[i] is alloced by get_zeroed_page.
and kmemleak will not scan the area alloced by get_zeroed_page.
The address stored in elts->pages will be regarded as leaked.

To fix this, call kmemleak_alloc to tell kmemleak to scan elts->pages[i]

Signed-off-by: Chen Jun <[email protected]>
---
kernel/trace/tracing_map.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c
index 4b50fc0cb12c..66307675d2a5 100644
--- a/kernel/trace/tracing_map.c
+++ b/kernel/trace/tracing_map.c
@@ -15,6 +15,7 @@
#include <linux/jhash.h>
#include <linux/slab.h>
#include <linux/sort.h>
+#include <linux/kmemleak.h>

#include "tracing_map.h"
#include "trace.h"
@@ -307,6 +308,7 @@ static void tracing_map_array_free(struct tracing_map_array *a)
for (i = 0; i < a->n_pages; i++) {
if (!a->pages[i])
break;
+ kmemleak_free(a->pages[i]);
free_page((unsigned long)a->pages[i]);
}

@@ -342,6 +344,7 @@ static struct tracing_map_array *tracing_map_array_alloc(unsigned int n_elts,
a->pages[i] = (void *)get_zeroed_page(GFP_KERNEL);
if (!a->pages[i])
goto free;
+ kmemleak_alloc(a->pages[i], PAGE_SIZE, 1, GFP_KERNEL);
}
out:
return a;
--
2.17.1



2021-11-24 15:16:21

by Steven Rostedt

[permalink] [raw]
Subject: Re: [PATCH] trace: Fix a kmemleak noise

On Wed, 24 Nov 2021 14:08:01 +0000
Chen Jun <[email protected]> wrote:

> The reason is elts->pages[i] is alloced by get_zeroed_page.
> and kmemleak will not scan the area alloced by get_zeroed_page.
> The address stored in elts->pages will be regarded as leaked.

Why doesn't kmemleak scan get_zeroed_page? And if that's the case, how does
all the other locations in the kernel that call get_zeroed_page handle this?

-- Steve

2021-11-25 01:49:53

by Chen Jun

[permalink] [raw]
Subject: Re: [PATCH] trace: Fix a kmemleak noise

$B:_(B 2021/11/24 23:16, Steven Rostedt $B<LF;(B:
Hi

> On Wed, 24 Nov 2021 14:08:01 +0000
> Chen Jun <[email protected]> wrote:
>
>> The reason is elts->pages[i] is alloced by get_zeroed_page.
>> and kmemleak will not scan the area alloced by get_zeroed_page.
>> The address stored in elts->pages will be regarded as leaked.
>
> Why doesn't kmemleak scan get_zeroed_page? And if that's the case, how does
> all the other locations in the kernel that call get_zeroed_page handle this?
> I think in most cases, the page do not contain pointers. But I am not
sure. Maybe we should better ask Catalin.

In block/blk-mq.c
blk_mq_alloc_rqs
.
page = alloc_pages_node(node,..
.
p = page_address(page);
/*$
* Allow kmemleak to scan these pages as they contain pointers
* to additional allocations like via ops->init_request().
*/$
kmemleak_alloc(p, order_to_size(this_order), 1, GFP_NOIO);

In lib/scatterlist.c
static struct scatterlist *sg_kmalloc(unsigned int nents, gfp_t gfp_mask)
{
if (nents == SG_MAX_SINGLE_ALLOC) {
/*
* Kmemleak doesn't track page allocations as they are not
* commonly used (in a raw form) for kernel data structures.
* As we chain together a list of pages and then a normal
* kmalloc (tracked by kmemleak), in order to for that last
* allocation not to become decoupled (and thus a
* false-positive) we need to inform kmemleak of all the
* intermediate allocations.
*/
void *ptr = (void *) __get_free_page(gfp_mask);
kmemleak_alloc(ptr, PAGE_SIZE, 1, gfp_mask);
return ptr;
.

> -- Steve
>


--
Regards
Chen Jun