diff options
author | Steven Rostedt <srostedt@redhat.com> | 2009-04-15 16:53:47 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-17 11:03:28 -0400 |
commit | d1b182a8d49ed6416325b4e0a1cb0f17cd4e702a (patch) | |
tree | f482bfba39828503f32ed994829d2d3cd6b81bfe /kernel/trace/trace_events.c | |
parent | e6187007d6c365b551c69ea3df46f06fd1c8bd19 (diff) |
tracing/events/ring-buffer: expose format of ring buffer headers to users
Currently, every thing needed to read the binary output from the
ring buffers is available, with the exception of the way the ring
buffers handles itself internally.
This patch creates two special files in the debugfs/tracing/events
directory:
# cat /debug/tracing/events/header_page
field: u64 timestamp; offset:0; size:8;
field: local_t commit; offset:8; size:8;
field: char data; offset:16; size:4080;
# cat /debug/tracing/events/header_event
type : 2 bits
len : 3 bits
time_delta : 27 bits
array : 32 bits
padding : type == 0
time_extend : type == 1
data : type == 3
This is to allow a userspace app to see if the ring buffer format changes
or not.
[ Impact: allow userspace apps to know of ringbuffer format changes ]
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace_events.c')
-rw-r--r-- | kernel/trace/trace_events.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index f81d6eec4e43..7163a2bb021a 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -610,6 +610,30 @@ subsystem_filter_write(struct file *filp, const char __user *ubuf, size_t cnt, | |||
610 | return cnt; | 610 | return cnt; |
611 | } | 611 | } |
612 | 612 | ||
613 | static ssize_t | ||
614 | show_header(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) | ||
615 | { | ||
616 | int (*func)(struct trace_seq *s) = filp->private_data; | ||
617 | struct trace_seq *s; | ||
618 | int r; | ||
619 | |||
620 | if (*ppos) | ||
621 | return 0; | ||
622 | |||
623 | s = kmalloc(sizeof(*s), GFP_KERNEL); | ||
624 | if (!s) | ||
625 | return -ENOMEM; | ||
626 | |||
627 | trace_seq_init(s); | ||
628 | |||
629 | func(s); | ||
630 | r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len); | ||
631 | |||
632 | kfree(s); | ||
633 | |||
634 | return r; | ||
635 | } | ||
636 | |||
613 | static const struct seq_operations show_event_seq_ops = { | 637 | static const struct seq_operations show_event_seq_ops = { |
614 | .start = t_start, | 638 | .start = t_start, |
615 | .next = t_next, | 639 | .next = t_next, |
@@ -667,6 +691,11 @@ static const struct file_operations ftrace_subsystem_filter_fops = { | |||
667 | .write = subsystem_filter_write, | 691 | .write = subsystem_filter_write, |
668 | }; | 692 | }; |
669 | 693 | ||
694 | static const struct file_operations ftrace_show_header_fops = { | ||
695 | .open = tracing_open_generic, | ||
696 | .read = show_header, | ||
697 | }; | ||
698 | |||
670 | static struct dentry *event_trace_events_dir(void) | 699 | static struct dentry *event_trace_events_dir(void) |
671 | { | 700 | { |
672 | static struct dentry *d_tracer; | 701 | static struct dentry *d_tracer; |
@@ -909,6 +938,15 @@ static __init int event_trace_init(void) | |||
909 | if (!d_events) | 938 | if (!d_events) |
910 | return 0; | 939 | return 0; |
911 | 940 | ||
941 | /* ring buffer internal formats */ | ||
942 | trace_create_file("header_page", 0444, d_events, | ||
943 | ring_buffer_print_page_header, | ||
944 | &ftrace_show_header_fops); | ||
945 | |||
946 | trace_create_file("header_event", 0444, d_events, | ||
947 | ring_buffer_print_entry_header, | ||
948 | &ftrace_show_header_fops); | ||
949 | |||
912 | for_each_event(call, __start_ftrace_events, __stop_ftrace_events) { | 950 | for_each_event(call, __start_ftrace_events, __stop_ftrace_events) { |
913 | /* The linker may leave blanks */ | 951 | /* The linker may leave blanks */ |
914 | if (!call->name) | 952 | if (!call->name) |