Skip to content

Commit a9c4bdd

Browse files
Linyu Yuanrostedt
authored andcommitted
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]>
1 parent a2ff84a commit a9c4bdd

File tree

4 files changed

+32
-0
lines changed

4 files changed

+32
-0
lines changed

include/linux/trace_seq.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ extern void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp,
9595
extern int trace_seq_hex_dump(struct trace_seq *s, const char *prefix_str,
9696
int prefix_type, int rowsize, int groupsize,
9797
const void *buf, size_t len, bool ascii);
98+
char *trace_seq_acquire(struct trace_seq *s, unsigned int len);
9899

99100
#else /* CONFIG_TRACING */
100101
static inline __printf(2, 3)
@@ -139,6 +140,10 @@ static inline int trace_seq_path(struct trace_seq *s, const struct path *path)
139140
{
140141
return 0;
141142
}
143+
static inline char *trace_seq_acquire(struct trace_seq *s, unsigned int len)
144+
{
145+
return NULL;
146+
}
142147
#endif /* CONFIG_TRACING */
143148

144149
#endif /* _LINUX_TRACE_SEQ_H */

include/trace/stages/stage3_trace_output.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,6 @@
139139
u64 ____val = (u64)(value); \
140140
(u32) do_div(____val, NSEC_PER_SEC); \
141141
})
142+
143+
#undef __get_buf
144+
#define __get_buf(len) trace_seq_acquire(p, (len))

include/trace/stages/stage7_class_define.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#undef __get_rel_sockaddr
2424
#undef __print_array
2525
#undef __print_hex_dump
26+
#undef __get_buf
2627

2728
/*
2829
* The below is not executed in the kernel. It is only what is

kernel/trace/trace_seq.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,3 +403,26 @@ int trace_seq_hex_dump(struct trace_seq *s, const char *prefix_str,
403403
return 1;
404404
}
405405
EXPORT_SYMBOL(trace_seq_hex_dump);
406+
407+
/*
408+
* trace_seq_acquire - acquire seq buffer with size len
409+
* @s: trace sequence descriptor
410+
* @len: size of buffer to be acquired
411+
*
412+
* acquire buffer with size of @len from trace_seq for output usage,
413+
* user can fill string into that buffer.
414+
*
415+
* Returns start address of acquired buffer.
416+
*
417+
* it allow multiple usage in one trace output function call.
418+
*/
419+
char *trace_seq_acquire(struct trace_seq *s, unsigned int len)
420+
{
421+
char *ret = trace_seq_buffer_ptr(s);
422+
423+
if (!WARN_ON_ONCE(seq_buf_buffer_left(&s->seq) < len))
424+
seq_buf_commit(&s->seq, len);
425+
426+
return ret;
427+
}
428+
EXPORT_SYMBOL(trace_seq_acquire);

0 commit comments

Comments
 (0)