aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/trace.h5
-rw-r--r--kernel/trace/trace_event_types.h3
-rw-r--r--kernel/trace/trace_events.c159
-rw-r--r--kernel/trace/trace_events_stage_1.h28
-rw-r--r--kernel/trace/trace_events_stage_2.h89
-rw-r--r--kernel/trace/trace_events_stage_3.h34
-rw-r--r--kernel/trace/trace_export.c23
7 files changed, 124 insertions, 217 deletions
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 2bfb7d11fc17..c5e1d8865fe4 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -751,12 +751,7 @@ struct ftrace_event_call {
751 int (*regfunc)(void); 751 int (*regfunc)(void);
752 void (*unregfunc)(void); 752 void (*unregfunc)(void);
753 int id; 753 int id;
754 struct dentry *raw_dir;
755 int raw_enabled;
756 int type;
757 int (*raw_init)(void); 754 int (*raw_init)(void);
758 int (*raw_reg)(void);
759 void (*raw_unreg)(void);
760 int (*show_format)(struct trace_seq *s); 755 int (*show_format)(struct trace_seq *s);
761}; 756};
762 757
diff --git a/kernel/trace/trace_event_types.h b/kernel/trace/trace_event_types.h
index d94179aa1fc2..5cca4c978bde 100644
--- a/kernel/trace/trace_event_types.h
+++ b/kernel/trace/trace_event_types.h
@@ -106,9 +106,10 @@ TRACE_EVENT_FORMAT(print, TRACE_PRINT, print_entry, ignore,
106 TRACE_STRUCT( 106 TRACE_STRUCT(
107 TRACE_FIELD(unsigned long, ip, ip) 107 TRACE_FIELD(unsigned long, ip, ip)
108 TRACE_FIELD(unsigned int, depth, depth) 108 TRACE_FIELD(unsigned int, depth, depth)
109 TRACE_FIELD(char *, fmt, fmt)
109 TRACE_FIELD_ZERO_CHAR(buf) 110 TRACE_FIELD_ZERO_CHAR(buf)
110 ), 111 ),
111 TP_RAW_FMT("%08lx (%d) %s") 112 TP_RAW_FMT("%08lx (%d) fmt:%p %s")
112); 113);
113 114
114TRACE_EVENT_FORMAT(branch, TRACE_BRANCH, trace_branch, ignore, 115TRACE_EVENT_FORMAT(branch, TRACE_BRANCH, trace_branch, ignore,
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index fa32ca320767..1880a6438097 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -59,22 +59,12 @@ static void ftrace_event_enable_disable(struct ftrace_event_call *call,
59 call->enabled = 0; 59 call->enabled = 0;
60 call->unregfunc(); 60 call->unregfunc();
61 } 61 }
62 if (call->raw_enabled) {
63 call->raw_enabled = 0;
64 call->raw_unreg();
65 }
66 break; 62 break;
67 case 1: 63 case 1:
68 if (!call->enabled && 64 if (!call->enabled) {
69 (call->type & TRACE_EVENT_TYPE_PRINTF)) {
70 call->enabled = 1; 65 call->enabled = 1;
71 call->regfunc(); 66 call->regfunc();
72 } 67 }
73 if (!call->raw_enabled &&
74 (call->type & TRACE_EVENT_TYPE_RAW)) {
75 call->raw_enabled = 1;
76 call->raw_reg();
77 }
78 break; 68 break;
79 } 69 }
80} 70}
@@ -300,7 +290,7 @@ event_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
300 struct ftrace_event_call *call = filp->private_data; 290 struct ftrace_event_call *call = filp->private_data;
301 char *buf; 291 char *buf;
302 292
303 if (call->enabled || call->raw_enabled) 293 if (call->enabled)
304 buf = "1\n"; 294 buf = "1\n";
305 else 295 else
306 buf = "0\n"; 296 buf = "0\n";
@@ -346,107 +336,6 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
346 return cnt; 336 return cnt;
347} 337}
348 338
349static ssize_t
350event_type_read(struct file *filp, char __user *ubuf, size_t cnt,
351 loff_t *ppos)
352{
353 struct ftrace_event_call *call = filp->private_data;
354 char buf[16];
355 int r = 0;
356
357 if (call->type & TRACE_EVENT_TYPE_PRINTF)
358 r += sprintf(buf, "printf\n");
359
360 if (call->type & TRACE_EVENT_TYPE_RAW)
361 r += sprintf(buf+r, "raw\n");
362
363 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
364}
365
366static ssize_t
367event_type_write(struct file *filp, const char __user *ubuf, size_t cnt,
368 loff_t *ppos)
369{
370 struct ftrace_event_call *call = filp->private_data;
371 char buf[64];
372
373 /*
374 * If there's only one type, we can't change it.
375 * And currently we always have printf type, and we
376 * may or may not have raw type.
377 *
378 * This is a redundant check, the file should be read
379 * only if this is the case anyway.
380 */
381
382 if (!call->raw_init)
383 return -EPERM;
384
385 if (cnt >= sizeof(buf))
386 return -EINVAL;
387
388 if (copy_from_user(&buf, ubuf, cnt))
389 return -EFAULT;
390
391 buf[cnt] = 0;
392
393 if (!strncmp(buf, "printf", 6) &&
394 (!buf[6] || isspace(buf[6]))) {
395
396 call->type = TRACE_EVENT_TYPE_PRINTF;
397
398 /*
399 * If raw enabled, the disable it and enable
400 * printf type.
401 */
402 if (call->raw_enabled) {
403 call->raw_enabled = 0;
404 call->raw_unreg();
405
406 call->enabled = 1;
407 call->regfunc();
408 }
409
410 } else if (!strncmp(buf, "raw", 3) &&
411 (!buf[3] || isspace(buf[3]))) {
412
413 call->type = TRACE_EVENT_TYPE_RAW;
414
415 /*
416 * If printf enabled, the disable it and enable
417 * raw type.
418 */
419 if (call->enabled) {
420 call->enabled = 0;
421 call->unregfunc();
422
423 call->raw_enabled = 1;
424 call->raw_reg();
425 }
426 } else
427 return -EINVAL;
428
429 *ppos += cnt;
430
431 return cnt;
432}
433
434static ssize_t
435event_available_types_read(struct file *filp, char __user *ubuf, size_t cnt,
436 loff_t *ppos)
437{
438 struct ftrace_event_call *call = filp->private_data;
439 char buf[16];
440 int r = 0;
441
442 r += sprintf(buf, "printf\n");
443
444 if (call->raw_init)
445 r += sprintf(buf+r, "raw\n");
446
447 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
448}
449
450#undef FIELD 339#undef FIELD
451#define FIELD(type, name) \ 340#define FIELD(type, name) \
452 #type, #name, (unsigned int)offsetof(typeof(field), name), \ 341 #type, #name, (unsigned int)offsetof(typeof(field), name), \
@@ -470,6 +359,7 @@ static int trace_write_header(struct trace_seq *s)
470 FIELD(int, pid), 359 FIELD(int, pid),
471 FIELD(int, tgid)); 360 FIELD(int, tgid));
472} 361}
362
473static ssize_t 363static ssize_t
474event_format_read(struct file *filp, char __user *ubuf, size_t cnt, 364event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
475 loff_t *ppos) 365 loff_t *ppos)
@@ -527,13 +417,6 @@ static const struct seq_operations show_set_event_seq_ops = {
527 .stop = t_stop, 417 .stop = t_stop,
528}; 418};
529 419
530static const struct file_operations ftrace_avail_fops = {
531 .open = ftrace_event_seq_open,
532 .read = seq_read,
533 .llseek = seq_lseek,
534 .release = seq_release,
535};
536
537static const struct file_operations ftrace_set_event_fops = { 420static const struct file_operations ftrace_set_event_fops = {
538 .open = ftrace_event_seq_open, 421 .open = ftrace_event_seq_open,
539 .read = seq_read, 422 .read = seq_read,
@@ -548,17 +431,6 @@ static const struct file_operations ftrace_enable_fops = {
548 .write = event_enable_write, 431 .write = event_enable_write,
549}; 432};
550 433
551static const struct file_operations ftrace_type_fops = {
552 .open = tracing_open_generic,
553 .read = event_type_read,
554 .write = event_type_write,
555};
556
557static const struct file_operations ftrace_available_types_fops = {
558 .open = tracing_open_generic,
559 .read = event_available_types_read,
560};
561
562static const struct file_operations ftrace_event_format_fops = { 434static const struct file_operations ftrace_event_format_fops = {
563 .open = tracing_open_generic, 435 .open = tracing_open_generic,
564 .read = event_format_read, 436 .read = event_format_read,
@@ -647,9 +519,6 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
647 } 519 }
648 } 520 }
649 521
650 /* default the output to printf */
651 call->type = TRACE_EVENT_TYPE_PRINTF;
652
653 call->dir = debugfs_create_dir(call->name, d_events); 522 call->dir = debugfs_create_dir(call->name, d_events);
654 if (!call->dir) { 523 if (!call->dir) {
655 pr_warning("Could not create debugfs " 524 pr_warning("Could not create debugfs "
@@ -665,21 +534,6 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
665 "'%s/enable' entry\n", call->name); 534 "'%s/enable' entry\n", call->name);
666 } 535 }
667 536
668 /* Only let type be writable, if we can change it */
669 entry = debugfs_create_file("type",
670 call->raw_init ? 0644 : 0444,
671 call->dir, call,
672 &ftrace_type_fops);
673 if (!entry)
674 pr_warning("Could not create debugfs "
675 "'%s/type' entry\n", call->name);
676
677 entry = debugfs_create_file("available_types", 0444, call->dir, call,
678 &ftrace_available_types_fops);
679 if (!entry)
680 pr_warning("Could not create debugfs "
681 "'%s/available_types' entry\n", call->name);
682
683 /* A trace may not want to export its format */ 537 /* A trace may not want to export its format */
684 if (!call->show_format) 538 if (!call->show_format)
685 return 0; 539 return 0;
@@ -704,13 +558,6 @@ static __init int event_trace_init(void)
704 if (!d_tracer) 558 if (!d_tracer)
705 return 0; 559 return 0;
706 560
707 entry = debugfs_create_file("available_events", 0444, d_tracer,
708 (void *)&show_event_seq_ops,
709 &ftrace_avail_fops);
710 if (!entry)
711 pr_warning("Could not create debugfs "
712 "'available_events' entry\n");
713
714 entry = debugfs_create_file("set_event", 0644, d_tracer, 561 entry = debugfs_create_file("set_event", 0644, d_tracer,
715 (void *)&show_set_event_seq_ops, 562 (void *)&show_set_event_seq_ops,
716 &ftrace_set_event_fops); 563 &ftrace_set_event_fops);
diff --git a/kernel/trace/trace_events_stage_1.h b/kernel/trace/trace_events_stage_1.h
index 3830a731424c..edfcbd3a0d1b 100644
--- a/kernel/trace/trace_events_stage_1.h
+++ b/kernel/trace/trace_events_stage_1.h
@@ -18,19 +18,23 @@
18#define TRACE_FORMAT(call, proto, args, fmt) 18#define TRACE_FORMAT(call, proto, args, fmt)
19 19
20#undef TRACE_EVENT_FORMAT 20#undef TRACE_EVENT_FORMAT
21#define TRACE_EVENT_FORMAT(name, proto, args, fmt, tstruct, tpfmt) \ 21#define TRACE_EVENT_FORMAT(name, proto, args, fmt, tstruct, tpfmt)
22 struct ftrace_raw_##name { \ 22
23 struct trace_entry ent; \ 23#undef __array
24 tstruct \ 24#define __array(type, item, len) type item[len];
25 }; \
26 static struct ftrace_event_call event_##name
27 25
28#undef TRACE_STRUCT 26#undef __field
29#define TRACE_STRUCT(args...) args 27#define __field(type, item) type item;
30 28
31#define TRACE_FIELD(type, item, assign) \ 29#undef TP_STRUCT__entry
32 type item; 30#define TP_STRUCT__entry(args...) args
33#define TRACE_FIELD_SPECIAL(type_item, item, cmd) \ 31
34 type_item; 32#undef TRACE_EVENT
33#define TRACE_EVENT(name, proto, args, tstruct, print, assign) \
34 struct ftrace_raw_##name { \
35 struct trace_entry ent; \
36 tstruct \
37 }; \
38 static struct ftrace_event_call event_##name
35 39
36#include <trace/trace_event_types.h> 40#include <trace/trace_event_types.h>
diff --git a/kernel/trace/trace_events_stage_2.h b/kernel/trace/trace_events_stage_2.h
index 8e2e0f56c2a8..d91bf4c56661 100644
--- a/kernel/trace/trace_events_stage_2.h
+++ b/kernel/trace/trace_events_stage_2.h
@@ -32,23 +32,14 @@
32 * in binary. 32 * in binary.
33 */ 33 */
34 34
35#undef TRACE_STRUCT 35#undef __entry
36#define TRACE_STRUCT(args...) args 36#define __entry field
37 37
38#undef TRACE_FIELD 38#undef TP_printk
39#define TRACE_FIELD(type, item, assign) \ 39#define TP_printk(fmt, args...) fmt "\n", args
40 field->item,
41 40
42#undef TRACE_FIELD_SPECIAL 41#undef TRACE_EVENT
43#define TRACE_FIELD_SPECIAL(type_item, item, cmd) \ 42#define TRACE_EVENT(call, proto, args, tstruct, print, assign) \
44 field->item,
45
46
47#undef TP_RAW_FMT
48#define TP_RAW_FMT(args...) args
49
50#undef TRACE_EVENT_FORMAT
51#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \
52enum print_line_t \ 43enum print_line_t \
53ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ 44ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
54{ \ 45{ \
@@ -66,14 +57,76 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \
66 \ 57 \
67 field = (typeof(field))entry; \ 58 field = (typeof(field))entry; \
68 \ 59 \
69 ret = trace_seq_printf(s, tpfmt "%s", tstruct "\n"); \ 60 ret = trace_seq_printf(s, print); \
70 if (!ret) \ 61 if (!ret) \
71 return TRACE_TYPE_PARTIAL_LINE; \ 62 return TRACE_TYPE_PARTIAL_LINE; \
72 \ 63 \
73 return TRACE_TYPE_HANDLED; \ 64 return TRACE_TYPE_HANDLED; \
74} 65}
75 66
76#include <trace/trace_event_types.h> 67#include <trace/trace_event_types.h>
77 68
78#include "trace_format.h" 69/*
70 * Setup the showing format of trace point.
71 *
72 * int
73 * ftrace_format_##call(struct trace_seq *s)
74 * {
75 * struct ftrace_raw_##call field;
76 * int ret;
77 *
78 * ret = trace_seq_printf(s, #type " " #item ";"
79 * " size:%d; offset:%d;\n",
80 * sizeof(field.type),
81 * offsetof(struct ftrace_raw_##call,
82 * item));
83 *
84 * }
85 */
86
87#undef TP_STRUCT__entry
88#define TP_STRUCT__entry(args...) args
89
90#undef __field
91#define __field(type, item) \
92 ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
93 "offset:%u;\tsize:%u;\n", \
94 (unsigned int)offsetof(typeof(field), item), \
95 (unsigned int)sizeof(field.item)); \
96 if (!ret) \
97 return 0;
98
99#undef __array
100#define __array(type, item, len) \
101 ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
102 "offset:%u;\tsize:%u;\n", \
103 (unsigned int)offsetof(typeof(field), item), \
104 (unsigned int)sizeof(field.item)); \
105 if (!ret) \
106 return 0;
107
108#undef __entry
109#define __entry "REC"
110
111#undef TP_printk
112#define TP_printk(fmt, args...) "%s, %s\n", #fmt, #args
113
114#undef TP_fast_assign
115#define TP_fast_assign(args...) args
116
117#undef TRACE_EVENT
118#define TRACE_EVENT(call, proto, args, tstruct, print, func) \
119static int \
120ftrace_format_##call(struct trace_seq *s) \
121{ \
122 struct ftrace_raw_##call field; \
123 int ret; \
124 \
125 tstruct; \
126 \
127 trace_seq_printf(s, "\nprint fmt: " print); \
128 \
129 return ret; \
130}
131
79#include <trace/trace_event_types.h> 132#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 41b82b93c9c7..8e398d864096 100644
--- a/kernel/trace/trace_events_stage_3.h
+++ b/kernel/trace/trace_events_stage_3.h
@@ -144,27 +144,15 @@ __attribute__((section("_ftrace_events"))) event_##call = { \
144 .unregfunc = ftrace_unreg_event_##call, \ 144 .unregfunc = ftrace_unreg_event_##call, \
145} 145}
146 146
147#undef TRACE_FIELD 147#undef TRACE_EVENT_FORMAT
148#define TRACE_FIELD(type, item, assign)\ 148#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, raw) \
149 entry->item = assign; 149 TRACE_FORMAT(call, PARAMS(proto), PARAMS(args), PARAMS(fmt))
150
151#undef TRACE_FIELD
152#define TRACE_FIELD(type, item, assign)\
153 entry->item = assign;
154
155#undef TP_CMD
156#define TP_CMD(cmd...) cmd
157
158#undef TRACE_ENTRY
159#define TRACE_ENTRY entry
160 150
161#undef TRACE_FIELD_SPECIAL 151#undef __entry
162#define TRACE_FIELD_SPECIAL(type_item, item, cmd) \ 152#define __entry entry
163 cmd;
164 153
165#undef TRACE_EVENT_FORMAT 154#undef TRACE_EVENT
166#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt) \ 155#define TRACE_EVENT(call, proto, args, tstruct, print, assign) \
167_TRACE_FORMAT(call, PARAMS(proto), PARAMS(args), PARAMS(fmt)) \
168 \ 156 \
169static struct ftrace_event_call event_##call; \ 157static struct ftrace_event_call event_##call; \
170 \ 158 \
@@ -185,7 +173,7 @@ static void ftrace_raw_event_##call(proto) \
185 return; \ 173 return; \
186 entry = ring_buffer_event_data(event); \ 174 entry = ring_buffer_event_data(event); \
187 \ 175 \
188 tstruct; \ 176 assign; \
189 \ 177 \
190 trace_current_buffer_unlock_commit(event, irq_flags, pc); \ 178 trace_current_buffer_unlock_commit(event, irq_flags, pc); \
191} \ 179} \
@@ -226,10 +214,8 @@ __attribute__((__aligned__(4))) \
226__attribute__((section("_ftrace_events"))) event_##call = { \ 214__attribute__((section("_ftrace_events"))) event_##call = { \
227 .name = #call, \ 215 .name = #call, \
228 .system = __stringify(TRACE_SYSTEM), \ 216 .system = __stringify(TRACE_SYSTEM), \
229 .regfunc = ftrace_reg_event_##call, \
230 .unregfunc = ftrace_unreg_event_##call, \
231 .raw_init = ftrace_raw_init_event_##call, \ 217 .raw_init = ftrace_raw_init_event_##call, \
232 .raw_reg = ftrace_raw_reg_event_##call, \ 218 .regfunc = ftrace_raw_reg_event_##call, \
233 .raw_unreg = ftrace_raw_unreg_event_##call, \ 219 .unregfunc = ftrace_raw_unreg_event_##call, \
234 .show_format = ftrace_format_##call, \ 220 .show_format = ftrace_format_##call, \
235} 221}
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c
index e62bc10f8103..23ae78430d58 100644
--- a/kernel/trace/trace_export.c
+++ b/kernel/trace/trace_export.c
@@ -15,7 +15,28 @@
15 15
16#include "trace_output.h" 16#include "trace_output.h"
17 17
18#include "trace_format.h" 18
19#undef TRACE_STRUCT
20#define TRACE_STRUCT(args...) args
21
22#undef TRACE_FIELD
23#define TRACE_FIELD(type, item, assign) \
24 ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t" \
25 "offset:%u;\tsize:%u;\n", \
26 (unsigned int)offsetof(typeof(field), item), \
27 (unsigned int)sizeof(field.item)); \
28 if (!ret) \
29 return 0;
30
31
32#undef TRACE_FIELD_SPECIAL
33#define TRACE_FIELD_SPECIAL(type_item, item, cmd) \
34 ret = trace_seq_printf(s, "\tfield special:" #type_item ";\t" \
35 "offset:%u;\tsize:%u;\n", \
36 (unsigned int)offsetof(typeof(field), item), \
37 (unsigned int)sizeof(field.item)); \
38 if (!ret) \
39 return 0;
19 40
20#undef TRACE_FIELD_ZERO_CHAR 41#undef TRACE_FIELD_ZERO_CHAR
21#define TRACE_FIELD_ZERO_CHAR(item) \ 42#define TRACE_FIELD_ZERO_CHAR(item) \