diff options
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/ftrace.h | 6 | ||||
-rw-r--r-- | include/linux/ftrace_event.h | 111 | ||||
-rw-r--r-- | include/linux/kernel.h | 70 | ||||
-rw-r--r-- | include/linux/ring_buffer.h | 6 | ||||
-rw-r--r-- | include/linux/trace_clock.h | 1 |
5 files changed, 163 insertions, 31 deletions
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 52da2a250795..f83e17a40e8b 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h | |||
@@ -261,8 +261,10 @@ struct ftrace_probe_ops { | |||
261 | void (*func)(unsigned long ip, | 261 | void (*func)(unsigned long ip, |
262 | unsigned long parent_ip, | 262 | unsigned long parent_ip, |
263 | void **data); | 263 | void **data); |
264 | int (*callback)(unsigned long ip, void **data); | 264 | int (*init)(struct ftrace_probe_ops *ops, |
265 | void (*free)(void **data); | 265 | unsigned long ip, void **data); |
266 | void (*free)(struct ftrace_probe_ops *ops, | ||
267 | unsigned long ip, void **data); | ||
266 | int (*print)(struct seq_file *m, | 268 | int (*print)(struct seq_file *m, |
267 | unsigned long ip, | 269 | unsigned long ip, |
268 | struct ftrace_probe_ops *ops, | 270 | struct ftrace_probe_ops *ops, |
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 13a54d0bdfa8..34e00fb49bec 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/perf_event.h> | 8 | #include <linux/perf_event.h> |
9 | 9 | ||
10 | struct trace_array; | 10 | struct trace_array; |
11 | struct trace_buffer; | ||
11 | struct tracer; | 12 | struct tracer; |
12 | struct dentry; | 13 | struct dentry; |
13 | 14 | ||
@@ -38,6 +39,12 @@ const char *ftrace_print_symbols_seq_u64(struct trace_seq *p, | |||
38 | const char *ftrace_print_hex_seq(struct trace_seq *p, | 39 | const char *ftrace_print_hex_seq(struct trace_seq *p, |
39 | const unsigned char *buf, int len); | 40 | const unsigned char *buf, int len); |
40 | 41 | ||
42 | struct trace_iterator; | ||
43 | struct trace_event; | ||
44 | |||
45 | int ftrace_raw_output_prep(struct trace_iterator *iter, | ||
46 | struct trace_event *event); | ||
47 | |||
41 | /* | 48 | /* |
42 | * The trace entry - the most basic unit of tracing. This is what | 49 | * The trace entry - the most basic unit of tracing. This is what |
43 | * is printed in the end as a single line in the trace output, such as: | 50 | * is printed in the end as a single line in the trace output, such as: |
@@ -61,6 +68,7 @@ struct trace_entry { | |||
61 | struct trace_iterator { | 68 | struct trace_iterator { |
62 | struct trace_array *tr; | 69 | struct trace_array *tr; |
63 | struct tracer *trace; | 70 | struct tracer *trace; |
71 | struct trace_buffer *trace_buffer; | ||
64 | void *private; | 72 | void *private; |
65 | int cpu_file; | 73 | int cpu_file; |
66 | struct mutex mutex; | 74 | struct mutex mutex; |
@@ -95,8 +103,6 @@ enum trace_iter_flags { | |||
95 | }; | 103 | }; |
96 | 104 | ||
97 | 105 | ||
98 | struct trace_event; | ||
99 | |||
100 | typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter, | 106 | typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter, |
101 | int flags, struct trace_event *event); | 107 | int flags, struct trace_event *event); |
102 | 108 | ||
@@ -128,6 +134,13 @@ enum print_line_t { | |||
128 | void tracing_generic_entry_update(struct trace_entry *entry, | 134 | void tracing_generic_entry_update(struct trace_entry *entry, |
129 | unsigned long flags, | 135 | unsigned long flags, |
130 | int pc); | 136 | int pc); |
137 | struct ftrace_event_file; | ||
138 | |||
139 | struct ring_buffer_event * | ||
140 | trace_event_buffer_lock_reserve(struct ring_buffer **current_buffer, | ||
141 | struct ftrace_event_file *ftrace_file, | ||
142 | int type, unsigned long len, | ||
143 | unsigned long flags, int pc); | ||
131 | struct ring_buffer_event * | 144 | struct ring_buffer_event * |
132 | trace_current_buffer_lock_reserve(struct ring_buffer **current_buffer, | 145 | trace_current_buffer_lock_reserve(struct ring_buffer **current_buffer, |
133 | int type, unsigned long len, | 146 | int type, unsigned long len, |
@@ -182,53 +195,49 @@ extern int ftrace_event_reg(struct ftrace_event_call *event, | |||
182 | enum trace_reg type, void *data); | 195 | enum trace_reg type, void *data); |
183 | 196 | ||
184 | enum { | 197 | enum { |
185 | TRACE_EVENT_FL_ENABLED_BIT, | ||
186 | TRACE_EVENT_FL_FILTERED_BIT, | 198 | TRACE_EVENT_FL_FILTERED_BIT, |
187 | TRACE_EVENT_FL_RECORDED_CMD_BIT, | ||
188 | TRACE_EVENT_FL_CAP_ANY_BIT, | 199 | TRACE_EVENT_FL_CAP_ANY_BIT, |
189 | TRACE_EVENT_FL_NO_SET_FILTER_BIT, | 200 | TRACE_EVENT_FL_NO_SET_FILTER_BIT, |
190 | TRACE_EVENT_FL_IGNORE_ENABLE_BIT, | 201 | TRACE_EVENT_FL_IGNORE_ENABLE_BIT, |
202 | TRACE_EVENT_FL_WAS_ENABLED_BIT, | ||
191 | }; | 203 | }; |
192 | 204 | ||
205 | /* | ||
206 | * Event flags: | ||
207 | * FILTERED - The event has a filter attached | ||
208 | * CAP_ANY - Any user can enable for perf | ||
209 | * NO_SET_FILTER - Set when filter has error and is to be ignored | ||
210 | * IGNORE_ENABLE - For ftrace internal events, do not enable with debugfs file | ||
211 | * WAS_ENABLED - Set and stays set when an event was ever enabled | ||
212 | * (used for module unloading, if a module event is enabled, | ||
213 | * it is best to clear the buffers that used it). | ||
214 | */ | ||
193 | enum { | 215 | enum { |
194 | TRACE_EVENT_FL_ENABLED = (1 << TRACE_EVENT_FL_ENABLED_BIT), | ||
195 | TRACE_EVENT_FL_FILTERED = (1 << TRACE_EVENT_FL_FILTERED_BIT), | 216 | TRACE_EVENT_FL_FILTERED = (1 << TRACE_EVENT_FL_FILTERED_BIT), |
196 | TRACE_EVENT_FL_RECORDED_CMD = (1 << TRACE_EVENT_FL_RECORDED_CMD_BIT), | ||
197 | TRACE_EVENT_FL_CAP_ANY = (1 << TRACE_EVENT_FL_CAP_ANY_BIT), | 217 | TRACE_EVENT_FL_CAP_ANY = (1 << TRACE_EVENT_FL_CAP_ANY_BIT), |
198 | TRACE_EVENT_FL_NO_SET_FILTER = (1 << TRACE_EVENT_FL_NO_SET_FILTER_BIT), | 218 | TRACE_EVENT_FL_NO_SET_FILTER = (1 << TRACE_EVENT_FL_NO_SET_FILTER_BIT), |
199 | TRACE_EVENT_FL_IGNORE_ENABLE = (1 << TRACE_EVENT_FL_IGNORE_ENABLE_BIT), | 219 | TRACE_EVENT_FL_IGNORE_ENABLE = (1 << TRACE_EVENT_FL_IGNORE_ENABLE_BIT), |
220 | TRACE_EVENT_FL_WAS_ENABLED = (1 << TRACE_EVENT_FL_WAS_ENABLED_BIT), | ||
200 | }; | 221 | }; |
201 | 222 | ||
202 | struct ftrace_event_call { | 223 | struct ftrace_event_call { |
203 | struct list_head list; | 224 | struct list_head list; |
204 | struct ftrace_event_class *class; | 225 | struct ftrace_event_class *class; |
205 | char *name; | 226 | char *name; |
206 | struct dentry *dir; | ||
207 | struct trace_event event; | 227 | struct trace_event event; |
208 | const char *print_fmt; | 228 | const char *print_fmt; |
209 | struct event_filter *filter; | 229 | struct event_filter *filter; |
230 | struct list_head *files; | ||
210 | void *mod; | 231 | void *mod; |
211 | void *data; | 232 | void *data; |
212 | |||
213 | /* | 233 | /* |
214 | * 32 bit flags: | 234 | * bit 0: filter_active |
215 | * bit 1: enabled | 235 | * bit 1: allow trace by non root (cap any) |
216 | * bit 2: filter_active | 236 | * bit 2: failed to apply filter |
217 | * bit 3: enabled cmd record | 237 | * bit 3: ftrace internal event (do not enable) |
218 | * bit 4: allow trace by non root (cap any) | 238 | * bit 4: Event was enabled by module |
219 | * bit 5: failed to apply filter | ||
220 | * bit 6: ftrace internal event (do not enable) | ||
221 | * | ||
222 | * Changes to flags must hold the event_mutex. | ||
223 | * | ||
224 | * Note: Reads of flags do not hold the event_mutex since | ||
225 | * they occur in critical sections. But the way flags | ||
226 | * is currently used, these changes do no affect the code | ||
227 | * except that when a change is made, it may have a slight | ||
228 | * delay in propagating the changes to other CPUs due to | ||
229 | * caching and such. | ||
230 | */ | 239 | */ |
231 | unsigned int flags; | 240 | int flags; /* static flags of different events */ |
232 | 241 | ||
233 | #ifdef CONFIG_PERF_EVENTS | 242 | #ifdef CONFIG_PERF_EVENTS |
234 | int perf_refcount; | 243 | int perf_refcount; |
@@ -236,6 +245,56 @@ struct ftrace_event_call { | |||
236 | #endif | 245 | #endif |
237 | }; | 246 | }; |
238 | 247 | ||
248 | struct trace_array; | ||
249 | struct ftrace_subsystem_dir; | ||
250 | |||
251 | enum { | ||
252 | FTRACE_EVENT_FL_ENABLED_BIT, | ||
253 | FTRACE_EVENT_FL_RECORDED_CMD_BIT, | ||
254 | FTRACE_EVENT_FL_SOFT_MODE_BIT, | ||
255 | FTRACE_EVENT_FL_SOFT_DISABLED_BIT, | ||
256 | }; | ||
257 | |||
258 | /* | ||
259 | * Ftrace event file flags: | ||
260 | * ENABLED - The event is enabled | ||
261 | * RECORDED_CMD - The comms should be recorded at sched_switch | ||
262 | * SOFT_MODE - The event is enabled/disabled by SOFT_DISABLED | ||
263 | * SOFT_DISABLED - When set, do not trace the event (even though its | ||
264 | * tracepoint may be enabled) | ||
265 | */ | ||
266 | enum { | ||
267 | FTRACE_EVENT_FL_ENABLED = (1 << FTRACE_EVENT_FL_ENABLED_BIT), | ||
268 | FTRACE_EVENT_FL_RECORDED_CMD = (1 << FTRACE_EVENT_FL_RECORDED_CMD_BIT), | ||
269 | FTRACE_EVENT_FL_SOFT_MODE = (1 << FTRACE_EVENT_FL_SOFT_MODE_BIT), | ||
270 | FTRACE_EVENT_FL_SOFT_DISABLED = (1 << FTRACE_EVENT_FL_SOFT_DISABLED_BIT), | ||
271 | }; | ||
272 | |||
273 | struct ftrace_event_file { | ||
274 | struct list_head list; | ||
275 | struct ftrace_event_call *event_call; | ||
276 | struct dentry *dir; | ||
277 | struct trace_array *tr; | ||
278 | struct ftrace_subsystem_dir *system; | ||
279 | |||
280 | /* | ||
281 | * 32 bit flags: | ||
282 | * bit 0: enabled | ||
283 | * bit 1: enabled cmd record | ||
284 | * bit 2: enable/disable with the soft disable bit | ||
285 | * bit 3: soft disabled | ||
286 | * | ||
287 | * Note: The bits must be set atomically to prevent races | ||
288 | * from other writers. Reads of flags do not need to be in | ||
289 | * sync as they occur in critical sections. But the way flags | ||
290 | * is currently used, these changes do not affect the code | ||
291 | * except that when a change is made, it may have a slight | ||
292 | * delay in propagating the changes to other CPUs due to | ||
293 | * caching and such. Which is mostly OK ;-) | ||
294 | */ | ||
295 | unsigned long flags; | ||
296 | }; | ||
297 | |||
239 | #define __TRACE_EVENT_FLAGS(name, value) \ | 298 | #define __TRACE_EVENT_FLAGS(name, value) \ |
240 | static int __init trace_init_flags_##name(void) \ | 299 | static int __init trace_init_flags_##name(void) \ |
241 | { \ | 300 | { \ |
@@ -274,7 +333,7 @@ extern int trace_define_field(struct ftrace_event_call *call, const char *type, | |||
274 | extern int trace_add_event_call(struct ftrace_event_call *call); | 333 | extern int trace_add_event_call(struct ftrace_event_call *call); |
275 | extern void trace_remove_event_call(struct ftrace_event_call *call); | 334 | extern void trace_remove_event_call(struct ftrace_event_call *call); |
276 | 335 | ||
277 | #define is_signed_type(type) (((type)(-1)) < (type)0) | 336 | #define is_signed_type(type) (((type)(-1)) < (type)1) |
278 | 337 | ||
279 | int trace_set_clr_event(const char *system, const char *event, int set); | 338 | int trace_set_clr_event(const char *system, const char *event, int set); |
280 | 339 | ||
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 79fdd80a42d4..2dac79c39199 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -486,6 +486,8 @@ enum ftrace_dump_mode { | |||
486 | void tracing_on(void); | 486 | void tracing_on(void); |
487 | void tracing_off(void); | 487 | void tracing_off(void); |
488 | int tracing_is_on(void); | 488 | int tracing_is_on(void); |
489 | void tracing_snapshot(void); | ||
490 | void tracing_snapshot_alloc(void); | ||
489 | 491 | ||
490 | extern void tracing_start(void); | 492 | extern void tracing_start(void); |
491 | extern void tracing_stop(void); | 493 | extern void tracing_stop(void); |
@@ -515,10 +517,32 @@ do { \ | |||
515 | * | 517 | * |
516 | * This is intended as a debugging tool for the developer only. | 518 | * This is intended as a debugging tool for the developer only. |
517 | * Please refrain from leaving trace_printks scattered around in | 519 | * Please refrain from leaving trace_printks scattered around in |
518 | * your code. | 520 | * your code. (Extra memory is used for special buffers that are |
521 | * allocated when trace_printk() is used) | ||
522 | * | ||
523 | * A little optization trick is done here. If there's only one | ||
524 | * argument, there's no need to scan the string for printf formats. | ||
525 | * The trace_puts() will suffice. But how can we take advantage of | ||
526 | * using trace_puts() when trace_printk() has only one argument? | ||
527 | * By stringifying the args and checking the size we can tell | ||
528 | * whether or not there are args. __stringify((__VA_ARGS__)) will | ||
529 | * turn into "()\0" with a size of 3 when there are no args, anything | ||
530 | * else will be bigger. All we need to do is define a string to this, | ||
531 | * and then take its size and compare to 3. If it's bigger, use | ||
532 | * do_trace_printk() otherwise, optimize it to trace_puts(). Then just | ||
533 | * let gcc optimize the rest. | ||
519 | */ | 534 | */ |
520 | 535 | ||
521 | #define trace_printk(fmt, args...) \ | 536 | #define trace_printk(fmt, ...) \ |
537 | do { \ | ||
538 | char _______STR[] = __stringify((__VA_ARGS__)); \ | ||
539 | if (sizeof(_______STR) > 3) \ | ||
540 | do_trace_printk(fmt, ##__VA_ARGS__); \ | ||
541 | else \ | ||
542 | trace_puts(fmt); \ | ||
543 | } while (0) | ||
544 | |||
545 | #define do_trace_printk(fmt, args...) \ | ||
522 | do { \ | 546 | do { \ |
523 | static const char *trace_printk_fmt \ | 547 | static const char *trace_printk_fmt \ |
524 | __attribute__((section("__trace_printk_fmt"))) = \ | 548 | __attribute__((section("__trace_printk_fmt"))) = \ |
@@ -538,7 +562,45 @@ int __trace_bprintk(unsigned long ip, const char *fmt, ...); | |||
538 | extern __printf(2, 3) | 562 | extern __printf(2, 3) |
539 | int __trace_printk(unsigned long ip, const char *fmt, ...); | 563 | int __trace_printk(unsigned long ip, const char *fmt, ...); |
540 | 564 | ||
541 | extern void trace_dump_stack(void); | 565 | /** |
566 | * trace_puts - write a string into the ftrace buffer | ||
567 | * @str: the string to record | ||
568 | * | ||
569 | * Note: __trace_bputs is an internal function for trace_puts and | ||
570 | * the @ip is passed in via the trace_puts macro. | ||
571 | * | ||
572 | * This is similar to trace_printk() but is made for those really fast | ||
573 | * paths that a developer wants the least amount of "Heisenbug" affects, | ||
574 | * where the processing of the print format is still too much. | ||
575 | * | ||
576 | * This function allows a kernel developer to debug fast path sections | ||
577 | * that printk is not appropriate for. By scattering in various | ||
578 | * printk like tracing in the code, a developer can quickly see | ||
579 | * where problems are occurring. | ||
580 | * | ||
581 | * This is intended as a debugging tool for the developer only. | ||
582 | * Please refrain from leaving trace_puts scattered around in | ||
583 | * your code. (Extra memory is used for special buffers that are | ||
584 | * allocated when trace_puts() is used) | ||
585 | * | ||
586 | * Returns: 0 if nothing was written, positive # if string was. | ||
587 | * (1 when __trace_bputs is used, strlen(str) when __trace_puts is used) | ||
588 | */ | ||
589 | |||
590 | extern int __trace_bputs(unsigned long ip, const char *str); | ||
591 | extern int __trace_puts(unsigned long ip, const char *str, int size); | ||
592 | #define trace_puts(str) ({ \ | ||
593 | static const char *trace_printk_fmt \ | ||
594 | __attribute__((section("__trace_printk_fmt"))) = \ | ||
595 | __builtin_constant_p(str) ? str : NULL; \ | ||
596 | \ | ||
597 | if (__builtin_constant_p(str)) \ | ||
598 | __trace_bputs(_THIS_IP_, trace_printk_fmt); \ | ||
599 | else \ | ||
600 | __trace_puts(_THIS_IP_, str, strlen(str)); \ | ||
601 | }) | ||
602 | |||
603 | extern void trace_dump_stack(int skip); | ||
542 | 604 | ||
543 | /* | 605 | /* |
544 | * The double __builtin_constant_p is because gcc will give us an error | 606 | * The double __builtin_constant_p is because gcc will give us an error |
@@ -573,6 +635,8 @@ static inline void trace_dump_stack(void) { } | |||
573 | static inline void tracing_on(void) { } | 635 | static inline void tracing_on(void) { } |
574 | static inline void tracing_off(void) { } | 636 | static inline void tracing_off(void) { } |
575 | static inline int tracing_is_on(void) { return 0; } | 637 | static inline int tracing_is_on(void) { return 0; } |
638 | static inline void tracing_snapshot(void) { } | ||
639 | static inline void tracing_snapshot_alloc(void) { } | ||
576 | 640 | ||
577 | static inline __printf(1, 2) | 641 | static inline __printf(1, 2) |
578 | int trace_printk(const char *fmt, ...) | 642 | int trace_printk(const char *fmt, ...) |
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index 1342e69542f3..d69cf637a15a 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/kmemcheck.h> | 4 | #include <linux/kmemcheck.h> |
5 | #include <linux/mm.h> | 5 | #include <linux/mm.h> |
6 | #include <linux/seq_file.h> | 6 | #include <linux/seq_file.h> |
7 | #include <linux/poll.h> | ||
7 | 8 | ||
8 | struct ring_buffer; | 9 | struct ring_buffer; |
9 | struct ring_buffer_iter; | 10 | struct ring_buffer_iter; |
@@ -96,6 +97,11 @@ __ring_buffer_alloc(unsigned long size, unsigned flags, struct lock_class_key *k | |||
96 | __ring_buffer_alloc((size), (flags), &__key); \ | 97 | __ring_buffer_alloc((size), (flags), &__key); \ |
97 | }) | 98 | }) |
98 | 99 | ||
100 | void ring_buffer_wait(struct ring_buffer *buffer, int cpu); | ||
101 | int ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu, | ||
102 | struct file *filp, poll_table *poll_table); | ||
103 | |||
104 | |||
99 | #define RING_BUFFER_ALL_CPUS -1 | 105 | #define RING_BUFFER_ALL_CPUS -1 |
100 | 106 | ||
101 | void ring_buffer_free(struct ring_buffer *buffer); | 107 | void ring_buffer_free(struct ring_buffer *buffer); |
diff --git a/include/linux/trace_clock.h b/include/linux/trace_clock.h index d563f37e1a1d..1d7ca2739272 100644 --- a/include/linux/trace_clock.h +++ b/include/linux/trace_clock.h | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | extern u64 notrace trace_clock_local(void); | 17 | extern u64 notrace trace_clock_local(void); |
18 | extern u64 notrace trace_clock(void); | 18 | extern u64 notrace trace_clock(void); |
19 | extern u64 notrace trace_clock_jiffies(void); | ||
19 | extern u64 notrace trace_clock_global(void); | 20 | extern u64 notrace trace_clock_global(void); |
20 | extern u64 notrace trace_clock_counter(void); | 21 | extern u64 notrace trace_clock_counter(void); |
21 | 22 | ||