| 7604256c | 15-Mar-2024 |
Steven Rostedt (Google) <[email protected]> |
tracing: Add __string_src() helper to help compilers not to get confused
The __string() helper macro of the TRACE_EVENT() macro is used to determine how much of the ring buffer needs to be allocated
tracing: Add __string_src() helper to help compilers not to get confused
The __string() helper macro of the TRACE_EVENT() macro is used to determine how much of the ring buffer needs to be allocated to fit the given source string. Some trace events have a string that is dependent on another variable that could be NULL, and in those cases the string is passed in to be NULL.
The __string() macro can handle being passed in a NULL pointer for which it will turn it into "(null)". It does that with:
strlen((src) ? (const char *)(src) : "(null)") + 1
But if src itself has the same conditional type it can confuse the compiler. That is:
__string(r ? dev(r)->name : NULL)
Would turn into:
strlen((r ? dev(r)->name : NULL) ? (r ? dev(r)->name : NULL) : "(null)" + 1
For which the compiler thinks that NULL is being passed to strlen() and gives this kind of warning:
./include/trace/stages/stage5_get_offsets.h:50:21: warning: argument 1 null where non-null expected [-Wnonnull] 50 | strlen((src) ? (const char *)(src) : "(null)") + 1)
Instead, create a static inline function that takes the src string and will return the string if it is not NULL and will return "(null)" if it is. This will then make the strlen() line:
strlen(__string_src(src)) + 1
Where the compiler can see that strlen() will not end up with NULL and does not warn about it.
Note that this depends on commit 51270d573a8d ("tracing/net_sched: Fix tracepoints that save qdisc_dev() as a string") being applied, as passing the qdisc_dev() into __string_src() will give an error.
Link: https://lore.kernel.org/all/ZfNmfCmgCs4Nc+EH@aschofie-mobl2/ Link: https://lore.kernel.org/linux-trace-kernel/[email protected]
Cc: Masami Hiramatsu <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Reported-by: Alison Schofield <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]>
show more ...
|
| 91684986 | 22-Feb-2024 |
Steven Rostedt (Google) <[email protected]> |
tracing: Use ? : shortcut in trace macros
Instead of having:
#define __assign_str(dst, src) \ memcpy(__get_str(dst), __data_offsets.dst##_ptr_ ? \ __data_offsets.dst##_ptr_ : "(null)",
tracing: Use ? : shortcut in trace macros
Instead of having:
#define __assign_str(dst, src) \ memcpy(__get_str(dst), __data_offsets.dst##_ptr_ ? \ __data_offsets.dst##_ptr_ : "(null)", \ __get_dynamic_array_len(dst))
Use the ? : shortcut and compact it down to:
#define __assign_str(dst, src) \ memcpy(__get_str(dst), __data_offsets.dst##_ptr_ ? : "(null)", \ __get_dynamic_array_len(dst))
Link: https://lore.kernel.org/linux-trace-kernel/[email protected]
Cc: Masami Hiramatsu <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Ville Syrjälä <[email protected]> Cc: Rodrigo Vivi <[email protected]> Cc: Chuck Lever <[email protected]> Suggested-by: Mathieu Desnoyers <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]>
show more ...
|
| e8b737bf | 22-Feb-2024 |
Steven Rostedt (Google) <[email protected]> |
tracing: Do not calculate strlen() twice for __string() fields
The TRACE_EVENT() macro handles dynamic strings by having:
TP_PROTO(struct some_struct *s), TP_ARGS(s), TP_STRUCT__entry(
tracing: Do not calculate strlen() twice for __string() fields
The TRACE_EVENT() macro handles dynamic strings by having:
TP_PROTO(struct some_struct *s), TP_ARGS(s), TP_STRUCT__entry( __string(my_string, s->string) ), TP_fast_assign( __assign_str(my_string, s->string); ) TP_printk("%s", __get_str(my_string))
There's even some code that may call a function helper to find the s->string value. The problem with the above is that the work to get the s->string is done twice. Once at the __string() and again in the __assign_str().
The length of the string is calculated via a strlen(), not once, but twice. Once during the __string() macro and again in __assign_str(). But the length is actually already recorded in the data location and here's no reason to call strlen() again.
Just use the saved length that was saved in the __string() code for the __assign_str() code.
Link: https://lore.kernel.org/linux-trace-kernel/[email protected]
Cc: Masami Hiramatsu <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Ville Syrjälä <[email protected]> Cc: Rodrigo Vivi <[email protected]> Cc: Chuck Lever <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]>
show more ...
|
| a9c4bdd5 | 30-Jan-2023 |
Linyu Yuan <[email protected]> |
tracing: Acquire buffer from temparary trace sequence
there is one dwc3 trace event declare as below, DECLARE_EVENT_CLASS(dwc3_log_event, TP_PROTO(u32 event, struct dwc3 *dwc), TP_ARGS(event, dwc)
tracing: Acquire buffer from temparary trace sequence
there is one dwc3 trace event declare as below, DECLARE_EVENT_CLASS(dwc3_log_event, TP_PROTO(u32 event, struct dwc3 *dwc), TP_ARGS(event, dwc), TP_STRUCT__entry( __field(u32, event) __field(u32, ep0state) __dynamic_array(char, str, DWC3_MSG_MAX) ), TP_fast_assign( __entry->event = event; __entry->ep0state = dwc->ep0state; ), TP_printk("event (%08x): %s", __entry->event, dwc3_decode_event(__get_str(str), DWC3_MSG_MAX, __entry->event, __entry->ep0state)) ); the problem is when trace function called, it will allocate up to DWC3_MSG_MAX bytes from trace event buffer, but never fill the buffer during fast assignment, it only fill the buffer when output function are called, so this means if output function are not called, the buffer will never used.
add __get_buf(len) which acquiree buffer from iter->tmp_seq when trace output function called, it allow user write string to acquired buffer.
the mentioned dwc3 trace event will changed as below, DECLARE_EVENT_CLASS(dwc3_log_event, TP_PROTO(u32 event, struct dwc3 *dwc), TP_ARGS(event, dwc), TP_STRUCT__entry( __field(u32, event) __field(u32, ep0state) ), TP_fast_assign( __entry->event = event; __entry->ep0state = dwc->ep0state; ), TP_printk("event (%08x): %s", __entry->event, dwc3_decode_event(__get_buf(DWC3_MSG_MAX), DWC3_MSG_MAX, __entry->event, __entry->ep0state)) );.
Link: https://lore.kernel.org/linux-trace-kernel/[email protected]
Cc: Masami Hiramatsu <[email protected]> Signed-off-by: Linyu Yuan <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]>
show more ...
|
| fab89a09 | 13-Dec-2022 |
Steven Rostedt (Google) <[email protected]> |
tracing: Remove pointer (asterisk) and brackets from cpumask_t field
To differentiate between long arrays and cpumasks, the __cpumask() field was created. Part of the TRACE_EVENT() macros test if th
tracing: Remove pointer (asterisk) and brackets from cpumask_t field
To differentiate between long arrays and cpumasks, the __cpumask() field was created. Part of the TRACE_EVENT() macros test if the type is signed or not by using the is_signed_type() macro. The __cpumask() field used the __dynamic_array() helper but because cpumask_t is a structure, it could not be used in the is_signed_type() macro as that would fail to build, so instead it passed in the pointer to cpumask_t.
Unfortunately, that creates in the format file:
field:__data_loc cpumask_t *[] mask; offset:36; size:4; signed:0;
Which looks like an array of pointers to cpumask_t and not a cpumask_t type, which is misleading to user space parsers.
Douglas Raillard pointed out that the "[]" are also misleading, as cpumask_t is not an array.
Since cpumask() hasn't been created yet, and the parsers currently fail on it (but will still produce the raw output), make it be:
field:__data_loc cpumask_t mask; offset:36; size:4; signed:0;
Which is the correct type of the field.
Then the parsers can be updated to handle this.
Link: https://lore.kernel.org/lkml/[email protected]/ Link: https://lore.kernel.org/linux-trace-kernel/[email protected]
Cc: Masami Hiramatsu <[email protected]> Cc: Valentin Schneider <[email protected]> Cc: Andrew Morton <[email protected]> Fixes: 8230f27b1ccc ("tracing: Add __cpumask to denote a trace event field that is a cpumask_t") Reported-by: Douglas Raillard <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]>
show more ...
|
| 84055411 | 29-Mar-2022 |
Steven Rostedt (Google) <[email protected]> |
tracing: Rename the staging files for trace_events
When looking for implementation of different phases of the creation of the TRACE_EVENT() macro, it is pretty useless when all helper macro redefini
tracing: Rename the staging files for trace_events
When looking for implementation of different phases of the creation of the TRACE_EVENT() macro, it is pretty useless when all helper macro redefinitions are in files labeled "stageX_defines.h". Rename them to state which phase the files are for. For instance, when looking for the defines that are used to create the event fields, seeing "stage4_event_fields.h" gives the developer a good idea that the defines are in that file.
Signed-off-by: Steven Rostedt (Google) <[email protected]>
show more ...
|