aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ring_buffer.h5
-rw-r--r--kernel/trace/ring_buffer.c44
-rw-r--r--kernel/trace/trace_events.c38
3 files changed, 87 insertions, 0 deletions
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
index f0aa486d131c..fac8f1ac6f49 100644
--- a/include/linux/ring_buffer.h
+++ b/include/linux/ring_buffer.h
@@ -166,6 +166,11 @@ void ring_buffer_free_read_page(struct ring_buffer *buffer, void *data);
166int ring_buffer_read_page(struct ring_buffer *buffer, void **data_page, 166int ring_buffer_read_page(struct ring_buffer *buffer, void **data_page,
167 size_t len, int cpu, int full); 167 size_t len, int cpu, int full);
168 168
169struct trace_seq;
170
171int ring_buffer_print_entry_header(struct trace_seq *s);
172int ring_buffer_print_page_header(struct trace_seq *s);
173
169enum ring_buffer_flags { 174enum ring_buffer_flags {
170 RB_FL_OVERWRITE = 1 << 0, 175 RB_FL_OVERWRITE = 1 << 0,
171}; 176};
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index f935bd5ec3e8..84a6055f37c9 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -22,6 +22,28 @@
22#include "trace.h" 22#include "trace.h"
23 23
24/* 24/*
25 * The ring buffer header is special. We must manually up keep it.
26 */
27int ring_buffer_print_entry_header(struct trace_seq *s)
28{
29 int ret;
30
31 ret = trace_seq_printf(s, "\ttype : 2 bits\n");
32 ret = trace_seq_printf(s, "\tlen : 3 bits\n");
33 ret = trace_seq_printf(s, "\ttime_delta : 27 bits\n");
34 ret = trace_seq_printf(s, "\tarray : 32 bits\n");
35 ret = trace_seq_printf(s, "\n");
36 ret = trace_seq_printf(s, "\tpadding : type == %d\n",
37 RINGBUF_TYPE_PADDING);
38 ret = trace_seq_printf(s, "\ttime_extend : type == %d\n",
39 RINGBUF_TYPE_TIME_EXTEND);
40 ret = trace_seq_printf(s, "\tdata : type == %d\n",
41 RINGBUF_TYPE_DATA);
42
43 return ret;
44}
45
46/*
25 * The ring buffer is made up of a list of pages. A separate list of pages is 47 * The ring buffer is made up of a list of pages. A separate list of pages is
26 * allocated for each CPU. A writer may only write to a buffer that is 48 * allocated for each CPU. A writer may only write to a buffer that is
27 * associated with the CPU it is currently executing on. A reader may read 49 * associated with the CPU it is currently executing on. A reader may read
@@ -340,6 +362,28 @@ static inline int test_time_stamp(u64 delta)
340 362
341#define BUF_PAGE_SIZE (PAGE_SIZE - BUF_PAGE_HDR_SIZE) 363#define BUF_PAGE_SIZE (PAGE_SIZE - BUF_PAGE_HDR_SIZE)
342 364
365int ring_buffer_print_page_header(struct trace_seq *s)
366{
367 struct buffer_data_page field;
368 int ret;
369
370 ret = trace_seq_printf(s, "\tfield: u64 timestamp;\t"
371 "offset:0;\tsize:%u;\n",
372 (unsigned int)sizeof(field.time_stamp));
373
374 ret = trace_seq_printf(s, "\tfield: local_t commit;\t"
375 "offset:%u;\tsize:%u;\n",
376 (unsigned int)offsetof(typeof(field), commit),
377 (unsigned int)sizeof(field.commit));
378
379 ret = trace_seq_printf(s, "\tfield: char data;\t"
380 "offset:%u;\tsize:%u;\n",
381 (unsigned int)offsetof(typeof(field), data),
382 (unsigned int)BUF_PAGE_SIZE);
383
384 return ret;
385}
386
343/* 387/*
344 * head_page == tail_page && head == tail then buffer is empty. 388 * head_page == tail_page && head == tail then buffer is empty.
345 */ 389 */
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
613static ssize_t
614show_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
613static const struct seq_operations show_event_seq_ops = { 637static 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
694static const struct file_operations ftrace_show_header_fops = {
695 .open = tracing_open_generic,
696 .read = show_header,
697};
698
670static struct dentry *event_trace_events_dir(void) 699static 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)