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

tracing: Add __cpumask to denote a trace event field that is a cpumask_t

The trace events have a __bitmask field that can be used for anything
that requires bitmasks. Although currently it is only used for CPU
masks, it could be used in the future for any type of bitmasks.

There is some user space tooling that wants to know if a field is a CPU
mask and not just some random unsigned long bitmask. Introduce
"__cpumask()" helper functions that work the same as the current
__bitmask() helpers but displays in the format file:

field:__data_loc cpumask_t *[] mask; offset:36; size:4; signed:0;

Instead of:

field:__data_loc unsigned long[] mask; offset:32; size:4; signed:0;

The main difference is the type. Instead of "unsigned long" it is
"cpumask_t *". Note, this type field needs to be a real type in the
__dynamic_array() logic that both __cpumask and__bitmask use, but the
comparison field requires it to be a scalar type whereas cpumask_t is a
structure (non-scalar). But everything works when making it a pointer.

Valentin added changes to remove the need of passing in "nr_bits" and the
__cpumask will always use nr_cpumask_bits as its size.

Link: https://lkml.kernel.org/r/20221014080456.1d32b989@rorschach.local.home

Requested-by: Valentin Schneider <vschneid@redhat.com>
Reviewed-by: Valentin Schneider <vschneid@redhat.com>
Signed-off-by: Valentin Schneider <vschneid@redhat.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

