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.

tracing: Add bitmask-list option for human-readable bitmask display

Add support for displaying bitmasks in human-readable list format (e.g.,
0,2-5,7) in addition to the default hexadecimal bitmap representation.
This is particularly useful when tracing CPU masks and other large
bitmasks where individual bit positions are more meaningful than their
hexadecimal encoding.

When the "bitmask-list" option is enabled, the printk "%*pbl" format
specifier is used to render bitmasks as comma-separated ranges, making
trace output easier to interpret for complex CPU configurations and
large bitmask values.

Link: https://patch.msgid.link/20251226160724.2246493-2-atomlin@atomlin.com
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

authored by

Aaron Tomlin and committed by
Steven Rostedt (Google)
2cddfc2e a4e0ea0e

+82 -11
+9
Documentation/trace/ftrace.rst
··· 1290 1290 This will be useful if you want to find out which hashed 1291 1291 value is corresponding to the real value in trace log. 1292 1292 1293 + bitmask-list 1294 + When enabled, bitmasks are displayed as a human-readable list of 1295 + ranges (e.g., 0,2-5,7) using the printk "%*pbl" format specifier. 1296 + When disabled (the default), bitmasks are displayed in the 1297 + traditional hexadecimal bitmap representation. The list format is 1298 + particularly useful for tracing CPU masks and other large bitmasks 1299 + where individual bit positions are more meaningful than their 1300 + hexadecimal encoding. 1301 + 1293 1302 record-cmd 1294 1303 When any event or tracer is enabled, a hook is enabled 1295 1304 in the sched_switch trace point to fill comm cache
+4 -4
include/linux/trace_events.h
··· 38 38 *symbol_array); 39 39 #endif 40 40 41 - const char *trace_print_bitmask_seq(struct trace_seq *p, void *bitmask_ptr, 41 + struct trace_iterator; 42 + struct trace_event; 43 + 44 + const char *trace_print_bitmask_seq(struct trace_iterator *iter, void *bitmask_ptr, 42 45 unsigned int bitmask_size); 43 46 44 47 const char *trace_print_hex_seq(struct trace_seq *p, ··· 56 53 trace_print_hex_dump_seq(struct trace_seq *p, const char *prefix_str, 57 54 int prefix_type, int rowsize, int groupsize, 58 55 const void *buf, size_t len, bool ascii); 59 - 60 - struct trace_iterator; 61 - struct trace_event; 62 56 63 57 int trace_raw_output_prep(struct trace_iterator *iter, 64 58 struct trace_event *event);
+11 -1
include/linux/trace_seq.h
··· 114 114 extern int trace_seq_path(struct trace_seq *s, const struct path *path); 115 115 116 116 extern void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, 117 - int nmaskbits); 117 + int nmaskbits); 118 + 119 + extern void trace_seq_bitmask_list(struct trace_seq *s, 120 + const unsigned long *maskp, 121 + int nmaskbits); 118 122 119 123 extern int trace_seq_hex_dump(struct trace_seq *s, const char *prefix_str, 120 124 int prefix_type, int rowsize, int groupsize, ··· 138 134 static inline void 139 135 trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, 140 136 int nmaskbits) 137 + { 138 + } 139 + 140 + static inline void 141 + trace_seq_bitmask_list(struct trace_seq *s, const unsigned long *maskp, 142 + int nmaskbits) 141 143 { 142 144 } 143 145
+2 -2
include/trace/stages/stage3_trace_output.h
··· 39 39 void *__bitmask = __get_dynamic_array(field); \ 40 40 unsigned int __bitmask_size; \ 41 41 __bitmask_size = __get_dynamic_array_len(field); \ 42 - trace_print_bitmask_seq(p, __bitmask, __bitmask_size); \ 42 + trace_print_bitmask_seq(iter, __bitmask, __bitmask_size); \ 43 43 }) 44 44 45 45 #undef __get_cpumask ··· 51 51 void *__bitmask = __get_rel_dynamic_array(field); \ 52 52 unsigned int __bitmask_size; \ 53 53 __bitmask_size = __get_rel_dynamic_array_len(field); \ 54 - trace_print_bitmask_seq(p, __bitmask, __bitmask_size); \ 54 + trace_print_bitmask_seq(iter, __bitmask, __bitmask_size); \ 55 55 }) 56 56 57 57 #undef __get_rel_cpumask
+1
kernel/trace/trace.h
··· 1411 1411 C(COPY_MARKER, "copy_trace_marker"), \ 1412 1412 C(PAUSE_ON_TRACE, "pause-on-trace"), \ 1413 1413 C(HASH_PTR, "hash-ptr"), /* Print hashed pointer */ \ 1414 + C(BITMASK_LIST, "bitmask-list"), \ 1414 1415 FUNCTION_FLAGS \ 1415 1416 FGRAPH_FLAGS \ 1416 1417 STACK_FLAGS \
+27 -3
kernel/trace/trace_output.c
··· 194 194 EXPORT_SYMBOL(trace_print_symbols_seq_u64); 195 195 #endif 196 196 197 + /** 198 + * trace_print_bitmask_seq - print a bitmask to a sequence buffer 199 + * @iter: The trace iterator for the current event instance 200 + * @bitmask_ptr: The pointer to the bitmask data 201 + * @bitmask_size: The size of the bitmask in bytes 202 + * 203 + * Prints a bitmask into a sequence buffer as either a hex string or a 204 + * human-readable range list, depending on the instance's "bitmask-list" 205 + * trace option. The bitmask is formatted into the iterator's temporary 206 + * scratchpad rather than the primary sequence buffer. This avoids 207 + * duplication and pointer-collision issues when the returned string is 208 + * processed by a "%s" specifier in a TP_printk() macro. 209 + * 210 + * Returns a pointer to the formatted string within the temporary buffer. 211 + */ 197 212 const char * 198 - trace_print_bitmask_seq(struct trace_seq *p, void *bitmask_ptr, 213 + trace_print_bitmask_seq(struct trace_iterator *iter, void *bitmask_ptr, 199 214 unsigned int bitmask_size) 200 215 { 201 - const char *ret = trace_seq_buffer_ptr(p); 216 + struct trace_seq *p = &iter->tmp_seq; 217 + const struct trace_array *tr = iter->tr; 218 + const char *ret; 202 219 203 - trace_seq_bitmask(p, bitmask_ptr, bitmask_size * 8); 220 + trace_seq_init(p); 221 + ret = trace_seq_buffer_ptr(p); 222 + 223 + if (tr->trace_flags & TRACE_ITER(BITMASK_LIST)) 224 + trace_seq_bitmask_list(p, bitmask_ptr, bitmask_size * 8); 225 + else 226 + trace_seq_bitmask(p, bitmask_ptr, bitmask_size * 8); 227 + 204 228 trace_seq_putc(p, 0); 205 229 206 230 return ret;
+28 -1
kernel/trace/trace_seq.c
··· 106 106 * Writes a ASCII representation of a bitmask string into @s. 107 107 */ 108 108 void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, 109 - int nmaskbits) 109 + int nmaskbits) 110 110 { 111 111 unsigned int save_len = s->seq.len; 112 112 ··· 123 123 } 124 124 } 125 125 EXPORT_SYMBOL_GPL(trace_seq_bitmask); 126 + 127 + /** 128 + * trace_seq_bitmask_list - write a bitmask array in its list representation 129 + * @s: trace sequence descriptor 130 + * @maskp: points to an array of unsigned longs that represent a bitmask 131 + * @nmaskbits: The number of bits that are valid in @maskp 132 + * 133 + * Writes a list representation (e.g., 0-3,5-7) of a bitmask string into @s. 134 + */ 135 + void trace_seq_bitmask_list(struct trace_seq *s, const unsigned long *maskp, 136 + int nmaskbits) 137 + { 138 + unsigned int save_len = s->seq.len; 139 + 140 + if (s->full) 141 + return; 142 + 143 + __trace_seq_init(s); 144 + 145 + seq_buf_printf(&s->seq, "%*pbl", nmaskbits, maskp); 146 + 147 + if (unlikely(seq_buf_has_overflowed(&s->seq))) { 148 + s->seq.len = save_len; 149 + s->full = 1; 150 + } 151 + } 152 + EXPORT_SYMBOL_GPL(trace_seq_bitmask_list); 126 153 127 154 /** 128 155 * trace_seq_vprintf - sequence printing of trace information