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

[akpm@linux-foundation.org: remove stray newline from struct allocinfo_private]
Link: https://lkml.kernel.org/r/20240514163128.3662251-1-surenb@google.com
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Cc: Kent Overstreet <kent.overstreet@linux.dev>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by Suren Baghdasaryan and committed by Andrew Morton a38568a0 8e0545c8

+35 -17
+3 -2
Documentation/filesystems/proc.rst
··· 961 base. Each allocation in the code is identified by its source file, line 962 number, module (if originates from a loadable module) and the function calling 963 the allocation. The number of bytes allocated and number of calls at each 964 - location are reported. 965 966 Example output. 967 968 :: 969 970 - > sort -rn /proc/allocinfo 971 127664128 31168 mm/page_ext.c:270 func:alloc_page_ext 972 56373248 4737 mm/slub.c:2259 func:alloc_slab_page 973 14880768 3633 mm/readahead.c:247 func:page_cache_ra_unbounded
··· 961 base. Each allocation in the code is identified by its source file, line 962 number, module (if originates from a loadable module) and the function calling 963 the allocation. The number of bytes allocated and number of calls at each 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. 966 967 Example output. 968 969 :: 970 971 + > tail -n +3 /proc/allocinfo | sort -rn 972 127664128 31168 mm/page_ext.c:270 func:alloc_page_ext 973 56373248 4737 mm/slub.c:2259 func:alloc_slab_page 974 14880768 3633 mm/readahead.c:247 func:page_cache_ra_unbounded
+32 -15
lib/alloc_tag.c
··· 16 DEFINE_STATIC_KEY_MAYBE(CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT, 17 mem_alloc_profiling_key); 18 19 static void *allocinfo_start(struct seq_file *m, loff_t *pos) 20 { 21 - struct codetag_iterator *iter; 22 struct codetag *ct; 23 loff_t node = *pos; 24 25 - iter = kzalloc(sizeof(*iter), GFP_KERNEL); 26 - m->private = iter; 27 - if (!iter) 28 return NULL; 29 30 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) 33 node--; 34 35 - return ct ? iter : NULL; 36 } 37 38 static void *allocinfo_next(struct seq_file *m, void *arg, loff_t *pos) 39 { 40 - struct codetag_iterator *iter = (struct codetag_iterator *)arg; 41 - struct codetag *ct = codetag_next_ct(iter); 42 43 (*pos)++; 44 if (!ct) 45 return NULL; 46 47 - return iter; 48 } 49 50 static void allocinfo_stop(struct seq_file *m, void *arg) 51 { 52 - struct codetag_iterator *iter = (struct codetag_iterator *)m->private; 53 54 - if (iter) { 55 codetag_lock_module_list(alloc_tag_cttype, false); 56 - kfree(iter); 57 } 58 } 59 60 static void alloc_tag_to_text(struct seq_buf *out, struct codetag *ct) ··· 84 85 static int allocinfo_show(struct seq_file *m, void *arg) 86 { 87 - struct codetag_iterator *iter = (struct codetag_iterator *)arg; 88 char *bufp; 89 size_t n = seq_get_buf(m, &bufp); 90 struct seq_buf buf; 91 92 seq_buf_init(&buf, bufp, n); 93 - alloc_tag_to_text(&buf, iter->ct); 94 seq_commit(m, seq_buf_used(&buf)); 95 return 0; 96 }
··· 16 DEFINE_STATIC_KEY_MAYBE(CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT, 17 mem_alloc_profiling_key); 18 19 + struct allocinfo_private { 20 + struct codetag_iterator iter; 21 + bool print_header; 22 + }; 23 + 24 static void *allocinfo_start(struct seq_file *m, loff_t *pos) 25 { 26 + struct allocinfo_private *priv; 27 struct codetag *ct; 28 loff_t node = *pos; 29 30 + priv = kzalloc(sizeof(*priv), GFP_KERNEL); 31 + m->private = priv; 32 + if (!priv) 33 return NULL; 34 35 + priv->print_header = (node == 0); 36 codetag_lock_module_list(alloc_tag_cttype, true); 37 + priv->iter = codetag_get_ct_iter(alloc_tag_cttype); 38 + while ((ct = codetag_next_ct(&priv->iter)) != NULL && node) 39 node--; 40 41 + return ct ? priv : NULL; 42 } 43 44 static void *allocinfo_next(struct seq_file *m, void *arg, loff_t *pos) 45 { 46 + struct allocinfo_private *priv = (struct allocinfo_private *)arg; 47 + struct codetag *ct = codetag_next_ct(&priv->iter); 48 49 (*pos)++; 50 if (!ct) 51 return NULL; 52 53 + return priv; 54 } 55 56 static void allocinfo_stop(struct seq_file *m, void *arg) 57 { 58 + struct allocinfo_private *priv = (struct allocinfo_private *)m->private; 59 60 + if (priv) { 61 codetag_lock_module_list(alloc_tag_cttype, false); 62 + kfree(priv); 63 } 64 + } 65 + 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 73 static void alloc_tag_to_text(struct seq_buf *out, struct codetag *ct) ··· 71 72 static int allocinfo_show(struct seq_file *m, void *arg) 73 { 74 + struct allocinfo_private *priv = (struct allocinfo_private *)arg; 75 char *bufp; 76 size_t n = seq_get_buf(m, &bufp); 77 struct seq_buf buf; 78 79 seq_buf_init(&buf, bufp, n); 80 + if (priv->print_header) { 81 + print_allocinfo_header(&buf); 82 + priv->print_header = false; 83 + } 84 + alloc_tag_to_text(&buf, priv->iter.ct); 85 seq_commit(m, seq_buf_used(&buf)); 86 return 0; 87 }