+91 -9
+6
include/trace/bpf_probe.h
··· 21 21 #undef __get_bitmask 22 22 #define __get_bitmask(field) (char *)__get_dynamic_array(field) 23 23 24 + #undef __get_cpumask 25 + #define __get_cpumask(field) (char *)__get_dynamic_array(field) 26 + 24 27 #undef __get_sockaddr 25 28 #define __get_sockaddr(field) ((struct sockaddr *)__get_dynamic_array(field)) 26 29 ··· 42 39 43 40 #undef __get_rel_bitmask 44 41 #define __get_rel_bitmask(field) (char *)__get_rel_dynamic_array(field) 42 + 43 + #undef __get_rel_cpumask 44 + #define __get_rel_cpumask(field) (char *)__get_rel_dynamic_array(field) 45 45 46 46 #undef __get_rel_sockaddr 47 47 #define __get_rel_sockaddr(field) ((struct sockaddr *)__get_rel_dynamic_array(field))
+6
include/trace/perf.h
··· 21 21 #undef __get_bitmask 22 22 #define __get_bitmask(field) (char *)__get_dynamic_array(field) 23 23 24 + #undef __get_cpumask 25 + #define __get_cpumask(field) (char *)__get_dynamic_array(field) 26 + 24 27 #undef __get_sockaddr 25 28 #define __get_sockaddr(field) ((struct sockaddr *)__get_dynamic_array(field)) 26 29 ··· 43 40 44 41 #undef __get_rel_bitmask 45 42 #define __get_rel_bitmask(field) (char *)__get_rel_dynamic_array(field) 43 + 44 + #undef __get_rel_cpumask 45 + #define __get_rel_cpumask(field) (char *)__get_rel_dynamic_array(field) 46 46 47 47 #undef __get_rel_sockaddr 48 48 #define __get_rel_sockaddr(field) ((struct sockaddr *)__get_rel_dynamic_array(field))
+6
include/trace/stages/stage1_struct_define.h
··· 32 32 #undef __bitmask 33 33 #define __bitmask(item, nr_bits) __dynamic_array(char, item, -1) 34 34 35 + #undef __cpumask 36 + #define __cpumask(item) __dynamic_array(char, item, -1) 37 + 35 38 #undef __sockaddr 36 39 #define __sockaddr(field, len) __dynamic_array(u8, field, len) 37 40 ··· 49 46 50 47 #undef __rel_bitmask 51 48 #define __rel_bitmask(item, nr_bits) __rel_dynamic_array(char, item, -1) 49 + 50 + #undef __rel_cpumask 51 + #define __rel_cpumask(item) __rel_dynamic_array(char, item, -1) 52 52 53 53 #undef __rel_sockaddr 54 54 #define __rel_sockaddr(field, len) __rel_dynamic_array(u8, field, len)
+6
include/trace/stages/stage2_data_offsets.h
··· 38 38 #undef __bitmask 39 39 #define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1) 40 40 41 + #undef __cpumask 42 + #define __cpumask(item) __dynamic_array(unsigned long, item, -1) 43 + 41 44 #undef __sockaddr 42 45 #define __sockaddr(field, len) __dynamic_array(u8, field, len) 43 46 ··· 55 52 56 53 #undef __rel_bitmask 57 54 #define __rel_bitmask(item, nr_bits) __rel_dynamic_array(unsigned long, item, -1) 55 + 56 + #undef __rel_cpumask 57 + #define __rel_cpumask(item) __rel_dynamic_array(unsigned long, item, -1) 58 58 59 59 #undef __rel_sockaddr 60 60 #define __rel_sockaddr(field, len) __rel_dynamic_array(u8, field, len)
+6
include/trace/stages/stage3_trace_output.h
··· 42 42 trace_print_bitmask_seq(p, __bitmask, __bitmask_size); \ 43 43 }) 44 44 45 + #undef __get_cpumask 46 + #define __get_cpumask(field) __get_bitmask(field) 47 + 45 48 #undef __get_rel_bitmask 46 49 #define __get_rel_bitmask(field) \ 47 50 ({ \ ··· 53 50 __bitmask_size = __get_rel_dynamic_array_len(field); \ 54 51 trace_print_bitmask_seq(p, __bitmask, __bitmask_size); \ 55 52 }) 53 + 54 + #undef __get_rel_cpumask 55 + #define __get_rel_cpumask(field) __get_rel_bitmask(field) 56 56 57 57 #undef __get_sockaddr 58 58 #define __get_sockaddr(field) ((struct sockaddr *)__get_dynamic_array(field))
+6
include/trace/stages/stage4_event_fields.h
··· 46 46 #undef __bitmask 47 47 #define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1) 48 48 49 + #undef __cpumask 50 + #define __cpumask(item) __dynamic_array(cpumask_t *, item, -1) 51 + 49 52 #undef __sockaddr 50 53 #define __sockaddr(field, len) __dynamic_array(u8, field, len) 51 54 ··· 66 63 67 64 #undef __rel_bitmask 68 65 #define __rel_bitmask(item, nr_bits) __rel_dynamic_array(unsigned long, item, -1) 66 + 67 + #undef __rel_cpumask 68 + #define __rel_cpumask(item) __rel_dynamic_array(cpumask_t *, item, -1) 69 69 70 70 #undef __rel_sockaddr 71 71 #define __rel_sockaddr(field, len) __rel_dynamic_array(u8, field, len)
+6
include/trace/stages/stage5_get_offsets.h
··· 82 82 #define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, \ 83 83 __bitmask_size_in_longs(nr_bits)) 84 84 85 + #undef __cpumask 86 + #define __cpumask(item) __bitmask(item, nr_cpumask_bits) 87 + 85 88 #undef __rel_bitmask 86 89 #define __rel_bitmask(item, nr_bits) __rel_dynamic_array(unsigned long, item, \ 87 90 __bitmask_size_in_longs(nr_bits)) 91 + 92 + #undef __rel_cpumask 93 + #define __rel_cpumask(item) __rel_bitmask(item, nr_cpumask_bits) 88 94 89 95 #undef __sockaddr 90 96 #define __sockaddr(field, len) __dynamic_array(u8, field, len)
+20
include/trace/stages/stage6_event_callback.h
··· 57 57 #define __assign_bitmask(dst, src, nr_bits) \ 58 58 memcpy(__get_bitmask(dst), (src), __bitmask_size_in_bytes(nr_bits)) 59 59 60 + #undef __cpumask 61 + #define __cpumask(item) __dynamic_array(unsigned long, item, -1) 62 + 63 + #undef __get_cpumask 64 + #define __get_cpumask(field) (char *)__get_dynamic_array(field) 65 + 66 + #undef __assign_cpumask 67 + #define __assign_cpumask(dst, src) \ 68 + memcpy(__get_cpumask(dst), (src), __bitmask_size_in_bytes(nr_cpumask_bits)) 69 + 60 70 #undef __sockaddr 61 71 #define __sockaddr(field, len) __dynamic_array(u8, field, len) 62 72 ··· 107 97 #undef __assign_rel_bitmask 108 98 #define __assign_rel_bitmask(dst, src, nr_bits) \ 109 99 memcpy(__get_rel_bitmask(dst), (src), __bitmask_size_in_bytes(nr_bits)) 100 + 101 + #undef __rel_cpumask 102 + #define __rel_cpumask(item) __rel_dynamic_array(unsigned long, item, -1) 103 + 104 + #undef __get_rel_cpumask 105 + #define __get_rel_cpumask(field) (char *)__get_rel_dynamic_array(field) 106 + 107 + #undef __assign_rel_cpumask 108 + #define __assign_rel_cpumask(dst, src) \ 109 + memcpy(__get_rel_cpumask(dst), (src), __bitmask_size_in_bytes(nr_cpumask_bits)) 110 110 111 111 #undef __rel_sockaddr 112 112 #define __rel_sockaddr(field, len) __rel_dynamic_array(u8, field, len)
+2
include/trace/stages/stage7_class_define.h
··· 13 13 #undef __get_dynamic_array_len 14 14 #undef __get_str 15 15 #undef __get_bitmask 16 + #undef __get_cpumask 16 17 #undef __get_sockaddr 17 18 #undef __get_rel_dynamic_array 18 19 #undef __get_rel_dynamic_array_len 19 20 #undef __get_rel_str 20 21 #undef __get_rel_bitmask 22 + #undef __get_rel_cpumask 21 23 #undef __get_rel_sockaddr 22 24 #undef __print_array 23 25 #undef __print_hex_dump
+1 -1
samples/trace_events/trace-events-sample.c
··· 50 50 51 51 trace_foo_with_template_print("I have to be different", cnt); 52 52 53 - trace_foo_rel_loc("Hello __rel_loc", cnt, bitmask); 53 + trace_foo_rel_loc("Hello __rel_loc", cnt, bitmask, current->cpus_ptr); 54 54 } 55 55 56 56 static void simple_thread_func(int cnt)
+26 -8
samples/trace_events/trace-events-sample.h
··· 200 200 * 201 201 * __assign_bitmask(target_cpus, cpumask_bits(bar), nr_cpumask_bits); 202 202 * 203 + * __cpumask: This is pretty much the same as __bitmask but is specific for 204 + * CPU masks. The type displayed to the user via the format files will 205 + * be "cpumaks_t" such that user space may deal with them differently 206 + * if they choose to do so, and the bits is always set to nr_cpumask_bits. 207 + * 208 + * __cpumask(target_cpu) 209 + * 210 + * To assign a cpumask, use the __assign_cpumask() helper macro. 211 + * 212 + * __assign_cpumask(target_cpus, cpumask_bits(bar)); 203 213 * 204 214 * fast_assign: This is a C like function that is used to store the items 205 215 * into the ring buffer. A special variable called "__entry" will be the ··· 222 212 * This is also used to print out the data from the trace files. 223 213 * Again, the __entry macro is used to access the data from the ring buffer. 224 214 * 225 - * Note, __dynamic_array, __string, and __bitmask require special helpers 226 - * to access the data. 215 + * Note, __dynamic_array, __string, __bitmask and __cpumask require special 216 + * helpers to access the data. 227 217 * 228 218 * For __dynamic_array(int, foo, bar) use __get_dynamic_array(foo) 229 219 * Use __get_dynamic_array_len(foo) to get the length of the array ··· 235 225 * For __string(foo, bar) use __get_str(foo) 236 226 * 237 227 * For __bitmask(target_cpus, nr_cpumask_bits) use __get_bitmask(target_cpus) 228 + * 229 + * For __cpumask(target_cpus) use __get_cpumask(target_cpus) 238 230 * 239 231 * 240 232 * Note, that for both the assign and the printk, __entry is the handler ··· 300 288 __dynamic_array(int, list, __length_of(lst)) 301 289 __string( str, string ) 302 290 __bitmask( cpus, num_possible_cpus() ) 291 + __cpumask( cpum ) 303 292 __vstring( vstr, fmt, va ) 304 293 ), 305 294 ··· 312 299 __assign_str(str, string); 313 300 __assign_vstr(vstr, fmt, va); 314 301 __assign_bitmask(cpus, cpumask_bits(mask), num_possible_cpus()); 302 + __assign_cpumask(cpum, cpumask_bits(mask)); 315 303 ), 316 304 317 - TP_printk("foo %s %d %s %s %s %s (%s) %s", __entry->foo, __entry->bar, 305 + TP_printk("foo %s %d %s %s %s %s (%s) (%s) %s", __entry->foo, __entry->bar, 318 306 319 307 /* 320 308 * Notice here the use of some helper functions. This includes: ··· 359 345 __print_array(__get_dynamic_array(list), 360 346 __get_dynamic_array_len(list) / sizeof(int), 361 347 sizeof(int)), 362 - __get_str(str), __get_bitmask(cpus), __get_str(vstr)) 348 + __get_str(str), __get_bitmask(cpus), __get_cpumask(cpus), 349 + __get_str(vstr)) 363 350 ); 364 351 365 352 /* ··· 557 542 558 543 TRACE_EVENT(foo_rel_loc, 559 544 560 - TP_PROTO(const char *foo, int bar, unsigned long *mask), 545 + TP_PROTO(const char *foo, int bar, unsigned long *mask, const cpumask_t *cpus), 561 546 562 - TP_ARGS(foo, bar, mask), 547 + TP_ARGS(foo, bar, mask, cpus), 563 548 564 549 TP_STRUCT__entry( 565 550 __rel_string( foo, foo ) 566 551 __field( int, bar ) 567 552 __rel_bitmask( bitmask, 568 553 BITS_PER_BYTE * sizeof(unsigned long) ) 554 + __rel_cpumask( cpumask ) 569 555 ), 570 556 571 557 TP_fast_assign( ··· 574 558 __entry->bar = bar; 575 559 __assign_rel_bitmask(bitmask, mask, 576 560 BITS_PER_BYTE * sizeof(unsigned long)); 561 + __assign_rel_cpumask(cpumask, cpus); 577 562 ), 578 563 579 - TP_printk("foo_rel_loc %s, %d, %s", __get_rel_str(foo), __entry->bar, 580 - __get_rel_bitmask(bitmask)) 564 + TP_printk("foo_rel_loc %s, %d, %s, %s", __get_rel_str(foo), __entry->bar, 565 + __get_rel_bitmask(bitmask), 566 + __get_rel_cpumask(cpumask)) 581 567 ); 582 568 #endif 583 569