Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

alloc_tag: mark inaccurate allocation counters in /proc/allocinfo output

While rare, memory allocation profiling can contain inaccurate counters if
slab object extension vector allocation fails. That allocation might
succeed later but prior to that, slab allocations that would have used
that object extension vector will not be accounted for. To indicate
incorrect counters, "accurate:no" marker is appended to the call site line
in the /proc/allocinfo output. Bump up /proc/allocinfo version to reflect
the change in the file format and update documentation.

Example output with invalid counters:
allocinfo - version: 2.0
0 0 arch/x86/kernel/kdebugfs.c:105 func:create_setup_data_nodes
0 0 arch/x86/kernel/alternative.c:2090 func:alternatives_smp_module_add
0 0 arch/x86/kernel/alternative.c:127 func:__its_alloc accurate:no
0 0 arch/x86/kernel/fpu/regset.c:160 func:xstateregs_set
0 0 arch/x86/kernel/fpu/xstate.c:1590 func:fpstate_realloc
0 0 arch/x86/kernel/cpu/aperfmperf.c:379 func:arch_enable_hybrid_capacity_scale
0 0 arch/x86/kernel/cpu/amd_cache_disable.c:258 func:init_amd_l3_attrs
49152 48 arch/x86/kernel/cpu/mce/core.c:2709 func:mce_device_create accurate:no
32768 1 arch/x86/kernel/cpu/mce/genpool.c:132 func:mce_gen_pool_create
0 0 arch/x86/kernel/cpu/mce/amd.c:1341 func:mce_threshold_create_device

[surenb@google.com: document new "accurate:no" marker]
Fixes: 39d117e04d15 ("alloc_tag: mark inaccurate allocation counters in /proc/allocinfo output")
[akpm@linux-foundation.org: simplification per Usama, reflow text]
[akpm@linux-foundation.org: add newline to prevent docs warning, per Randy]
Link: https://lkml.kernel.org/r/20250915230224.4115531-1-surenb@google.com
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Suggested-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
Acked-by: Usama Arif <usamaarif642@gmail.com>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Cc: David Rientjes <rientjes@google.com>
Cc: David Wang <00107082@163.com>
Cc: Kent Overstreet <kent.overstreet@linux.dev>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Sourav Panda <souravpanda@google.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Suren Baghdasaryan and committed by
Andrew Morton
b9e2f58f 5e1953dc

+34 -2
+13
Documentation/filesystems/proc.rst
··· 1009 1009 the allocation. The number of bytes allocated and number of calls at each 1010 1010 location are reported. The first line indicates the version of the file, the 1011 1011 second line is the header listing fields in the file. 1012 + If file version is 2.0 or higher then each line may contain additional 1013 + <key>:<value> pairs representing extra information about the call site. 1014 + For example if the counters are not accurate, the line will be appended with 1015 + "accurate:no" pair. 1016 + 1017 + Supported markers in v2: 1018 + accurate:no 1019 + 1020 + Absolute values of the counters in this line are not accurate 1021 + because of the failure to allocate memory to track some of the 1022 + allocations made at this location. Deltas in these counters are 1023 + accurate, therefore counters can be used to track allocation size 1024 + and count changes. 1012 1025 1013 1026 Example output. 1014 1027
+12
include/linux/alloc_tag.h
··· 221 221 ref->ct = NULL; 222 222 } 223 223 224 + static inline void alloc_tag_set_inaccurate(struct alloc_tag *tag) 225 + { 226 + tag->ct.flags |= CODETAG_FLAG_INACCURATE; 227 + } 228 + 229 + static inline bool alloc_tag_is_inaccurate(struct alloc_tag *tag) 230 + { 231 + return !!(tag->ct.flags & CODETAG_FLAG_INACCURATE); 232 + } 233 + 224 234 #define alloc_tag_record(p) ((p) = current->alloc_tag) 225 235 226 236 #else /* CONFIG_MEM_ALLOC_PROFILING */ ··· 240 230 static inline void alloc_tag_add(union codetag_ref *ref, struct alloc_tag *tag, 241 231 size_t bytes) {} 242 232 static inline void alloc_tag_sub(union codetag_ref *ref, size_t bytes) {} 233 + static inline void alloc_tag_set_inaccurate(struct alloc_tag *tag) {} 234 + static inline bool alloc_tag_is_inaccurate(struct alloc_tag *tag) { return false; } 243 235 #define alloc_tag_record(p) do {} while (0) 244 236 245 237 #endif /* CONFIG_MEM_ALLOC_PROFILING */
+4 -1
include/linux/codetag.h
··· 16 16 #define CODETAG_SECTION_START_PREFIX "__start_" 17 17 #define CODETAG_SECTION_STOP_PREFIX "__stop_" 18 18 19 + /* codetag flags */ 20 + #define CODETAG_FLAG_INACCURATE (1 << 0) 21 + 19 22 /* 20 23 * An instance of this structure is created in a special ELF section at every 21 24 * code location being tagged. At runtime, the special section is treated as 22 25 * an array of these. 23 26 */ 24 27 struct codetag { 25 - unsigned int flags; /* used in later patches */ 28 + unsigned int flags; 26 29 unsigned int lineno; 27 30 const char *modname; 28 31 const char *function;
+3 -1
lib/alloc_tag.c
··· 80 80 static void print_allocinfo_header(struct seq_buf *buf) 81 81 { 82 82 /* Output format version, so we can change it. */ 83 - seq_buf_printf(buf, "allocinfo - version: 1.0\n"); 83 + seq_buf_printf(buf, "allocinfo - version: 2.0\n"); 84 84 seq_buf_printf(buf, "# <size> <calls> <tag info>\n"); 85 85 } 86 86 ··· 92 92 93 93 seq_buf_printf(out, "%12lli %8llu ", bytes, counter.calls); 94 94 codetag_to_text(out, ct); 95 + if (unlikely(alloc_tag_is_inaccurate(tag))) 96 + seq_buf_printf(out, " accurate:no"); 95 97 seq_buf_putc(out, ' '); 96 98 seq_buf_putc(out, '\n'); 97 99 }
+2
mm/slub.c
··· 2143 2143 */ 2144 2144 if (likely(obj_exts)) 2145 2145 alloc_tag_add(&obj_exts->ref, current->alloc_tag, s->size); 2146 + else 2147 + alloc_tag_set_inaccurate(current->alloc_tag); 2146 2148 } 2147 2149 2148 2150 static inline void