diff options
Diffstat (limited to 'kernel/trace/trace.h')
-rw-r--r-- | kernel/trace/trace.h | 219 |
1 files changed, 210 insertions, 9 deletions
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 8465ad052707..f96f4e787ff3 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/ring_buffer.h> | 8 | #include <linux/ring_buffer.h> |
9 | #include <linux/mmiotrace.h> | 9 | #include <linux/mmiotrace.h> |
10 | #include <linux/ftrace.h> | 10 | #include <linux/ftrace.h> |
11 | #include <trace/boot.h> | ||
11 | 12 | ||
12 | enum trace_type { | 13 | enum trace_type { |
13 | __TRACE_FIRST_TYPE = 0, | 14 | __TRACE_FIRST_TYPE = 0, |
@@ -21,7 +22,14 @@ enum trace_type { | |||
21 | TRACE_SPECIAL, | 22 | TRACE_SPECIAL, |
22 | TRACE_MMIO_RW, | 23 | TRACE_MMIO_RW, |
23 | TRACE_MMIO_MAP, | 24 | TRACE_MMIO_MAP, |
24 | TRACE_BOOT, | 25 | TRACE_BRANCH, |
26 | TRACE_BOOT_CALL, | ||
27 | TRACE_BOOT_RET, | ||
28 | TRACE_GRAPH_RET, | ||
29 | TRACE_GRAPH_ENT, | ||
30 | TRACE_USER_STACK, | ||
31 | TRACE_BTS, | ||
32 | TRACE_POWER, | ||
25 | 33 | ||
26 | __TRACE_LAST_TYPE | 34 | __TRACE_LAST_TYPE |
27 | }; | 35 | }; |
@@ -38,6 +46,7 @@ struct trace_entry { | |||
38 | unsigned char flags; | 46 | unsigned char flags; |
39 | unsigned char preempt_count; | 47 | unsigned char preempt_count; |
40 | int pid; | 48 | int pid; |
49 | int tgid; | ||
41 | }; | 50 | }; |
42 | 51 | ||
43 | /* | 52 | /* |
@@ -48,6 +57,18 @@ struct ftrace_entry { | |||
48 | unsigned long ip; | 57 | unsigned long ip; |
49 | unsigned long parent_ip; | 58 | unsigned long parent_ip; |
50 | }; | 59 | }; |
60 | |||
61 | /* Function call entry */ | ||
62 | struct ftrace_graph_ent_entry { | ||
63 | struct trace_entry ent; | ||
64 | struct ftrace_graph_ent graph_ent; | ||
65 | }; | ||
66 | |||
67 | /* Function return entry */ | ||
68 | struct ftrace_graph_ret_entry { | ||
69 | struct trace_entry ent; | ||
70 | struct ftrace_graph_ret ret; | ||
71 | }; | ||
51 | extern struct tracer boot_tracer; | 72 | extern struct tracer boot_tracer; |
52 | 73 | ||
53 | /* | 74 | /* |
@@ -85,6 +106,11 @@ struct stack_entry { | |||
85 | unsigned long caller[FTRACE_STACK_ENTRIES]; | 106 | unsigned long caller[FTRACE_STACK_ENTRIES]; |
86 | }; | 107 | }; |
87 | 108 | ||
109 | struct userstack_entry { | ||
110 | struct trace_entry ent; | ||
111 | unsigned long caller[FTRACE_STACK_ENTRIES]; | ||
112 | }; | ||
113 | |||
88 | /* | 114 | /* |
89 | * ftrace_printk entry: | 115 | * ftrace_printk entry: |
90 | */ | 116 | */ |
@@ -112,9 +138,35 @@ struct trace_mmiotrace_map { | |||
112 | struct mmiotrace_map map; | 138 | struct mmiotrace_map map; |
113 | }; | 139 | }; |
114 | 140 | ||
115 | struct trace_boot { | 141 | struct trace_boot_call { |
142 | struct trace_entry ent; | ||
143 | struct boot_trace_call boot_call; | ||
144 | }; | ||
145 | |||
146 | struct trace_boot_ret { | ||
147 | struct trace_entry ent; | ||
148 | struct boot_trace_ret boot_ret; | ||
149 | }; | ||
150 | |||
151 | #define TRACE_FUNC_SIZE 30 | ||
152 | #define TRACE_FILE_SIZE 20 | ||
153 | struct trace_branch { | ||
154 | struct trace_entry ent; | ||
155 | unsigned line; | ||
156 | char func[TRACE_FUNC_SIZE+1]; | ||
157 | char file[TRACE_FILE_SIZE+1]; | ||
158 | char correct; | ||
159 | }; | ||
160 | |||
161 | struct bts_entry { | ||
162 | struct trace_entry ent; | ||
163 | unsigned long from; | ||
164 | unsigned long to; | ||
165 | }; | ||
166 | |||
167 | struct trace_power { | ||
116 | struct trace_entry ent; | 168 | struct trace_entry ent; |
117 | struct boot_trace initcall; | 169 | struct power_trace state_data; |
118 | }; | 170 | }; |
119 | 171 | ||
120 | /* | 172 | /* |
@@ -172,7 +224,6 @@ struct trace_iterator; | |||
172 | struct trace_array { | 224 | struct trace_array { |
173 | struct ring_buffer *buffer; | 225 | struct ring_buffer *buffer; |
174 | unsigned long entries; | 226 | unsigned long entries; |
175 | long ctrl; | ||
176 | int cpu; | 227 | int cpu; |
177 | cycle_t time_start; | 228 | cycle_t time_start; |
178 | struct task_struct *waiter; | 229 | struct task_struct *waiter; |
@@ -212,13 +263,22 @@ extern void __ftrace_bad_type(void); | |||
212 | IF_ASSIGN(var, ent, struct ctx_switch_entry, 0); \ | 263 | IF_ASSIGN(var, ent, struct ctx_switch_entry, 0); \ |
213 | IF_ASSIGN(var, ent, struct trace_field_cont, TRACE_CONT); \ | 264 | IF_ASSIGN(var, ent, struct trace_field_cont, TRACE_CONT); \ |
214 | IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK); \ | 265 | IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK); \ |
266 | IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\ | ||
215 | IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT); \ | 267 | IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT); \ |
216 | IF_ASSIGN(var, ent, struct special_entry, 0); \ | 268 | IF_ASSIGN(var, ent, struct special_entry, 0); \ |
217 | IF_ASSIGN(var, ent, struct trace_mmiotrace_rw, \ | 269 | IF_ASSIGN(var, ent, struct trace_mmiotrace_rw, \ |
218 | TRACE_MMIO_RW); \ | 270 | TRACE_MMIO_RW); \ |
219 | IF_ASSIGN(var, ent, struct trace_mmiotrace_map, \ | 271 | IF_ASSIGN(var, ent, struct trace_mmiotrace_map, \ |
220 | TRACE_MMIO_MAP); \ | 272 | TRACE_MMIO_MAP); \ |
221 | IF_ASSIGN(var, ent, struct trace_boot, TRACE_BOOT); \ | 273 | IF_ASSIGN(var, ent, struct trace_boot_call, TRACE_BOOT_CALL);\ |
274 | IF_ASSIGN(var, ent, struct trace_boot_ret, TRACE_BOOT_RET);\ | ||
275 | IF_ASSIGN(var, ent, struct trace_branch, TRACE_BRANCH); \ | ||
276 | IF_ASSIGN(var, ent, struct ftrace_graph_ent_entry, \ | ||
277 | TRACE_GRAPH_ENT); \ | ||
278 | IF_ASSIGN(var, ent, struct ftrace_graph_ret_entry, \ | ||
279 | TRACE_GRAPH_RET); \ | ||
280 | IF_ASSIGN(var, ent, struct bts_entry, TRACE_BTS);\ | ||
281 | IF_ASSIGN(var, ent, struct trace_power, TRACE_POWER); \ | ||
222 | __ftrace_bad_type(); \ | 282 | __ftrace_bad_type(); \ |
223 | } while (0) | 283 | } while (0) |
224 | 284 | ||
@@ -229,29 +289,56 @@ enum print_line_t { | |||
229 | TRACE_TYPE_UNHANDLED = 2 /* Relay to other output functions */ | 289 | TRACE_TYPE_UNHANDLED = 2 /* Relay to other output functions */ |
230 | }; | 290 | }; |
231 | 291 | ||
292 | |||
293 | /* | ||
294 | * An option specific to a tracer. This is a boolean value. | ||
295 | * The bit is the bit index that sets its value on the | ||
296 | * flags value in struct tracer_flags. | ||
297 | */ | ||
298 | struct tracer_opt { | ||
299 | const char *name; /* Will appear on the trace_options file */ | ||
300 | u32 bit; /* Mask assigned in val field in tracer_flags */ | ||
301 | }; | ||
302 | |||
303 | /* | ||
304 | * The set of specific options for a tracer. Your tracer | ||
305 | * have to set the initial value of the flags val. | ||
306 | */ | ||
307 | struct tracer_flags { | ||
308 | u32 val; | ||
309 | struct tracer_opt *opts; | ||
310 | }; | ||
311 | |||
312 | /* Makes more easy to define a tracer opt */ | ||
313 | #define TRACER_OPT(s, b) .name = #s, .bit = b | ||
314 | |||
232 | /* | 315 | /* |
233 | * A specific tracer, represented by methods that operate on a trace array: | 316 | * A specific tracer, represented by methods that operate on a trace array: |
234 | */ | 317 | */ |
235 | struct tracer { | 318 | struct tracer { |
236 | const char *name; | 319 | const char *name; |
237 | void (*init)(struct trace_array *tr); | 320 | /* Your tracer should raise a warning if init fails */ |
321 | int (*init)(struct trace_array *tr); | ||
238 | void (*reset)(struct trace_array *tr); | 322 | void (*reset)(struct trace_array *tr); |
323 | void (*start)(struct trace_array *tr); | ||
324 | void (*stop)(struct trace_array *tr); | ||
239 | void (*open)(struct trace_iterator *iter); | 325 | void (*open)(struct trace_iterator *iter); |
240 | void (*pipe_open)(struct trace_iterator *iter); | 326 | void (*pipe_open)(struct trace_iterator *iter); |
241 | void (*close)(struct trace_iterator *iter); | 327 | void (*close)(struct trace_iterator *iter); |
242 | void (*start)(struct trace_iterator *iter); | ||
243 | void (*stop)(struct trace_iterator *iter); | ||
244 | ssize_t (*read)(struct trace_iterator *iter, | 328 | ssize_t (*read)(struct trace_iterator *iter, |
245 | struct file *filp, char __user *ubuf, | 329 | struct file *filp, char __user *ubuf, |
246 | size_t cnt, loff_t *ppos); | 330 | size_t cnt, loff_t *ppos); |
247 | void (*ctrl_update)(struct trace_array *tr); | ||
248 | #ifdef CONFIG_FTRACE_STARTUP_TEST | 331 | #ifdef CONFIG_FTRACE_STARTUP_TEST |
249 | int (*selftest)(struct tracer *trace, | 332 | int (*selftest)(struct tracer *trace, |
250 | struct trace_array *tr); | 333 | struct trace_array *tr); |
251 | #endif | 334 | #endif |
335 | void (*print_header)(struct seq_file *m); | ||
252 | enum print_line_t (*print_line)(struct trace_iterator *iter); | 336 | enum print_line_t (*print_line)(struct trace_iterator *iter); |
337 | /* If you handled the flag setting, return 0 */ | ||
338 | int (*set_flag)(u32 old_flags, u32 bit, int set); | ||
253 | struct tracer *next; | 339 | struct tracer *next; |
254 | int print_max; | 340 | int print_max; |
341 | struct tracer_flags *flags; | ||
255 | }; | 342 | }; |
256 | 343 | ||
257 | struct trace_seq { | 344 | struct trace_seq { |
@@ -279,8 +366,11 @@ struct trace_iterator { | |||
279 | unsigned long iter_flags; | 366 | unsigned long iter_flags; |
280 | loff_t pos; | 367 | loff_t pos; |
281 | long idx; | 368 | long idx; |
369 | |||
370 | cpumask_t started; | ||
282 | }; | 371 | }; |
283 | 372 | ||
373 | int tracing_is_enabled(void); | ||
284 | void trace_wake_up(void); | 374 | void trace_wake_up(void); |
285 | void tracing_reset(struct trace_array *tr, int cpu); | 375 | void tracing_reset(struct trace_array *tr, int cpu); |
286 | int tracing_open_generic(struct inode *inode, struct file *filp); | 376 | int tracing_open_generic(struct inode *inode, struct file *filp); |
@@ -321,8 +411,17 @@ void trace_function(struct trace_array *tr, | |||
321 | unsigned long parent_ip, | 411 | unsigned long parent_ip, |
322 | unsigned long flags, int pc); | 412 | unsigned long flags, int pc); |
323 | 413 | ||
414 | void trace_graph_return(struct ftrace_graph_ret *trace); | ||
415 | void trace_graph_entry(struct ftrace_graph_ent *trace); | ||
416 | void trace_bts(struct trace_array *tr, | ||
417 | unsigned long from, | ||
418 | unsigned long to); | ||
419 | |||
324 | void tracing_start_cmdline_record(void); | 420 | void tracing_start_cmdline_record(void); |
325 | void tracing_stop_cmdline_record(void); | 421 | void tracing_stop_cmdline_record(void); |
422 | void tracing_sched_switch_assign_trace(struct trace_array *tr); | ||
423 | void tracing_stop_sched_switch_record(void); | ||
424 | void tracing_start_sched_switch_record(void); | ||
326 | int register_tracer(struct tracer *type); | 425 | int register_tracer(struct tracer *type); |
327 | void unregister_tracer(struct tracer *type); | 426 | void unregister_tracer(struct tracer *type); |
328 | 427 | ||
@@ -358,6 +457,7 @@ struct tracer_switch_ops { | |||
358 | struct tracer_switch_ops *next; | 457 | struct tracer_switch_ops *next; |
359 | }; | 458 | }; |
360 | 459 | ||
460 | char *trace_find_cmdline(int pid); | ||
361 | #endif /* CONFIG_CONTEXT_SWITCH_TRACER */ | 461 | #endif /* CONFIG_CONTEXT_SWITCH_TRACER */ |
362 | 462 | ||
363 | #ifdef CONFIG_DYNAMIC_FTRACE | 463 | #ifdef CONFIG_DYNAMIC_FTRACE |
@@ -383,12 +483,18 @@ extern int trace_selftest_startup_sched_switch(struct tracer *trace, | |||
383 | struct trace_array *tr); | 483 | struct trace_array *tr); |
384 | extern int trace_selftest_startup_sysprof(struct tracer *trace, | 484 | extern int trace_selftest_startup_sysprof(struct tracer *trace, |
385 | struct trace_array *tr); | 485 | struct trace_array *tr); |
486 | extern int trace_selftest_startup_branch(struct tracer *trace, | ||
487 | struct trace_array *tr); | ||
386 | #endif /* CONFIG_FTRACE_STARTUP_TEST */ | 488 | #endif /* CONFIG_FTRACE_STARTUP_TEST */ |
387 | 489 | ||
388 | extern void *head_page(struct trace_array_cpu *data); | 490 | extern void *head_page(struct trace_array_cpu *data); |
389 | extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...); | 491 | extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...); |
390 | extern void trace_seq_print_cont(struct trace_seq *s, | 492 | extern void trace_seq_print_cont(struct trace_seq *s, |
391 | struct trace_iterator *iter); | 493 | struct trace_iterator *iter); |
494 | |||
495 | extern int | ||
496 | seq_print_ip_sym(struct trace_seq *s, unsigned long ip, | ||
497 | unsigned long sym_flags); | ||
392 | extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, | 498 | extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, |
393 | size_t cnt); | 499 | size_t cnt); |
394 | extern long ns2usecs(cycle_t nsec); | 500 | extern long ns2usecs(cycle_t nsec); |
@@ -396,6 +502,17 @@ extern int trace_vprintk(unsigned long ip, const char *fmt, va_list args); | |||
396 | 502 | ||
397 | extern unsigned long trace_flags; | 503 | extern unsigned long trace_flags; |
398 | 504 | ||
505 | /* Standard output formatting function used for function return traces */ | ||
506 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
507 | extern enum print_line_t print_graph_function(struct trace_iterator *iter); | ||
508 | #else | ||
509 | static inline enum print_line_t | ||
510 | print_graph_function(struct trace_iterator *iter) | ||
511 | { | ||
512 | return TRACE_TYPE_UNHANDLED; | ||
513 | } | ||
514 | #endif | ||
515 | |||
399 | /* | 516 | /* |
400 | * trace_iterator_flags is an enumeration that defines bit | 517 | * trace_iterator_flags is an enumeration that defines bit |
401 | * positions into trace_flags that controls the output. | 518 | * positions into trace_flags that controls the output. |
@@ -415,8 +532,92 @@ enum trace_iterator_flags { | |||
415 | TRACE_ITER_STACKTRACE = 0x100, | 532 | TRACE_ITER_STACKTRACE = 0x100, |
416 | TRACE_ITER_SCHED_TREE = 0x200, | 533 | TRACE_ITER_SCHED_TREE = 0x200, |
417 | TRACE_ITER_PRINTK = 0x400, | 534 | TRACE_ITER_PRINTK = 0x400, |
535 | TRACE_ITER_PREEMPTONLY = 0x800, | ||
536 | TRACE_ITER_BRANCH = 0x1000, | ||
537 | TRACE_ITER_ANNOTATE = 0x2000, | ||
538 | TRACE_ITER_USERSTACKTRACE = 0x4000, | ||
539 | TRACE_ITER_SYM_USEROBJ = 0x8000 | ||
418 | }; | 540 | }; |
419 | 541 | ||
542 | /* | ||
543 | * TRACE_ITER_SYM_MASK masks the options in trace_flags that | ||
544 | * control the output of kernel symbols. | ||
545 | */ | ||
546 | #define TRACE_ITER_SYM_MASK \ | ||
547 | (TRACE_ITER_PRINT_PARENT|TRACE_ITER_SYM_OFFSET|TRACE_ITER_SYM_ADDR) | ||
548 | |||
420 | extern struct tracer nop_trace; | 549 | extern struct tracer nop_trace; |
421 | 550 | ||
551 | /** | ||
552 | * ftrace_preempt_disable - disable preemption scheduler safe | ||
553 | * | ||
554 | * When tracing can happen inside the scheduler, there exists | ||
555 | * cases that the tracing might happen before the need_resched | ||
556 | * flag is checked. If this happens and the tracer calls | ||
557 | * preempt_enable (after a disable), a schedule might take place | ||
558 | * causing an infinite recursion. | ||
559 | * | ||
560 | * To prevent this, we read the need_recshed flag before | ||
561 | * disabling preemption. When we want to enable preemption we | ||
562 | * check the flag, if it is set, then we call preempt_enable_no_resched. | ||
563 | * Otherwise, we call preempt_enable. | ||
564 | * | ||
565 | * The rational for doing the above is that if need resched is set | ||
566 | * and we have yet to reschedule, we are either in an atomic location | ||
567 | * (where we do not need to check for scheduling) or we are inside | ||
568 | * the scheduler and do not want to resched. | ||
569 | */ | ||
570 | static inline int ftrace_preempt_disable(void) | ||
571 | { | ||
572 | int resched; | ||
573 | |||
574 | resched = need_resched(); | ||
575 | preempt_disable_notrace(); | ||
576 | |||
577 | return resched; | ||
578 | } | ||
579 | |||
580 | /** | ||
581 | * ftrace_preempt_enable - enable preemption scheduler safe | ||
582 | * @resched: the return value from ftrace_preempt_disable | ||
583 | * | ||
584 | * This is a scheduler safe way to enable preemption and not miss | ||
585 | * any preemption checks. The disabled saved the state of preemption. | ||
586 | * If resched is set, then we were either inside an atomic or | ||
587 | * are inside the scheduler (we would have already scheduled | ||
588 | * otherwise). In this case, we do not want to call normal | ||
589 | * preempt_enable, but preempt_enable_no_resched instead. | ||
590 | */ | ||
591 | static inline void ftrace_preempt_enable(int resched) | ||
592 | { | ||
593 | if (resched) | ||
594 | preempt_enable_no_resched_notrace(); | ||
595 | else | ||
596 | preempt_enable_notrace(); | ||
597 | } | ||
598 | |||
599 | #ifdef CONFIG_BRANCH_TRACER | ||
600 | extern int enable_branch_tracing(struct trace_array *tr); | ||
601 | extern void disable_branch_tracing(void); | ||
602 | static inline int trace_branch_enable(struct trace_array *tr) | ||
603 | { | ||
604 | if (trace_flags & TRACE_ITER_BRANCH) | ||
605 | return enable_branch_tracing(tr); | ||
606 | return 0; | ||
607 | } | ||
608 | static inline void trace_branch_disable(void) | ||
609 | { | ||
610 | /* due to races, always disable */ | ||
611 | disable_branch_tracing(); | ||
612 | } | ||
613 | #else | ||
614 | static inline int trace_branch_enable(struct trace_array *tr) | ||
615 | { | ||
616 | return 0; | ||
617 | } | ||
618 | static inline void trace_branch_disable(void) | ||
619 | { | ||
620 | } | ||
621 | #endif /* CONFIG_BRANCH_TRACER */ | ||
622 | |||
422 | #endif /* _LINUX_KERNEL_TRACE_H */ | 623 | #endif /* _LINUX_KERNEL_TRACE_H */ |