mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 14:19:09 -04:00
mm: slub: Add debugfs interface to capture slub allocs owner
With kmem event we were missing number of allocs and frees due to high frequency of event occurrence. So added debugfs interface to capture the slub alloc owners from slab list and it prints data using sequential file interface when we execute the "cat /sys/kernel/debug/slab/alloc_trace" command. Change-Id: I72eb5a21cc20a046f04d88d4dfbafa5cf378805a Signed-off-by: Faiyaz Mohammed <faiyazm@codeaurora.org>
This commit is contained in:
parent
a344fa7c85
commit
0414f5d0d3
1 changed files with 99 additions and 0 deletions
99
mm/slub.c
99
mm/slub.c
|
|
@ -37,6 +37,10 @@
|
|||
|
||||
#include <trace/events/kmem.h>
|
||||
|
||||
#ifdef CONFIG_SLUB_DEBUG
|
||||
#include <linux/debugfs.h>
|
||||
#endif
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
/*
|
||||
|
|
@ -5910,6 +5914,85 @@ struct saved_alias {
|
|||
|
||||
static struct saved_alias *alias_list;
|
||||
|
||||
#ifdef CONFIG_SLUB_DEBUG
|
||||
static struct dentry *slab_debugfs_top;
|
||||
|
||||
static int alloc_trace_locations(struct seq_file *seq, struct kmem_cache *s,
|
||||
enum track_item alloc)
|
||||
{
|
||||
unsigned long i;
|
||||
struct loc_track t = { 0, 0, NULL };
|
||||
int node;
|
||||
unsigned long *map = kmalloc(BITS_TO_LONGS(oo_objects(s->max)) *
|
||||
sizeof(unsigned long), GFP_KERNEL);
|
||||
struct kmem_cache_node *n;
|
||||
|
||||
if (!map || !alloc_loc_track(&t, PAGE_SIZE / sizeof(struct location),
|
||||
GFP_KERNEL)) {
|
||||
kfree(map);
|
||||
return -ENOMEM;
|
||||
}
|
||||
/* Push back cpu slabs */
|
||||
flush_all(s);
|
||||
|
||||
for_each_kmem_cache_node(s, node, n) {
|
||||
unsigned long flags;
|
||||
struct page *page;
|
||||
|
||||
if (!atomic_long_read(&n->nr_slabs))
|
||||
continue;
|
||||
|
||||
spin_lock_irqsave(&n->list_lock, flags);
|
||||
list_for_each_entry(page, &n->partial, lru)
|
||||
process_slab(&t, s, page, alloc, map);
|
||||
list_for_each_entry(page, &n->full, lru)
|
||||
process_slab(&t, s, page, alloc, map);
|
||||
spin_unlock_irqrestore(&n->list_lock, flags);
|
||||
}
|
||||
|
||||
for (i = 0; i < t.count; i++) {
|
||||
struct location *l = &t.loc[i];
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
free_loc_track(&t);
|
||||
kfree(map);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int slab_debug_alloc_trace(struct seq_file *seq,
|
||||
void *ignored)
|
||||
{
|
||||
|
||||
struct kmem_cache *slab;
|
||||
|
||||
list_for_each_entry(slab, &slab_caches, list) {
|
||||
if (!(slab->flags & SLAB_STORE_USER))
|
||||
continue;
|
||||
alloc_trace_locations(seq, slab, TRACK_ALLOC);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int slab_debug_alloc_trace_open(struct inode *inode,
|
||||
struct file *file)
|
||||
{
|
||||
return single_open(file, slab_debug_alloc_trace,
|
||||
inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations slab_debug_alloc_fops = {
|
||||
.open = slab_debug_alloc_trace_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
#endif
|
||||
|
||||
static int sysfs_slab_alias(struct kmem_cache *s, const char *name)
|
||||
{
|
||||
struct saved_alias *al;
|
||||
|
|
@ -5956,6 +6039,22 @@ static int __init slab_sysfs_init(void)
|
|||
s->name);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SLUB_DEBUG
|
||||
if (slub_debug) {
|
||||
slab_debugfs_top = debugfs_create_dir("slab", NULL);
|
||||
if (!slab_debugfs_top) {
|
||||
pr_err("Couldn't create slab debugfs directory\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!debugfs_create_file("alloc_trace", 0400, slab_debugfs_top,
|
||||
NULL, &slab_debug_alloc_fops)) {
|
||||
pr_err("Couldn't create slab/tests debugfs directory\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
while (alias_list) {
|
||||
struct saved_alias *al = alias_list;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue