Skip to content

Commit a38568a

Browse files
surenbaghdasaryanakpm00
authored andcommitted
lib: add version into /proc/allocinfo output
Add version string and a header at the beginning of /proc/allocinfo to allow later format changes. Example output: > head /proc/allocinfo allocinfo - version: 1.0 # <size> <calls> <tag info> 0 0 init/main.c:1314 func:do_initcalls 0 0 init/do_mounts.c:353 func:mount_nodev_root 0 0 init/do_mounts.c:187 func:mount_root_generic 0 0 init/do_mounts.c:158 func:do_mount_root 0 0 init/initramfs.c:493 func:unpack_to_rootfs 0 0 init/initramfs.c:492 func:unpack_to_rootfs 0 0 init/initramfs.c:491 func:unpack_to_rootfs 512 1 arch/x86/events/rapl.c:681 func:init_rapl_pmus 128 1 arch/x86/events/rapl.c:571 func:rapl_cpu_online [[email protected]: remove stray newline from struct allocinfo_private] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Suren Baghdasaryan <[email protected]> Reviewed-by: Pasha Tatashin <[email protected]> Reviewed-by: Kees Cook <[email protected]> Cc: Kent Overstreet <[email protected]> Cc: Vlastimil Babka <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 8e0545c commit a38568a

File tree

2 files changed

+35
-17
lines changed

2 files changed

+35
-17
lines changed

Documentation/filesystems/proc.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -961,13 +961,14 @@ Provides information about memory allocations at all locations in the code
961961
base. Each allocation in the code is identified by its source file, line
962962
number, module (if originates from a loadable module) and the function calling
963963
the allocation. The number of bytes allocated and number of calls at each
964-
location are reported.
964+
location are reported. The first line indicates the version of the file, the
965+
second line is the header listing fields in the file.
965966

966967
Example output.
967968

968969
::
969970

970-
> sort -rn /proc/allocinfo
971+
> tail -n +3 /proc/allocinfo | sort -rn
971972
127664128 31168 mm/page_ext.c:270 func:alloc_page_ext
972973
56373248 4737 mm/slub.c:2259 func:alloc_slab_page
973974
14880768 3633 mm/readahead.c:247 func:page_cache_ra_unbounded

lib/alloc_tag.c

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,47 +16,60 @@ EXPORT_SYMBOL(_shared_alloc_tag);
1616
DEFINE_STATIC_KEY_MAYBE(CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT,
1717
mem_alloc_profiling_key);
1818

19+
struct allocinfo_private {
20+
struct codetag_iterator iter;
21+
bool print_header;
22+
};
23+
1924
static void *allocinfo_start(struct seq_file *m, loff_t *pos)
2025
{
21-
struct codetag_iterator *iter;
26+
struct allocinfo_private *priv;
2227
struct codetag *ct;
2328
loff_t node = *pos;
2429

25-
iter = kzalloc(sizeof(*iter), GFP_KERNEL);
26-
m->private = iter;
27-
if (!iter)
30+
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
31+
m->private = priv;
32+
if (!priv)
2833
return NULL;
2934

35+
priv->print_header = (node == 0);
3036
codetag_lock_module_list(alloc_tag_cttype, true);
31-
*iter = codetag_get_ct_iter(alloc_tag_cttype);
32-
while ((ct = codetag_next_ct(iter)) != NULL && node)
37+
priv->iter = codetag_get_ct_iter(alloc_tag_cttype);
38+
while ((ct = codetag_next_ct(&priv->iter)) != NULL && node)
3339
node--;
3440

35-
return ct ? iter : NULL;
41+
return ct ? priv : NULL;
3642
}
3743

3844
static void *allocinfo_next(struct seq_file *m, void *arg, loff_t *pos)
3945
{
40-
struct codetag_iterator *iter = (struct codetag_iterator *)arg;
41-
struct codetag *ct = codetag_next_ct(iter);
46+
struct allocinfo_private *priv = (struct allocinfo_private *)arg;
47+
struct codetag *ct = codetag_next_ct(&priv->iter);
4248

4349
(*pos)++;
4450
if (!ct)
4551
return NULL;
4652

47-
return iter;
53+
return priv;
4854
}
4955

5056
static void allocinfo_stop(struct seq_file *m, void *arg)
5157
{
52-
struct codetag_iterator *iter = (struct codetag_iterator *)m->private;
58+
struct allocinfo_private *priv = (struct allocinfo_private *)m->private;
5359

54-
if (iter) {
60+
if (priv) {
5561
codetag_lock_module_list(alloc_tag_cttype, false);
56-
kfree(iter);
62+
kfree(priv);
5763
}
5864
}
5965

66+
static void print_allocinfo_header(struct seq_buf *buf)
67+
{
68+
/* Output format version, so we can change it. */
69+
seq_buf_printf(buf, "allocinfo - version: 1.0\n");
70+
seq_buf_printf(buf, "# <size> <calls> <tag info>\n");
71+
}
72+
6073
static void alloc_tag_to_text(struct seq_buf *out, struct codetag *ct)
6174
{
6275
struct alloc_tag *tag = ct_to_alloc_tag(ct);
@@ -71,13 +84,17 @@ static void alloc_tag_to_text(struct seq_buf *out, struct codetag *ct)
7184

7285
static int allocinfo_show(struct seq_file *m, void *arg)
7386
{
74-
struct codetag_iterator *iter = (struct codetag_iterator *)arg;
87+
struct allocinfo_private *priv = (struct allocinfo_private *)arg;
7588
char *bufp;
7689
size_t n = seq_get_buf(m, &bufp);
7790
struct seq_buf buf;
7891

7992
seq_buf_init(&buf, bufp, n);
80-
alloc_tag_to_text(&buf, iter->ct);
93+
if (priv->print_header) {
94+
print_allocinfo_header(&buf);
95+
priv->print_header = false;
96+
}
97+
alloc_tag_to_text(&buf, priv->iter.ct);
8198
seq_commit(m, seq_buf_used(&buf));
8299
return 0;
83100
}

0 commit comments

Comments
 (0)