aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/trace.h1
-rw-r--r--kernel/trace/trace_events.c56
-rw-r--r--kernel/trace/trace_events_stage_2.h52
-rw-r--r--kernel/trace/trace_events_stage_3.h2
4 files changed, 110 insertions, 1 deletions
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index cf6ba4181b14..e606633fb498 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -754,6 +754,7 @@ struct ftrace_event_call {
754 int (*raw_init)(void); 754 int (*raw_init)(void);
755 int (*raw_reg)(void); 755 int (*raw_reg)(void);
756 void (*raw_unreg)(void); 756 void (*raw_unreg)(void);
757 int (*show_format)(struct trace_seq *s);
757}; 758};
758 759
759void event_trace_printk(unsigned long ip, const char *fmt, ...); 760void event_trace_printk(unsigned long ip, const char *fmt, ...);
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 26069fa6b3b0..d57a772981c1 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -3,6 +3,9 @@
3 * 3 *
4 * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> 4 * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
5 * 5 *
6 * - Added format output of fields of the trace point.
7 * This was based off of work by Tom Zanussi <tzanussi@gmail.com>.
8 *
6 */ 9 */
7 10
8#include <linux/debugfs.h> 11#include <linux/debugfs.h>
@@ -444,6 +447,42 @@ event_available_types_read(struct file *filp, char __user *ubuf, size_t cnt,
444 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); 447 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
445} 448}
446 449
450static ssize_t
451event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
452 loff_t *ppos)
453{
454 struct ftrace_event_call *call = filp->private_data;
455 struct trace_seq *s;
456 char *buf;
457 int r;
458
459 s = kmalloc(sizeof(*s), GFP_KERNEL);
460 if (!s)
461 return -ENOMEM;
462
463 trace_seq_init(s);
464
465 if (*ppos)
466 return 0;
467
468 r = call->show_format(s);
469 if (!r) {
470 /*
471 * ug! The format output is bigger than a PAGE!!
472 */
473 buf = "FORMAT TOO BIG\n";
474 r = simple_read_from_buffer(ubuf, cnt, ppos,
475 buf, strlen(buf));
476 goto out;
477 }
478
479 r = simple_read_from_buffer(ubuf, cnt, ppos,
480 s->buffer, s->len);
481 out:
482 kfree(s);
483 return r;
484}
485
447static const struct seq_operations show_event_seq_ops = { 486static const struct seq_operations show_event_seq_ops = {
448 .start = t_start, 487 .start = t_start,
449 .next = t_next, 488 .next = t_next,
@@ -490,6 +529,11 @@ static const struct file_operations ftrace_available_types_fops = {
490 .read = event_available_types_read, 529 .read = event_available_types_read,
491}; 530};
492 531
532static const struct file_operations ftrace_event_format_fops = {
533 .open = tracing_open_generic,
534 .read = event_format_read,
535};
536
493static struct dentry *event_trace_events_dir(void) 537static struct dentry *event_trace_events_dir(void)
494{ 538{
495 static struct dentry *d_tracer; 539 static struct dentry *d_tracer;
@@ -602,7 +646,17 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
602 &ftrace_available_types_fops); 646 &ftrace_available_types_fops);
603 if (!entry) 647 if (!entry)
604 pr_warning("Could not create debugfs " 648 pr_warning("Could not create debugfs "
605 "'%s/type' available_types\n", call->name); 649 "'%s/available_types' entry\n", call->name);
650
651 /* A trace may not want to export its format */
652 if (!call->show_format)
653 return 0;
654
655 entry = debugfs_create_file("format", 0444, call->dir, call,
656 &ftrace_event_format_fops);
657 if (!entry)
658 pr_warning("Could not create debugfs "
659 "'%s/format' entry\n", call->name);
606 660
607 return 0; 661 return 0;
608} 662}
diff --git a/kernel/trace/trace_events_stage_2.h b/kernel/trace/trace_events_stage_2.h
index dc79fe3a2ecb..3a80ea4e92cb 100644
--- a/kernel/trace/trace_events_stage_2.h
+++ b/kernel/trace/trace_events_stage_2.h
@@ -74,3 +74,55 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
74} 74}
75 75
76#include <trace/trace_event_types.h> 76#include <trace/trace_event_types.h>
77
78/*
79 * Setup the showing format of trace point.
80 *
81 * int
82 * ftrace_format_##call(struct trace_seq *s)
83 * {
84 * struct ftrace_raw_##call field;
85 * int ret;
86 *
87 * ret = trace_seq_printf(s, #type " " #item ";"
88 * " size:%d; offset:%d;\n",
89 * sizeof(field.type),
90 * offsetof(struct ftrace_raw_##call,
91 * item));
92 *
93 * }
94 */
95
96#undef TRACE_FIELD
97#define TRACE_FIELD(type, item, assign) \
98 ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
99 "offset:%lu;\tsize:%lu;\n", \
100 offsetof(typeof(field), item), \
101 sizeof(field.item)); \
102 if (!ret) \
103 return 0;
104
105
106#undef TRACE_FIELD_SPECIAL
107#define TRACE_FIELD_SPECIAL(type_item, item, cmd) \
108 ret = trace_seq_printf(s, "\tfield special:" #type_item ";\t" \
109 "offset:%lu;\tsize:%lu;\n", \
110 offsetof(typeof(field), item), \
111 sizeof(field.item)); \
112 if (!ret) \
113 return 0;
114
115#undef TRACE_EVENT_FORMAT
116#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \
117int \
118ftrace_format_##call(struct trace_seq *s) \
119{ \
120 struct ftrace_raw_##call field; \
121 int ret; \
122 \
123 tstruct; \
124 \
125 return ret; \
126}
127
128#include <trace/trace_event_types.h>
diff --git a/kernel/trace/trace_events_stage_3.h b/kernel/trace/trace_events_stage_3.h
index 2ab65e958223..c62a4d2a5283 100644
--- a/kernel/trace/trace_events_stage_3.h
+++ b/kernel/trace/trace_events_stage_3.h
@@ -101,6 +101,7 @@
101 * .raw_init = ftrace_raw_init_event_<call>, 101 * .raw_init = ftrace_raw_init_event_<call>,
102 * .raw_reg = ftrace_raw_reg_event_<call>, 102 * .raw_reg = ftrace_raw_reg_event_<call>,
103 * .raw_unreg = ftrace_raw_unreg_event_<call>, 103 * .raw_unreg = ftrace_raw_unreg_event_<call>,
104 * .show_format = ftrace_format_<call>,
104 * } 105 * }
105 * 106 *
106 */ 107 */
@@ -230,4 +231,5 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
230 .raw_init = ftrace_raw_init_event_##call, \ 231 .raw_init = ftrace_raw_init_event_##call, \
231 .raw_reg = ftrace_raw_reg_event_##call, \ 232 .raw_reg = ftrace_raw_reg_event_##call, \
232 .raw_unreg = ftrace_raw_unreg_event_##call, \ 233 .raw_unreg = ftrace_raw_unreg_event_##call, \
234 .show_format = ftrace_format_##call, \
233} 235}