Re: [RFC PATCH 2/2] trace: allocate temparary buffer for trace output usage

From: Linyu Yuan
Date: Wed Dec 14 2022 - 20:53:42 EST


is it possible add a generic macro like #define __get_buf(offset, len)  (p->buffer + (offset))  ?

it only use buffer filed of struct trace_seq .

On 12/15/2022 9:22 AM, Linyu Yuan wrote:
thanks for remind, will check and use it.


thanks

On 12/14/2022 10:25 PM, Steven Rostedt wrote:
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