From 891d9b3eb6b715ea39f7a53d1d242d3f679bf61d Mon Sep 17 00:00:00 2001 From: Faiyaz Mohammed Date: Fri, 16 Oct 2020 12:30:12 +0530 Subject: [PATCH] mm: slub: update slab_alloc interface to capture slab stacks Update /sys/kernel/debug/slab/alloc_trace interface to capture slab stack along with slab object details. Now output of alloc_trace is: alloc_list: call_site=mempool_alloc_slab+0x1c/0x28 count=2 object_size=1024 slab_size=1472 slab_name=sgpool-32 mempool_alloc_slab+0x1c/0x28 mempool_init_node+0xdc/0x238 mempool_create+0x58/0x88 sg_pool_init+0x70/0xf8 do_one_initcall+0x15c/0x2e8 kernel_init_freeable+0x334/0x3d8 kernel_init+0x18/0x298 ret_from_fork+0x10/0x18. Change-Id: I19da702bfd22e5526e2c9a04d22717dc70700ae7 Signed-off-by: Faiyaz Mohammed --- mm/slub.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/mm/slub.c b/mm/slub.c index 331bda58d643..e200fbc1b985 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -4568,6 +4568,9 @@ struct location { long max_pid; DECLARE_BITMAP(cpus, NR_CPUS); nodemask_t nodes; +#ifdef CONFIG_STACKTRACE + unsigned long addrs[TRACK_ADDRS_COUNT]; /* Called from address */ +#endif }; struct loc_track { @@ -4610,6 +4613,7 @@ static int add_location(struct loc_track *t, struct kmem_cache *s, struct location *l; unsigned long caddr; unsigned long age = jiffies - track->when; + unsigned int i = 0; start = -1; end = t->count; @@ -4667,6 +4671,15 @@ static int add_location(struct loc_track *t, struct kmem_cache *s, t->count++; l->count = 1; l->addr = track->addr; +#ifdef CONFIG_STACKTRACE + for (i = 0; i < TRACK_ADDRS_COUNT; i++) + if (l->addrs[i]) { + l->addrs[i] = track->addrs[i]; + continue; + } else + break; + +#endif l->sum_time = age; l->min_time = age; l->max_time = age; @@ -6126,10 +6139,19 @@ static int alloc_trace_locations(struct seq_file *seq, struct kmem_cache *s, for (i = 0; i < t.count; i++) { struct location *l = &t.loc[i]; + unsigned int j = 0; seq_printf(seq, "alloc_list: call_site=%pS count=%zu object_size=%zu slab_size=%zu slab_name=%s\n", l->addr, l->count, s->object_size, s->size, s->name); +#ifdef CONFIG_STACKTRACE + for (j = 0; j < TRACK_ADDRS_COUNT; j++) + if (l->addrs[j]) { + seq_printf(seq, "%pS\n", l->addrs[j]); + continue; + } else + break; +#endif } free_loc_track(&t);