+Cc Douglas
On 14/10/22 08:04, Steven Rostedt wrote:
> From: Steven Rostedt (Google) <rostedt@goodmis.org>
>
> 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.
>
> Requested-by: Valentin Schneider <vschneid@redhat.com>
> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Thanks for spinning this out so quickly! I gave it a test against my IPI
tracepoints, it's working OK with one (expected) change:
[ipi:ipi_send_cpumask] function __get_cpumask not defined
CPU 0 is empty
CPU 1 is empty
CPU 3 is empty
cpus=4
echo-173 [002] 11.859745: ipi_send_cpumask: [FAILED TO PARSE] cpumask=ARRAY[02, 00, 00, 00, 00, 00, 00, 00] callsite=0xffffffff81121013
so libtraceevent is going to need updating - I'm happy to do that (if you
haven't done it already!)
Lastly, given all cpumasks have a (usable) size of nr_cpumask_bits, we can
factor out the size argument, see below. Regardless:
Reviewed-by: Valentin Schneider <vschneid@redhat.com>
---
diff --git a/include/trace/stages/stage1_struct_define.h b/include/trace/stages/stage1_struct_define.h
index e1a9b8462b418..b6a9e60755fe0 100644
--- a/include/trace/stages/stage1_struct_define.h
+++ b/include/trace/stages/stage1_struct_define.h
@@ -33,7 +33,7 @@
#define __bitmask(item, nr_bits) __dynamic_array(char, item, -1)
#undef __cpumask
-#define __cpumask(item, nr_bits) __dynamic_array(char, item, -1)
+#define __cpumask(item) __dynamic_array(char, item, -1)
#undef __sockaddr
#define __sockaddr(field, len) __dynamic_array(u8, field, len)
diff --git a/include/trace/stages/stage2_data_offsets.h b/include/trace/stages/stage2_data_offsets.h
index 4f096c30303b9..2c3838f5ee892 100644
--- a/include/trace/stages/stage2_data_offsets.h
+++ b/include/trace/stages/stage2_data_offsets.h
@@ -39,7 +39,7 @@
#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
#undef __cpumask
-#define __cpumask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
+#define __cpumask(item) __dynamic_array(unsigned long, item, -1)
#undef __sockaddr
#define __sockaddr(field, len) __dynamic_array(u8, field, len)
diff --git a/include/trace/stages/stage4_event_fields.h b/include/trace/stages/stage4_event_fields.h
index 11cf5550494d2..52ccf0b9b1765 100644
--- a/include/trace/stages/stage4_event_fields.h
+++ b/include/trace/stages/stage4_event_fields.h
@@ -47,7 +47,7 @@
#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
#undef __cpumask
-#define __cpumask(item, nr_bits) __dynamic_array(cpumask_t *, item, -1)
+#define __cpumask(item) __dynamic_array(cpumask_t *, item, -1)
#undef __sockaddr
#define __sockaddr(field, len) __dynamic_array(u8, field, len)
diff --git a/include/trace/stages/stage5_get_offsets.h b/include/trace/stages/stage5_get_offsets.h
index 0d9386b0d320c..b3934b74c72d0 100644
--- a/include/trace/stages/stage5_get_offsets.h
+++ b/include/trace/stages/stage5_get_offsets.h
@@ -83,7 +83,7 @@
__bitmask_size_in_longs(nr_bits))
#undef __cpumask
-#define __cpumask(item, nr_bits) __bitmask(item, nr_bits)
+#define __cpumask(item) __bitmask(item, nr_cpumask_bits)
#undef __rel_bitmask
#define __rel_bitmask(item, nr_bits) __rel_dynamic_array(unsigned long, item, \
diff --git a/include/trace/stages/stage6_event_callback.h b/include/trace/stages/stage6_event_callback.h
index 76774cb9acc89..e12e541fef42b 100644
--- a/include/trace/stages/stage6_event_callback.h
+++ b/include/trace/stages/stage6_event_callback.h
@@ -58,14 +58,14 @@
memcpy(__get_bitmask(dst), (src), __bitmask_size_in_bytes(nr_bits))
#undef __cpumask
-#define __cpumask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
+#define __cpumask(item) __dynamic_array(unsigned long, item, -1)
#undef __get_cpumask
#define __get_cpumask(field) (char *)__get_dynamic_array(field)
#undef __assign_cpumask
-#define __assign_cpumask(dst, src, nr_bits) \
- memcpy(__get_cpumask(dst), (src), __bitmask_size_in_bytes(nr_bits))
+#define __assign_cpumask(dst, src) \
+ memcpy(__get_cpumask(dst), (src), __bitmask_size_in_bytes(nr_cpumask_bits))
#undef __sockaddr
#define __sockaddr(field, len) __dynamic_array(u8, field, len)
@@ -21,6 +21,9 @@
#undef __get_bitmask
#define __get_bitmask(field) (char *)__get_dynamic_array(field)
+#undef __get_cpumask
+#define __get_cpumask(field) (char *)__get_dynamic_array(field)
+
#undef __get_sockaddr
#define __get_sockaddr(field) ((struct sockaddr *)__get_dynamic_array(field))
@@ -40,6 +43,9 @@
#undef __get_rel_bitmask
#define __get_rel_bitmask(field) (char *)__get_rel_dynamic_array(field)
+#undef __get_rel_cpumask
+#define __get_rel_cpumask(field) (char *)__get_rel_dynamic_array(field)
+
#undef __get_rel_sockaddr
#define __get_rel_sockaddr(field) ((struct sockaddr *)__get_rel_dynamic_array(field))
@@ -21,6 +21,9 @@
#undef __get_bitmask
#define __get_bitmask(field) (char *)__get_dynamic_array(field)
+#undef __get_cpumask
+#define __get_cpumask(field) (char *)__get_dynamic_array(field)
+
#undef __get_sockaddr
#define __get_sockaddr(field) ((struct sockaddr *)__get_dynamic_array(field))
@@ -41,6 +44,9 @@
#undef __get_rel_bitmask
#define __get_rel_bitmask(field) (char *)__get_rel_dynamic_array(field)
+#undef __get_rel_cpumask
+#define __get_rel_cpumask(field) (char *)__get_rel_dynamic_array(field)
+
#undef __get_rel_sockaddr
#define __get_rel_sockaddr(field) ((struct sockaddr *)__get_rel_dynamic_array(field))
@@ -32,6 +32,9 @@
#undef __bitmask
#define __bitmask(item, nr_bits) __dynamic_array(char, item, -1)
+#undef __cpumask
+#define __cpumask(item, nr_bits) __dynamic_array(char, item, -1)
+
#undef __sockaddr
#define __sockaddr(field, len) __dynamic_array(u8, field, len)
@@ -47,6 +50,9 @@
#undef __rel_bitmask
#define __rel_bitmask(item, nr_bits) __rel_dynamic_array(char, item, -1)
+#undef __rel_cpumask
+#define __rel_cpumask(item, nr_bits) __rel_dynamic_array(char, item, -1)
+
#undef __rel_sockaddr
#define __rel_sockaddr(field, len) __rel_dynamic_array(u8, field, len)
@@ -38,6 +38,9 @@
#undef __bitmask
#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
+#undef __cpumask
+#define __cpumask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
+
#undef __sockaddr
#define __sockaddr(field, len) __dynamic_array(u8, field, len)
@@ -53,5 +56,8 @@
#undef __rel_bitmask
#define __rel_bitmask(item, nr_bits) __rel_dynamic_array(unsigned long, item, -1)
+#undef __rel_cpumask
+#define __rel_cpumask(item, nr_bits) __rel_dynamic_array(unsigned long, item, -1)
+
#undef __rel_sockaddr
#define __rel_sockaddr(field, len) __rel_dynamic_array(u8, field, len)
@@ -42,6 +42,9 @@
trace_print_bitmask_seq(p, __bitmask, __bitmask_size); \
})
+#undef __get_cpumask
+#define __get_cpumask(field) __get_bitmask(field)
+
#undef __get_rel_bitmask
#define __get_rel_bitmask(field) \
({ \
@@ -51,6 +54,9 @@
trace_print_bitmask_seq(p, __bitmask, __bitmask_size); \
})
+#undef __get_rel_cpumask
+#define __get_rel_cpumask(field) __get_rel_bitmask(field)
+
#undef __get_sockaddr
#define __get_sockaddr(field) ((struct sockaddr *)__get_dynamic_array(field))
@@ -46,6 +46,9 @@
#undef __bitmask
#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
+#undef __cpumask
+#define __cpumask(item, nr_bits) __dynamic_array(cpumask_t *, item, -1)
+
#undef __sockaddr
#define __sockaddr(field, len) __dynamic_array(u8, field, len)
@@ -64,5 +67,8 @@
#undef __rel_bitmask
#define __rel_bitmask(item, nr_bits) __rel_dynamic_array(unsigned long, item, -1)
+#undef __rel_cpumask
+#define __rel_cpumask(item, nr_bits) __rel_dynamic_array(cpumask_t *, item, -1)
+
#undef __rel_sockaddr
#define __rel_sockaddr(field, len) __rel_dynamic_array(u8, field, len)
@@ -82,10 +82,16 @@
#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, \
__bitmask_size_in_longs(nr_bits))
+#undef __cpumask
+#define __cpumask(item, nr_bits) __bitmask(item, nr_bits)
+
#undef __rel_bitmask
#define __rel_bitmask(item, nr_bits) __rel_dynamic_array(unsigned long, item, \
__bitmask_size_in_longs(nr_bits))
+#undef __rel_cpumask
+#define __rel_cpumask(item, nr_bits) __rel_bitmask(item, nr_bits)
+
#undef __sockaddr
#define __sockaddr(field, len) __dynamic_array(u8, field, len)
@@ -57,6 +57,16 @@
#define __assign_bitmask(dst, src, nr_bits) \
memcpy(__get_bitmask(dst), (src), __bitmask_size_in_bytes(nr_bits))
+#undef __cpumask
+#define __cpumask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
+
+#undef __get_cpumask
+#define __get_cpumask(field) (char *)__get_dynamic_array(field)
+
+#undef __assign_cpumask
+#define __assign_cpumask(dst, src, nr_bits) \
+ memcpy(__get_cpumask(dst), (src), __bitmask_size_in_bytes(nr_bits))
+
#undef __sockaddr
#define __sockaddr(field, len) __dynamic_array(u8, field, len)
@@ -98,6 +108,16 @@
#define __assign_rel_bitmask(dst, src, nr_bits) \
memcpy(__get_rel_bitmask(dst), (src), __bitmask_size_in_bytes(nr_bits))
+#undef __rel_cpumask
+#define __rel_cpumask(item, nr_bits) __rel_dynamic_array(unsigned long, item, -1)
+
+#undef __get_rel_cpumask
+#define __get_rel_cpumask(field) (char *)__get_rel_dynamic_array(field)
+
+#undef __assign_rel_cpumask
+#define __assign_rel_cpumask(dst, src, nr_bits) \
+ memcpy(__get_rel_cpumask(dst), (src), __bitmask_size_in_bytes(nr_bits))
+
#undef __rel_sockaddr
#define __rel_sockaddr(field, len) __rel_dynamic_array(u8, field, len)
@@ -13,11 +13,13 @@
#undef __get_dynamic_array_len
#undef __get_str
#undef __get_bitmask
+#undef __get_cpumask
#undef __get_sockaddr
#undef __get_rel_dynamic_array
#undef __get_rel_dynamic_array_len
#undef __get_rel_str
#undef __get_rel_bitmask
+#undef __get_rel_cpumask
#undef __get_rel_sockaddr
#undef __print_array
#undef __print_hex_dump
@@ -50,7 +50,7 @@ static void do_simple_thread_func(int cnt, const char *fmt, ...)
trace_foo_with_template_print("I have to be different", cnt);
- trace_foo_rel_loc("Hello __rel_loc", cnt, bitmask);
+ trace_foo_rel_loc("Hello __rel_loc", cnt, bitmask, current->cpus_ptr);
}
static void simple_thread_func(int cnt)
@@ -200,6 +200,16 @@
*
* __assign_bitmask(target_cpus, cpumask_bits(bar), nr_cpumask_bits);
*
+ * __cpumask: This is pretty much the same as __bitmask but is specific for
+ * CPU masks. The type displayed to the user via the format files will
+ * be "cpumaks_t" such that user space may deal with them differently
+ * if they choose to do so.
+ *
+ * __cpumask(target_cpu, nr_cpumask_bits)
+ *
+ * To assign a cpumask, use the __assign_cpumask() helper macro.
+ *
+ * __assign_cpumask(target_cpus, cpumask_bits(bar), nr_cpumask_bits);
*
* fast_assign: This is a C like function that is used to store the items
* into the ring buffer. A special variable called "__entry" will be the
@@ -212,8 +222,8 @@
* This is also used to print out the data from the trace files.
* Again, the __entry macro is used to access the data from the ring buffer.
*
- * Note, __dynamic_array, __string, and __bitmask require special helpers
- * to access the data.
+ * Note, __dynamic_array, __string, __bitmask and __cpumask require special
+ * helpers to access the data.
*
* For __dynamic_array(int, foo, bar) use __get_dynamic_array(foo)
* Use __get_dynamic_array_len(foo) to get the length of the array
@@ -226,6 +236,8 @@
*
* For __bitmask(target_cpus, nr_cpumask_bits) use __get_bitmask(target_cpus)
*
+ * For __cpumask(target_cpus, nr_cpumask_bits) use __get_cpumask(target_cpus)
+ *
*
* Note, that for both the assign and the printk, __entry is the handler
* to the data structure in the ring buffer, and is defined by the
@@ -288,6 +300,7 @@ TRACE_EVENT(foo_bar,
__dynamic_array(int, list, __length_of(lst))
__string( str, string )
__bitmask( cpus, num_possible_cpus() )
+ __cpumask( cpum, num_possible_cpus() )
__vstring( vstr, fmt, va )
),
@@ -299,9 +312,10 @@ TRACE_EVENT(foo_bar,
__assign_str(str, string);
__assign_vstr(vstr, fmt, va);
__assign_bitmask(cpus, cpumask_bits(mask), num_possible_cpus());
+ __assign_cpumask(cpum, cpumask_bits(mask), num_possible_cpus());
),
- TP_printk("foo %s %d %s %s %s %s (%s) %s", __entry->foo, __entry->bar,
+ TP_printk("foo %s %d %s %s %s %s (%s) (%s) %s", __entry->foo, __entry->bar,
/*
* Notice here the use of some helper functions. This includes:
@@ -345,7 +359,8 @@ TRACE_EVENT(foo_bar,
__print_array(__get_dynamic_array(list),
__get_dynamic_array_len(list) / sizeof(int),
sizeof(int)),
- __get_str(str), __get_bitmask(cpus), __get_str(vstr))
+ __get_str(str), __get_bitmask(cpus), __get_cpumask(cpus),
+ __get_str(vstr))
);
/*
@@ -542,15 +557,16 @@ DEFINE_EVENT_PRINT(foo_template, foo_with_template_print,
TRACE_EVENT(foo_rel_loc,
- TP_PROTO(const char *foo, int bar, unsigned long *mask),
+ TP_PROTO(const char *foo, int bar, unsigned long *mask, const cpumask_t *cpus),
- TP_ARGS(foo, bar, mask),
+ TP_ARGS(foo, bar, mask, cpus),
TP_STRUCT__entry(
__rel_string( foo, foo )
__field( int, bar )
__rel_bitmask( bitmask,
BITS_PER_BYTE * sizeof(unsigned long) )
+ __rel_cpumask( cpumask, cpumask_size() )
),
TP_fast_assign(
@@ -558,10 +574,12 @@ TRACE_EVENT(foo_rel_loc,
__entry->bar = bar;
__assign_rel_bitmask(bitmask, mask,
BITS_PER_BYTE * sizeof(unsigned long));
+ __assign_rel_cpumask(cpumask, cpus, cpumask_size());
),
- TP_printk("foo_rel_loc %s, %d, %s", __get_rel_str(foo), __entry->bar,
- __get_rel_bitmask(bitmask))
+ TP_printk("foo_rel_loc %s, %d, %s, %s", __get_rel_str(foo), __entry->bar,
+ __get_rel_bitmask(bitmask),
+ __get_rel_cpumask(cpumask))
);
#endif