On Wed, 14 Dec 2022 22:11:42 +0800
Linyu Yuan <quic_linyyuan@xxxxxxxxxxx> wrote:
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 __alloc_buf() and __get_buf() which will not allocate event buffer
when trace function called, but when trace output function called,
it will
kmalloc buffer with size DWC3_MSG_MAX for temprary usage and free it
before trace output function return.
This looks exactly like what the trace_seq *p is to be used for.
static notrace enum print_line_t \
trace_raw_output_##call(struct trace_iterator *iter, int flags, \
struct trace_event *trace_event) \
{ \
struct trace_seq *s = &iter->seq; \
struct trace_seq __maybe_unused *p = &iter->tmp_seq; \
^^^^^^^^^^^^^^^^^^^^
struct trace_event_raw_##call *field; \
int ret; \
\
field = (typeof(field))iter->ent; \
\
ret = trace_raw_output_prep(iter, trace_event); \
if (ret != TRACE_TYPE_HANDLED) \
return ret; \
\
trace_event_printf(iter, print); \
\
return trace_handle_return(s); \
} \
That is a trace_seq buffer that is for temporary usage during the
output.
See:
include/trace/events/libata.h
include/trace/events/scsi.h
As well as the macros trace_print_bitmask_seq(),
trace_print_flags_seq(),
trace_print_symbols_seq(), etc.
-- Steve