Commit 6ea22486 authored by Dave Martin's avatar Dave Martin Committed by Steven Rostedt

tracing: Add array printing helper

If a trace event contains an array, there is currently no standard
way to format this for text output.  Drivers are currently hacking
around this by a) local hacks that use the trace_seq functionailty
directly, or b) just not printing that information.  For fixed size
arrays, formatting of the elements can be open-coded, but this gets
cumbersome for arrays of non-trivial size.

These approaches result in non-standard content of the event format
description delivered to userspace, so userland tools needs to be
taught to understand and parse each array printing method
individually.

This patch implements a __print_array() helper that tracepoint
implementations can use instead of reinventing it.  A simple C-style
syntax is used to delimit the array and its elements {like,this}.

So that the helpers can be used with large static arrays as well as
dynamic arrays, they take a pointer and element count: they can be
used with __get_dynamic_array() for use with dynamic arrays.
Link: http://lkml.kernel.org/r/1422449335-8289-2-git-send-email-javi.merino@arm.com

Cc: Ingo Molnar <mingo@redhat.com>
Signed-off-by: default avatarDave Martin <Dave.Martin@arm.com>
Signed-off-by: default avatarJavi Merino <javi.merino@arm.com>
Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
parent 69a1c994
...@@ -44,6 +44,10 @@ const char *ftrace_print_bitmask_seq(struct trace_seq *p, void *bitmask_ptr, ...@@ -44,6 +44,10 @@ const char *ftrace_print_bitmask_seq(struct trace_seq *p, void *bitmask_ptr,
const char *ftrace_print_hex_seq(struct trace_seq *p, const char *ftrace_print_hex_seq(struct trace_seq *p,
const unsigned char *buf, int len); const unsigned char *buf, int len);
const char *ftrace_print_array_seq(struct trace_seq *p,
const void *buf, int buf_len,
size_t el_size);
struct trace_iterator; struct trace_iterator;
struct trace_event; struct trace_event;
......
...@@ -263,6 +263,14 @@ ...@@ -263,6 +263,14 @@
#undef __print_hex #undef __print_hex
#define __print_hex(buf, buf_len) ftrace_print_hex_seq(p, buf, buf_len) #define __print_hex(buf, buf_len) ftrace_print_hex_seq(p, buf, buf_len)
#undef __print_array
#define __print_array(array, count, el_size) \
({ \
BUILD_BUG_ON(el_size != 1 && el_size != 2 && \
el_size != 4 && el_size != 8); \
ftrace_print_array_seq(p, array, count, el_size); \
})
#undef DECLARE_EVENT_CLASS #undef DECLARE_EVENT_CLASS
#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
static notrace enum print_line_t \ static notrace enum print_line_t \
...@@ -674,6 +682,7 @@ static inline void ftrace_test_probe_##call(void) \ ...@@ -674,6 +682,7 @@ static inline void ftrace_test_probe_##call(void) \
#undef __get_dynamic_array_len #undef __get_dynamic_array_len
#undef __get_str #undef __get_str
#undef __get_bitmask #undef __get_bitmask
#undef __print_array
#undef TP_printk #undef TP_printk
#define TP_printk(fmt, args...) "\"" fmt "\", " __stringify(args) #define TP_printk(fmt, args...) "\"" fmt "\", " __stringify(args)
......
...@@ -177,6 +177,50 @@ ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len) ...@@ -177,6 +177,50 @@ ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len)
} }
EXPORT_SYMBOL(ftrace_print_hex_seq); EXPORT_SYMBOL(ftrace_print_hex_seq);
const char *
ftrace_print_array_seq(struct trace_seq *p, const void *buf, int buf_len,
size_t el_size)
{
const char *ret = trace_seq_buffer_ptr(p);
const char *prefix = "";
void *ptr = (void *)buf;
trace_seq_putc(p, '{');
while (ptr < buf + buf_len) {
switch (el_size) {
case 1:
trace_seq_printf(p, "%s0x%x", prefix,
*(u8 *)ptr);
break;
case 2:
trace_seq_printf(p, "%s0x%x", prefix,
*(u16 *)ptr);
break;
case 4:
trace_seq_printf(p, "%s0x%x", prefix,
*(u32 *)ptr);
break;
case 8:
trace_seq_printf(p, "%s0x%llx", prefix,
*(u64 *)ptr);
break;
default:
trace_seq_printf(p, "BAD SIZE:%zu 0x%x", el_size,
*(u8 *)ptr);
el_size = 1;
}
prefix = ",";
ptr += el_size;
}
trace_seq_putc(p, '}');
trace_seq_putc(p, 0);
return ret;
}
EXPORT_SYMBOL(ftrace_print_array_seq);
int ftrace_raw_output_prep(struct trace_iterator *iter, int ftrace_raw_output_prep(struct trace_iterator *iter,
struct trace_event *trace_event) struct trace_event *trace_event)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment