Skip to content

Commit

Permalink
lib: add memory allocations report in show_mem()
Browse files Browse the repository at this point in the history
Include allocations in show_mem reports.

Link: https://lkml.kernel.org/r/[email protected]
Signed-off-by: Kent Overstreet <[email protected]>
Signed-off-by: Suren Baghdasaryan <[email protected]>
Reviewed-by: Vlastimil Babka <[email protected]>
Tested-by: Kees Cook <[email protected]>
Cc: Alexander Viro <[email protected]>
Cc: Alex Gaynor <[email protected]>
Cc: Alice Ryhl <[email protected]>
Cc: Andreas Hindborg <[email protected]>
Cc: Benno Lossin <[email protected]>
Cc: "Björn Roy Baron" <[email protected]>
Cc: Boqun Feng <[email protected]>
Cc: Christoph Lameter <[email protected]>
Cc: Dennis Zhou <[email protected]>
Cc: Gary Guo <[email protected]>
Cc: Miguel Ojeda <[email protected]>
Cc: Pasha Tatashin <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Tejun Heo <[email protected]>
Cc: Wedson Almeida Filho <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
  • Loading branch information
surenbaghdasaryan authored and akpm00 committed Apr 26, 2024
1 parent 9e54dd8 commit 1438d34
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 0 deletions.
7 changes: 7 additions & 0 deletions include/linux/alloc_tag.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ struct alloc_tag {

#ifdef CONFIG_MEM_ALLOC_PROFILING

struct codetag_bytes {
struct codetag *ct;
s64 bytes;
};

size_t alloc_tag_top_users(struct codetag_bytes *tags, size_t count, bool can_sleep);

static inline struct alloc_tag *ct_to_alloc_tag(struct codetag *ct)
{
return container_of(ct, struct alloc_tag, ct);
Expand Down
1 change: 1 addition & 0 deletions include/linux/codetag.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ struct codetag_iterator {
}

void codetag_lock_module_list(struct codetag_type *cttype, bool lock);
bool codetag_trylock_module_list(struct codetag_type *cttype);
struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype);
struct codetag *codetag_next_ct(struct codetag_iterator *iter);

Expand Down
38 changes: 38 additions & 0 deletions lib/alloc_tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,44 @@ static const struct seq_operations allocinfo_seq_op = {
.show = allocinfo_show,
};

size_t alloc_tag_top_users(struct codetag_bytes *tags, size_t count, bool can_sleep)
{
struct codetag_iterator iter;
struct codetag *ct;
struct codetag_bytes n;
unsigned int i, nr = 0;

if (can_sleep)
codetag_lock_module_list(alloc_tag_cttype, true);
else if (!codetag_trylock_module_list(alloc_tag_cttype))
return 0;

iter = codetag_get_ct_iter(alloc_tag_cttype);
while ((ct = codetag_next_ct(&iter))) {
struct alloc_tag_counters counter = alloc_tag_read(ct_to_alloc_tag(ct));

n.ct = ct;
n.bytes = counter.bytes;

for (i = 0; i < nr; i++)
if (n.bytes > tags[i].bytes)
break;

if (i < count) {
nr -= nr == count;
memmove(&tags[i + 1],
&tags[i],
sizeof(tags[0]) * (nr - i));
nr++;
tags[i] = n;
}
}

codetag_lock_module_list(alloc_tag_cttype, false);

return nr;
}

static void __init procfs_init(void)
{
proc_create_seq("allocinfo", 0444, NULL, &allocinfo_seq_op);
Expand Down
5 changes: 5 additions & 0 deletions lib/codetag.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ void codetag_lock_module_list(struct codetag_type *cttype, bool lock)
up_read(&cttype->mod_lock);
}

bool codetag_trylock_module_list(struct codetag_type *cttype)
{
return down_read_trylock(&cttype->mod_lock) != 0;
}

struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype)
{
struct codetag_iterator iter = {
Expand Down
26 changes: 26 additions & 0 deletions mm/show_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,4 +423,30 @@ void __show_mem(unsigned int filter, nodemask_t *nodemask, int max_zone_idx)
#ifdef CONFIG_MEMORY_FAILURE
printk("%lu pages hwpoisoned\n", atomic_long_read(&num_poisoned_pages));
#endif
#ifdef CONFIG_MEM_ALLOC_PROFILING
{
struct codetag_bytes tags[10];
size_t i, nr;

nr = alloc_tag_top_users(tags, ARRAY_SIZE(tags), false);
if (nr) {
pr_notice("Memory allocations:\n");
for (i = 0; i < nr; i++) {
struct codetag *ct = tags[i].ct;
struct alloc_tag *tag = ct_to_alloc_tag(ct);
struct alloc_tag_counters counter = alloc_tag_read(tag);

/* Same as alloc_tag_to_text() but w/o intermediate buffer */
if (ct->modname)
pr_notice("%12lli %8llu %s:%u [%s] func:%s\n",
counter.bytes, counter.calls, ct->filename,
ct->lineno, ct->modname, ct->function);
else
pr_notice("%12lli %8llu %s:%u func:%s\n",
counter.bytes, counter.calls, ct->filename,
ct->lineno, ct->function);
}
}
}
#endif
}

0 comments on commit 1438d34

Please sign in to comment.