diff options
Diffstat (limited to 'kernel/trace/trace.h')
| -rw-r--r-- | kernel/trace/trace.h | 315 |
1 files changed, 267 insertions, 48 deletions
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 4d3d381bfd95..cb0ce3fc36d3 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
| @@ -9,6 +9,8 @@ | |||
| 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 | #include <trace/boot.h> |
| 12 | #include <trace/kmemtrace.h> | ||
| 13 | #include <trace/power.h> | ||
| 12 | 14 | ||
| 13 | enum trace_type { | 15 | enum trace_type { |
| 14 | __TRACE_FIRST_TYPE = 0, | 16 | __TRACE_FIRST_TYPE = 0, |
| @@ -16,9 +18,9 @@ enum trace_type { | |||
| 16 | TRACE_FN, | 18 | TRACE_FN, |
| 17 | TRACE_CTX, | 19 | TRACE_CTX, |
| 18 | TRACE_WAKE, | 20 | TRACE_WAKE, |
| 19 | TRACE_CONT, | ||
| 20 | TRACE_STACK, | 21 | TRACE_STACK, |
| 21 | TRACE_PRINT, | 22 | TRACE_PRINT, |
| 23 | TRACE_BPRINT, | ||
| 22 | TRACE_SPECIAL, | 24 | TRACE_SPECIAL, |
| 23 | TRACE_MMIO_RW, | 25 | TRACE_MMIO_RW, |
| 24 | TRACE_MMIO_MAP, | 26 | TRACE_MMIO_MAP, |
| @@ -29,9 +31,14 @@ enum trace_type { | |||
| 29 | TRACE_GRAPH_ENT, | 31 | TRACE_GRAPH_ENT, |
| 30 | TRACE_USER_STACK, | 32 | TRACE_USER_STACK, |
| 31 | TRACE_HW_BRANCHES, | 33 | TRACE_HW_BRANCHES, |
| 34 | TRACE_SYSCALL_ENTER, | ||
| 35 | TRACE_SYSCALL_EXIT, | ||
| 36 | TRACE_KMEM_ALLOC, | ||
| 37 | TRACE_KMEM_FREE, | ||
| 32 | TRACE_POWER, | 38 | TRACE_POWER, |
| 39 | TRACE_BLK, | ||
| 33 | 40 | ||
| 34 | __TRACE_LAST_TYPE | 41 | __TRACE_LAST_TYPE, |
| 35 | }; | 42 | }; |
| 36 | 43 | ||
| 37 | /* | 44 | /* |
| @@ -42,7 +49,6 @@ enum trace_type { | |||
| 42 | */ | 49 | */ |
| 43 | struct trace_entry { | 50 | struct trace_entry { |
| 44 | unsigned char type; | 51 | unsigned char type; |
| 45 | unsigned char cpu; | ||
| 46 | unsigned char flags; | 52 | unsigned char flags; |
| 47 | unsigned char preempt_count; | 53 | unsigned char preempt_count; |
| 48 | int pid; | 54 | int pid; |
| @@ -60,13 +66,13 @@ struct ftrace_entry { | |||
| 60 | 66 | ||
| 61 | /* Function call entry */ | 67 | /* Function call entry */ |
| 62 | struct ftrace_graph_ent_entry { | 68 | struct ftrace_graph_ent_entry { |
| 63 | struct trace_entry ent; | 69 | struct trace_entry ent; |
| 64 | struct ftrace_graph_ent graph_ent; | 70 | struct ftrace_graph_ent graph_ent; |
| 65 | }; | 71 | }; |
| 66 | 72 | ||
| 67 | /* Function return entry */ | 73 | /* Function return entry */ |
| 68 | struct ftrace_graph_ret_entry { | 74 | struct ftrace_graph_ret_entry { |
| 69 | struct trace_entry ent; | 75 | struct trace_entry ent; |
| 70 | struct ftrace_graph_ret ret; | 76 | struct ftrace_graph_ret ret; |
| 71 | }; | 77 | }; |
| 72 | extern struct tracer boot_tracer; | 78 | extern struct tracer boot_tracer; |
| @@ -112,12 +118,18 @@ struct userstack_entry { | |||
| 112 | }; | 118 | }; |
| 113 | 119 | ||
| 114 | /* | 120 | /* |
| 115 | * ftrace_printk entry: | 121 | * trace_printk entry: |
| 116 | */ | 122 | */ |
| 123 | struct bprint_entry { | ||
| 124 | struct trace_entry ent; | ||
| 125 | unsigned long ip; | ||
| 126 | const char *fmt; | ||
| 127 | u32 buf[]; | ||
| 128 | }; | ||
| 129 | |||
| 117 | struct print_entry { | 130 | struct print_entry { |
| 118 | struct trace_entry ent; | 131 | struct trace_entry ent; |
| 119 | unsigned long ip; | 132 | unsigned long ip; |
| 120 | int depth; | ||
| 121 | char buf[]; | 133 | char buf[]; |
| 122 | }; | 134 | }; |
| 123 | 135 | ||
| @@ -170,15 +182,45 @@ struct trace_power { | |||
| 170 | struct power_trace state_data; | 182 | struct power_trace state_data; |
| 171 | }; | 183 | }; |
| 172 | 184 | ||
| 185 | struct kmemtrace_alloc_entry { | ||
| 186 | struct trace_entry ent; | ||
| 187 | enum kmemtrace_type_id type_id; | ||
| 188 | unsigned long call_site; | ||
| 189 | const void *ptr; | ||
| 190 | size_t bytes_req; | ||
| 191 | size_t bytes_alloc; | ||
| 192 | gfp_t gfp_flags; | ||
| 193 | int node; | ||
| 194 | }; | ||
| 195 | |||
| 196 | struct kmemtrace_free_entry { | ||
| 197 | struct trace_entry ent; | ||
| 198 | enum kmemtrace_type_id type_id; | ||
| 199 | unsigned long call_site; | ||
| 200 | const void *ptr; | ||
| 201 | }; | ||
| 202 | |||
| 203 | struct syscall_trace_enter { | ||
| 204 | struct trace_entry ent; | ||
| 205 | int nr; | ||
| 206 | unsigned long args[]; | ||
| 207 | }; | ||
| 208 | |||
| 209 | struct syscall_trace_exit { | ||
| 210 | struct trace_entry ent; | ||
| 211 | int nr; | ||
| 212 | unsigned long ret; | ||
| 213 | }; | ||
| 214 | |||
| 215 | |||
| 173 | /* | 216 | /* |
| 174 | * trace_flag_type is an enumeration that holds different | 217 | * trace_flag_type is an enumeration that holds different |
| 175 | * states when a trace occurs. These are: | 218 | * states when a trace occurs. These are: |
| 176 | * IRQS_OFF - interrupts were disabled | 219 | * IRQS_OFF - interrupts were disabled |
| 177 | * IRQS_NOSUPPORT - arch does not support irqs_disabled_flags | 220 | * IRQS_NOSUPPORT - arch does not support irqs_disabled_flags |
| 178 | * NEED_RESCED - reschedule is requested | 221 | * NEED_RESCED - reschedule is requested |
| 179 | * HARDIRQ - inside an interrupt handler | 222 | * HARDIRQ - inside an interrupt handler |
| 180 | * SOFTIRQ - inside a softirq handler | 223 | * SOFTIRQ - inside a softirq handler |
| 181 | * CONT - multiple entries hold the trace item | ||
| 182 | */ | 224 | */ |
| 183 | enum trace_flag_type { | 225 | enum trace_flag_type { |
| 184 | TRACE_FLAG_IRQS_OFF = 0x01, | 226 | TRACE_FLAG_IRQS_OFF = 0x01, |
| @@ -186,7 +228,6 @@ enum trace_flag_type { | |||
| 186 | TRACE_FLAG_NEED_RESCHED = 0x04, | 228 | TRACE_FLAG_NEED_RESCHED = 0x04, |
| 187 | TRACE_FLAG_HARDIRQ = 0x08, | 229 | TRACE_FLAG_HARDIRQ = 0x08, |
| 188 | TRACE_FLAG_SOFTIRQ = 0x10, | 230 | TRACE_FLAG_SOFTIRQ = 0x10, |
| 189 | TRACE_FLAG_CONT = 0x20, | ||
| 190 | }; | 231 | }; |
| 191 | 232 | ||
| 192 | #define TRACE_BUF_SIZE 1024 | 233 | #define TRACE_BUF_SIZE 1024 |
| @@ -198,6 +239,7 @@ enum trace_flag_type { | |||
| 198 | */ | 239 | */ |
| 199 | struct trace_array_cpu { | 240 | struct trace_array_cpu { |
| 200 | atomic_t disabled; | 241 | atomic_t disabled; |
| 242 | void *buffer_page; /* ring buffer spare */ | ||
| 201 | 243 | ||
| 202 | /* these fields get copied into max-trace: */ | 244 | /* these fields get copied into max-trace: */ |
| 203 | unsigned long trace_idx; | 245 | unsigned long trace_idx; |
| @@ -262,10 +304,10 @@ extern void __ftrace_bad_type(void); | |||
| 262 | do { \ | 304 | do { \ |
| 263 | IF_ASSIGN(var, ent, struct ftrace_entry, TRACE_FN); \ | 305 | IF_ASSIGN(var, ent, struct ftrace_entry, TRACE_FN); \ |
| 264 | IF_ASSIGN(var, ent, struct ctx_switch_entry, 0); \ | 306 | IF_ASSIGN(var, ent, struct ctx_switch_entry, 0); \ |
| 265 | IF_ASSIGN(var, ent, struct trace_field_cont, TRACE_CONT); \ | ||
| 266 | IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK); \ | 307 | IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK); \ |
| 267 | IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\ | 308 | IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\ |
| 268 | IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT); \ | 309 | IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT); \ |
| 310 | IF_ASSIGN(var, ent, struct bprint_entry, TRACE_BPRINT); \ | ||
| 269 | IF_ASSIGN(var, ent, struct special_entry, 0); \ | 311 | IF_ASSIGN(var, ent, struct special_entry, 0); \ |
| 270 | IF_ASSIGN(var, ent, struct trace_mmiotrace_rw, \ | 312 | IF_ASSIGN(var, ent, struct trace_mmiotrace_rw, \ |
| 271 | TRACE_MMIO_RW); \ | 313 | TRACE_MMIO_RW); \ |
| @@ -279,7 +321,15 @@ extern void __ftrace_bad_type(void); | |||
| 279 | IF_ASSIGN(var, ent, struct ftrace_graph_ret_entry, \ | 321 | IF_ASSIGN(var, ent, struct ftrace_graph_ret_entry, \ |
| 280 | TRACE_GRAPH_RET); \ | 322 | TRACE_GRAPH_RET); \ |
| 281 | IF_ASSIGN(var, ent, struct hw_branch_entry, TRACE_HW_BRANCHES);\ | 323 | IF_ASSIGN(var, ent, struct hw_branch_entry, TRACE_HW_BRANCHES);\ |
| 282 | IF_ASSIGN(var, ent, struct trace_power, TRACE_POWER); \ | 324 | IF_ASSIGN(var, ent, struct trace_power, TRACE_POWER); \ |
| 325 | IF_ASSIGN(var, ent, struct kmemtrace_alloc_entry, \ | ||
| 326 | TRACE_KMEM_ALLOC); \ | ||
| 327 | IF_ASSIGN(var, ent, struct kmemtrace_free_entry, \ | ||
| 328 | TRACE_KMEM_FREE); \ | ||
| 329 | IF_ASSIGN(var, ent, struct syscall_trace_enter, \ | ||
| 330 | TRACE_SYSCALL_ENTER); \ | ||
| 331 | IF_ASSIGN(var, ent, struct syscall_trace_exit, \ | ||
| 332 | TRACE_SYSCALL_EXIT); \ | ||
| 283 | __ftrace_bad_type(); \ | 333 | __ftrace_bad_type(); \ |
| 284 | } while (0) | 334 | } while (0) |
| 285 | 335 | ||
| @@ -287,7 +337,8 @@ extern void __ftrace_bad_type(void); | |||
| 287 | enum print_line_t { | 337 | enum print_line_t { |
| 288 | TRACE_TYPE_PARTIAL_LINE = 0, /* Retry after flushing the seq */ | 338 | TRACE_TYPE_PARTIAL_LINE = 0, /* Retry after flushing the seq */ |
| 289 | TRACE_TYPE_HANDLED = 1, | 339 | TRACE_TYPE_HANDLED = 1, |
| 290 | TRACE_TYPE_UNHANDLED = 2 /* Relay to other output functions */ | 340 | TRACE_TYPE_UNHANDLED = 2, /* Relay to other output functions */ |
| 341 | TRACE_TYPE_NO_CONSUME = 3 /* Handled but ask to not consume */ | ||
| 291 | }; | 342 | }; |
| 292 | 343 | ||
| 293 | 344 | ||
| @@ -297,8 +348,8 @@ enum print_line_t { | |||
| 297 | * flags value in struct tracer_flags. | 348 | * flags value in struct tracer_flags. |
| 298 | */ | 349 | */ |
| 299 | struct tracer_opt { | 350 | struct tracer_opt { |
| 300 | const char *name; /* Will appear on the trace_options file */ | 351 | const char *name; /* Will appear on the trace_options file */ |
| 301 | u32 bit; /* Mask assigned in val field in tracer_flags */ | 352 | u32 bit; /* Mask assigned in val field in tracer_flags */ |
| 302 | }; | 353 | }; |
| 303 | 354 | ||
| 304 | /* | 355 | /* |
| @@ -307,28 +358,51 @@ struct tracer_opt { | |||
| 307 | */ | 358 | */ |
| 308 | struct tracer_flags { | 359 | struct tracer_flags { |
| 309 | u32 val; | 360 | u32 val; |
| 310 | struct tracer_opt *opts; | 361 | struct tracer_opt *opts; |
| 311 | }; | 362 | }; |
| 312 | 363 | ||
| 313 | /* Makes more easy to define a tracer opt */ | 364 | /* Makes more easy to define a tracer opt */ |
| 314 | #define TRACER_OPT(s, b) .name = #s, .bit = b | 365 | #define TRACER_OPT(s, b) .name = #s, .bit = b |
| 315 | 366 | ||
| 316 | /* | 367 | |
| 317 | * A specific tracer, represented by methods that operate on a trace array: | 368 | /** |
| 369 | * struct tracer - a specific tracer and its callbacks to interact with debugfs | ||
| 370 | * @name: the name chosen to select it on the available_tracers file | ||
| 371 | * @init: called when one switches to this tracer (echo name > current_tracer) | ||
| 372 | * @reset: called when one switches to another tracer | ||
| 373 | * @start: called when tracing is unpaused (echo 1 > tracing_enabled) | ||
| 374 | * @stop: called when tracing is paused (echo 0 > tracing_enabled) | ||
| 375 | * @open: called when the trace file is opened | ||
| 376 | * @pipe_open: called when the trace_pipe file is opened | ||
| 377 | * @wait_pipe: override how the user waits for traces on trace_pipe | ||
| 378 | * @close: called when the trace file is released | ||
| 379 | * @read: override the default read callback on trace_pipe | ||
| 380 | * @splice_read: override the default splice_read callback on trace_pipe | ||
| 381 | * @selftest: selftest to run on boot (see trace_selftest.c) | ||
| 382 | * @print_headers: override the first lines that describe your columns | ||
| 383 | * @print_line: callback that prints a trace | ||
| 384 | * @set_flag: signals one of your private flags changed (trace_options file) | ||
| 385 | * @flags: your private flags | ||
| 318 | */ | 386 | */ |
| 319 | struct tracer { | 387 | struct tracer { |
| 320 | const char *name; | 388 | const char *name; |
| 321 | /* Your tracer should raise a warning if init fails */ | ||
| 322 | int (*init)(struct trace_array *tr); | 389 | int (*init)(struct trace_array *tr); |
| 323 | void (*reset)(struct trace_array *tr); | 390 | void (*reset)(struct trace_array *tr); |
| 324 | void (*start)(struct trace_array *tr); | 391 | void (*start)(struct trace_array *tr); |
| 325 | void (*stop)(struct trace_array *tr); | 392 | void (*stop)(struct trace_array *tr); |
| 326 | void (*open)(struct trace_iterator *iter); | 393 | void (*open)(struct trace_iterator *iter); |
| 327 | void (*pipe_open)(struct trace_iterator *iter); | 394 | void (*pipe_open)(struct trace_iterator *iter); |
| 395 | void (*wait_pipe)(struct trace_iterator *iter); | ||
| 328 | void (*close)(struct trace_iterator *iter); | 396 | void (*close)(struct trace_iterator *iter); |
| 329 | ssize_t (*read)(struct trace_iterator *iter, | 397 | ssize_t (*read)(struct trace_iterator *iter, |
| 330 | struct file *filp, char __user *ubuf, | 398 | struct file *filp, char __user *ubuf, |
| 331 | size_t cnt, loff_t *ppos); | 399 | size_t cnt, loff_t *ppos); |
| 400 | ssize_t (*splice_read)(struct trace_iterator *iter, | ||
| 401 | struct file *filp, | ||
| 402 | loff_t *ppos, | ||
| 403 | struct pipe_inode_info *pipe, | ||
| 404 | size_t len, | ||
| 405 | unsigned int flags); | ||
| 332 | #ifdef CONFIG_FTRACE_STARTUP_TEST | 406 | #ifdef CONFIG_FTRACE_STARTUP_TEST |
| 333 | int (*selftest)(struct tracer *trace, | 407 | int (*selftest)(struct tracer *trace, |
| 334 | struct trace_array *tr); | 408 | struct trace_array *tr); |
| @@ -339,7 +413,8 @@ struct tracer { | |||
| 339 | int (*set_flag)(u32 old_flags, u32 bit, int set); | 413 | int (*set_flag)(u32 old_flags, u32 bit, int set); |
| 340 | struct tracer *next; | 414 | struct tracer *next; |
| 341 | int print_max; | 415 | int print_max; |
| 342 | struct tracer_flags *flags; | 416 | struct tracer_flags *flags; |
| 417 | struct tracer_stat *stats; | ||
| 343 | }; | 418 | }; |
| 344 | 419 | ||
| 345 | struct trace_seq { | 420 | struct trace_seq { |
| @@ -348,6 +423,16 @@ struct trace_seq { | |||
| 348 | unsigned int readpos; | 423 | unsigned int readpos; |
| 349 | }; | 424 | }; |
| 350 | 425 | ||
| 426 | static inline void | ||
| 427 | trace_seq_init(struct trace_seq *s) | ||
| 428 | { | ||
| 429 | s->len = 0; | ||
| 430 | s->readpos = 0; | ||
| 431 | } | ||
| 432 | |||
| 433 | |||
| 434 | #define TRACE_PIPE_ALL_CPU -1 | ||
| 435 | |||
| 351 | /* | 436 | /* |
| 352 | * Trace iterator - used by printout routines who present trace | 437 | * Trace iterator - used by printout routines who present trace |
| 353 | * results to users and which routines might sleep, etc: | 438 | * results to users and which routines might sleep, etc: |
| @@ -356,6 +441,8 @@ struct trace_iterator { | |||
| 356 | struct trace_array *tr; | 441 | struct trace_array *tr; |
| 357 | struct tracer *trace; | 442 | struct tracer *trace; |
| 358 | void *private; | 443 | void *private; |
| 444 | int cpu_file; | ||
| 445 | struct mutex mutex; | ||
| 359 | struct ring_buffer_iter *buffer_iter[NR_CPUS]; | 446 | struct ring_buffer_iter *buffer_iter[NR_CPUS]; |
| 360 | 447 | ||
| 361 | /* The below is zeroed out in pipe_read */ | 448 | /* The below is zeroed out in pipe_read */ |
| @@ -371,6 +458,7 @@ struct trace_iterator { | |||
| 371 | cpumask_var_t started; | 458 | cpumask_var_t started; |
| 372 | }; | 459 | }; |
| 373 | 460 | ||
| 461 | int tracer_init(struct tracer *t, struct trace_array *tr); | ||
| 374 | int tracing_is_enabled(void); | 462 | int tracing_is_enabled(void); |
| 375 | void trace_wake_up(void); | 463 | void trace_wake_up(void); |
| 376 | void tracing_reset(struct trace_array *tr, int cpu); | 464 | void tracing_reset(struct trace_array *tr, int cpu); |
| @@ -379,26 +467,50 @@ int tracing_open_generic(struct inode *inode, struct file *filp); | |||
| 379 | struct dentry *tracing_init_dentry(void); | 467 | struct dentry *tracing_init_dentry(void); |
| 380 | void init_tracer_sysprof_debugfs(struct dentry *d_tracer); | 468 | void init_tracer_sysprof_debugfs(struct dentry *d_tracer); |
| 381 | 469 | ||
| 470 | struct ring_buffer_event; | ||
| 471 | |||
| 472 | struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr, | ||
| 473 | unsigned char type, | ||
| 474 | unsigned long len, | ||
| 475 | unsigned long flags, | ||
| 476 | int pc); | ||
| 477 | void trace_buffer_unlock_commit(struct trace_array *tr, | ||
| 478 | struct ring_buffer_event *event, | ||
| 479 | unsigned long flags, int pc); | ||
| 480 | |||
| 481 | struct ring_buffer_event * | ||
| 482 | trace_current_buffer_lock_reserve(unsigned char type, unsigned long len, | ||
| 483 | unsigned long flags, int pc); | ||
| 484 | void trace_current_buffer_unlock_commit(struct ring_buffer_event *event, | ||
| 485 | unsigned long flags, int pc); | ||
| 486 | void trace_nowake_buffer_unlock_commit(struct ring_buffer_event *event, | ||
| 487 | unsigned long flags, int pc); | ||
| 488 | |||
| 382 | struct trace_entry *tracing_get_trace_entry(struct trace_array *tr, | 489 | struct trace_entry *tracing_get_trace_entry(struct trace_array *tr, |
| 383 | struct trace_array_cpu *data); | 490 | struct trace_array_cpu *data); |
| 491 | |||
| 492 | struct trace_entry *trace_find_next_entry(struct trace_iterator *iter, | ||
| 493 | int *ent_cpu, u64 *ent_ts); | ||
| 494 | |||
| 384 | void tracing_generic_entry_update(struct trace_entry *entry, | 495 | void tracing_generic_entry_update(struct trace_entry *entry, |
| 385 | unsigned long flags, | 496 | unsigned long flags, |
| 386 | int pc); | 497 | int pc); |
| 387 | 498 | ||
| 499 | void default_wait_pipe(struct trace_iterator *iter); | ||
| 500 | void poll_wait_pipe(struct trace_iterator *iter); | ||
| 501 | |||
| 388 | void ftrace(struct trace_array *tr, | 502 | void ftrace(struct trace_array *tr, |
| 389 | struct trace_array_cpu *data, | 503 | struct trace_array_cpu *data, |
| 390 | unsigned long ip, | 504 | unsigned long ip, |
| 391 | unsigned long parent_ip, | 505 | unsigned long parent_ip, |
| 392 | unsigned long flags, int pc); | 506 | unsigned long flags, int pc); |
| 393 | void tracing_sched_switch_trace(struct trace_array *tr, | 507 | void tracing_sched_switch_trace(struct trace_array *tr, |
| 394 | struct trace_array_cpu *data, | ||
| 395 | struct task_struct *prev, | 508 | struct task_struct *prev, |
| 396 | struct task_struct *next, | 509 | struct task_struct *next, |
| 397 | unsigned long flags, int pc); | 510 | unsigned long flags, int pc); |
| 398 | void tracing_record_cmdline(struct task_struct *tsk); | 511 | void tracing_record_cmdline(struct task_struct *tsk); |
| 399 | 512 | ||
| 400 | void tracing_sched_wakeup_trace(struct trace_array *tr, | 513 | void tracing_sched_wakeup_trace(struct trace_array *tr, |
| 401 | struct trace_array_cpu *data, | ||
| 402 | struct task_struct *wakee, | 514 | struct task_struct *wakee, |
| 403 | struct task_struct *cur, | 515 | struct task_struct *cur, |
| 404 | unsigned long flags, int pc); | 516 | unsigned long flags, int pc); |
| @@ -408,14 +520,12 @@ void trace_special(struct trace_array *tr, | |||
| 408 | unsigned long arg2, | 520 | unsigned long arg2, |
| 409 | unsigned long arg3, int pc); | 521 | unsigned long arg3, int pc); |
| 410 | void trace_function(struct trace_array *tr, | 522 | void trace_function(struct trace_array *tr, |
| 411 | struct trace_array_cpu *data, | ||
| 412 | unsigned long ip, | 523 | unsigned long ip, |
| 413 | unsigned long parent_ip, | 524 | unsigned long parent_ip, |
| 414 | unsigned long flags, int pc); | 525 | unsigned long flags, int pc); |
| 415 | 526 | ||
| 416 | void trace_graph_return(struct ftrace_graph_ret *trace); | 527 | void trace_graph_return(struct ftrace_graph_ret *trace); |
| 417 | int trace_graph_entry(struct ftrace_graph_ent *trace); | 528 | int trace_graph_entry(struct ftrace_graph_ent *trace); |
| 418 | void trace_hw_branch(struct trace_array *tr, u64 from, u64 to); | ||
| 419 | 529 | ||
| 420 | void tracing_start_cmdline_record(void); | 530 | void tracing_start_cmdline_record(void); |
| 421 | void tracing_stop_cmdline_record(void); | 531 | void tracing_stop_cmdline_record(void); |
| @@ -434,15 +544,11 @@ void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu); | |||
| 434 | void update_max_tr_single(struct trace_array *tr, | 544 | void update_max_tr_single(struct trace_array *tr, |
| 435 | struct task_struct *tsk, int cpu); | 545 | struct task_struct *tsk, int cpu); |
| 436 | 546 | ||
| 437 | extern cycle_t ftrace_now(int cpu); | 547 | void __trace_stack(struct trace_array *tr, |
| 548 | unsigned long flags, | ||
| 549 | int skip, int pc); | ||
| 438 | 550 | ||
| 439 | #ifdef CONFIG_FUNCTION_TRACER | 551 | extern cycle_t ftrace_now(int cpu); |
| 440 | void tracing_start_function_trace(void); | ||
| 441 | void tracing_stop_function_trace(void); | ||
| 442 | #else | ||
| 443 | # define tracing_start_function_trace() do { } while (0) | ||
| 444 | # define tracing_stop_function_trace() do { } while (0) | ||
| 445 | #endif | ||
| 446 | 552 | ||
| 447 | #ifdef CONFIG_CONTEXT_SWITCH_TRACER | 553 | #ifdef CONFIG_CONTEXT_SWITCH_TRACER |
| 448 | typedef void | 554 | typedef void |
| @@ -456,10 +562,10 @@ struct tracer_switch_ops { | |||
| 456 | void *private; | 562 | void *private; |
| 457 | struct tracer_switch_ops *next; | 563 | struct tracer_switch_ops *next; |
| 458 | }; | 564 | }; |
| 459 | |||
| 460 | char *trace_find_cmdline(int pid); | ||
| 461 | #endif /* CONFIG_CONTEXT_SWITCH_TRACER */ | 565 | #endif /* CONFIG_CONTEXT_SWITCH_TRACER */ |
| 462 | 566 | ||
| 567 | extern void trace_find_cmdline(int pid, char comm[]); | ||
| 568 | |||
| 463 | #ifdef CONFIG_DYNAMIC_FTRACE | 569 | #ifdef CONFIG_DYNAMIC_FTRACE |
| 464 | extern unsigned long ftrace_update_tot_cnt; | 570 | extern unsigned long ftrace_update_tot_cnt; |
| 465 | #define DYN_FTRACE_TEST_NAME trace_selftest_dynamic_test_func | 571 | #define DYN_FTRACE_TEST_NAME trace_selftest_dynamic_test_func |
| @@ -469,6 +575,8 @@ extern int DYN_FTRACE_TEST_NAME(void); | |||
| 469 | #ifdef CONFIG_FTRACE_STARTUP_TEST | 575 | #ifdef CONFIG_FTRACE_STARTUP_TEST |
| 470 | extern int trace_selftest_startup_function(struct tracer *trace, | 576 | extern int trace_selftest_startup_function(struct tracer *trace, |
| 471 | struct trace_array *tr); | 577 | struct trace_array *tr); |
| 578 | extern int trace_selftest_startup_function_graph(struct tracer *trace, | ||
| 579 | struct trace_array *tr); | ||
| 472 | extern int trace_selftest_startup_irqsoff(struct tracer *trace, | 580 | extern int trace_selftest_startup_irqsoff(struct tracer *trace, |
| 473 | struct trace_array *tr); | 581 | struct trace_array *tr); |
| 474 | extern int trace_selftest_startup_preemptoff(struct tracer *trace, | 582 | extern int trace_selftest_startup_preemptoff(struct tracer *trace, |
| @@ -488,18 +596,11 @@ extern int trace_selftest_startup_branch(struct tracer *trace, | |||
| 488 | #endif /* CONFIG_FTRACE_STARTUP_TEST */ | 596 | #endif /* CONFIG_FTRACE_STARTUP_TEST */ |
| 489 | 597 | ||
| 490 | extern void *head_page(struct trace_array_cpu *data); | 598 | extern void *head_page(struct trace_array_cpu *data); |
| 491 | extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...); | ||
| 492 | extern void trace_seq_print_cont(struct trace_seq *s, | ||
| 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); | ||
| 498 | extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, | ||
| 499 | size_t cnt); | ||
| 500 | extern long ns2usecs(cycle_t nsec); | 599 | extern long ns2usecs(cycle_t nsec); |
| 501 | extern int | 600 | extern int |
| 502 | trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args); | 601 | trace_vbprintk(unsigned long ip, const char *fmt, va_list args); |
| 602 | extern int | ||
| 603 | trace_vprintk(unsigned long ip, const char *fmt, va_list args); | ||
| 503 | 604 | ||
| 504 | extern unsigned long trace_flags; | 605 | extern unsigned long trace_flags; |
| 505 | 606 | ||
| @@ -580,7 +681,11 @@ enum trace_iterator_flags { | |||
| 580 | TRACE_ITER_ANNOTATE = 0x2000, | 681 | TRACE_ITER_ANNOTATE = 0x2000, |
| 581 | TRACE_ITER_USERSTACKTRACE = 0x4000, | 682 | TRACE_ITER_USERSTACKTRACE = 0x4000, |
| 582 | TRACE_ITER_SYM_USEROBJ = 0x8000, | 683 | TRACE_ITER_SYM_USEROBJ = 0x8000, |
| 583 | TRACE_ITER_PRINTK_MSGONLY = 0x10000 | 684 | TRACE_ITER_PRINTK_MSGONLY = 0x10000, |
| 685 | TRACE_ITER_CONTEXT_INFO = 0x20000, /* Print pid/cpu/time */ | ||
| 686 | TRACE_ITER_LATENCY_FMT = 0x40000, | ||
| 687 | TRACE_ITER_GLOBAL_CLK = 0x80000, | ||
| 688 | TRACE_ITER_SLEEP_TIME = 0x100000, | ||
| 584 | }; | 689 | }; |
| 585 | 690 | ||
| 586 | /* | 691 | /* |
| @@ -601,12 +706,12 @@ extern struct tracer nop_trace; | |||
| 601 | * preempt_enable (after a disable), a schedule might take place | 706 | * preempt_enable (after a disable), a schedule might take place |
| 602 | * causing an infinite recursion. | 707 | * causing an infinite recursion. |
| 603 | * | 708 | * |
| 604 | * To prevent this, we read the need_recshed flag before | 709 | * To prevent this, we read the need_resched flag before |
| 605 | * disabling preemption. When we want to enable preemption we | 710 | * disabling preemption. When we want to enable preemption we |
| 606 | * check the flag, if it is set, then we call preempt_enable_no_resched. | 711 | * check the flag, if it is set, then we call preempt_enable_no_resched. |
| 607 | * Otherwise, we call preempt_enable. | 712 | * Otherwise, we call preempt_enable. |
| 608 | * | 713 | * |
| 609 | * The rational for doing the above is that if need resched is set | 714 | * The rational for doing the above is that if need_resched is set |
| 610 | * and we have yet to reschedule, we are either in an atomic location | 715 | * and we have yet to reschedule, we are either in an atomic location |
| 611 | * (where we do not need to check for scheduling) or we are inside | 716 | * (where we do not need to check for scheduling) or we are inside |
| 612 | * the scheduler and do not want to resched. | 717 | * the scheduler and do not want to resched. |
| @@ -627,7 +732,7 @@ static inline int ftrace_preempt_disable(void) | |||
| 627 | * | 732 | * |
| 628 | * This is a scheduler safe way to enable preemption and not miss | 733 | * This is a scheduler safe way to enable preemption and not miss |
| 629 | * any preemption checks. The disabled saved the state of preemption. | 734 | * any preemption checks. The disabled saved the state of preemption. |
| 630 | * If resched is set, then we were either inside an atomic or | 735 | * If resched is set, then we are either inside an atomic or |
| 631 | * are inside the scheduler (we would have already scheduled | 736 | * are inside the scheduler (we would have already scheduled |
| 632 | * otherwise). In this case, we do not want to call normal | 737 | * otherwise). In this case, we do not want to call normal |
| 633 | * preempt_enable, but preempt_enable_no_resched instead. | 738 | * preempt_enable, but preempt_enable_no_resched instead. |
| @@ -664,4 +769,118 @@ static inline void trace_branch_disable(void) | |||
| 664 | } | 769 | } |
| 665 | #endif /* CONFIG_BRANCH_TRACER */ | 770 | #endif /* CONFIG_BRANCH_TRACER */ |
| 666 | 771 | ||
| 772 | /* set ring buffers to default size if not already done so */ | ||
| 773 | int tracing_update_buffers(void); | ||
| 774 | |||
| 775 | /* trace event type bit fields, not numeric */ | ||
| 776 | enum { | ||
| 777 | TRACE_EVENT_TYPE_PRINTF = 1, | ||
| 778 | TRACE_EVENT_TYPE_RAW = 2, | ||
| 779 | }; | ||
| 780 | |||
| 781 | struct ftrace_event_field { | ||
| 782 | struct list_head link; | ||
| 783 | char *name; | ||
| 784 | char *type; | ||
| 785 | int offset; | ||
| 786 | int size; | ||
| 787 | }; | ||
| 788 | |||
| 789 | struct ftrace_event_call { | ||
| 790 | char *name; | ||
| 791 | char *system; | ||
| 792 | struct dentry *dir; | ||
| 793 | int enabled; | ||
| 794 | int (*regfunc)(void); | ||
| 795 | void (*unregfunc)(void); | ||
| 796 | int id; | ||
| 797 | int (*raw_init)(void); | ||
| 798 | int (*show_format)(struct trace_seq *s); | ||
| 799 | int (*define_fields)(void); | ||
| 800 | struct list_head fields; | ||
| 801 | struct filter_pred **preds; | ||
| 802 | |||
| 803 | #ifdef CONFIG_EVENT_PROFILE | ||
| 804 | atomic_t profile_count; | ||
| 805 | int (*profile_enable)(struct ftrace_event_call *); | ||
| 806 | void (*profile_disable)(struct ftrace_event_call *); | ||
| 807 | #endif | ||
| 808 | }; | ||
| 809 | |||
| 810 | struct event_subsystem { | ||
| 811 | struct list_head list; | ||
| 812 | const char *name; | ||
| 813 | struct dentry *entry; | ||
| 814 | struct filter_pred **preds; | ||
| 815 | }; | ||
| 816 | |||
| 817 | #define events_for_each(event) \ | ||
| 818 | for (event = __start_ftrace_events; \ | ||
| 819 | (unsigned long)event < (unsigned long)__stop_ftrace_events; \ | ||
| 820 | event++) | ||
| 821 | |||
| 822 | #define MAX_FILTER_PRED 8 | ||
| 823 | |||
| 824 | struct filter_pred; | ||
| 825 | |||
| 826 | typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event); | ||
| 827 | |||
| 828 | struct filter_pred { | ||
| 829 | filter_pred_fn_t fn; | ||
| 830 | u64 val; | ||
| 831 | char *str_val; | ||
| 832 | int str_len; | ||
| 833 | char *field_name; | ||
| 834 | int offset; | ||
| 835 | int not; | ||
| 836 | int or; | ||
| 837 | int compound; | ||
| 838 | int clear; | ||
| 839 | }; | ||
| 840 | |||
| 841 | int trace_define_field(struct ftrace_event_call *call, char *type, | ||
| 842 | char *name, int offset, int size); | ||
| 843 | extern void filter_free_pred(struct filter_pred *pred); | ||
| 844 | extern void filter_print_preds(struct filter_pred **preds, | ||
| 845 | struct trace_seq *s); | ||
| 846 | extern int filter_parse(char **pbuf, struct filter_pred *pred); | ||
| 847 | extern int filter_add_pred(struct ftrace_event_call *call, | ||
| 848 | struct filter_pred *pred); | ||
| 849 | extern void filter_free_preds(struct ftrace_event_call *call); | ||
| 850 | extern int filter_match_preds(struct ftrace_event_call *call, void *rec); | ||
| 851 | extern void filter_free_subsystem_preds(struct event_subsystem *system); | ||
| 852 | extern int filter_add_subsystem_pred(struct event_subsystem *system, | ||
| 853 | struct filter_pred *pred); | ||
| 854 | |||
| 855 | void event_trace_printk(unsigned long ip, const char *fmt, ...); | ||
| 856 | extern struct ftrace_event_call __start_ftrace_events[]; | ||
| 857 | extern struct ftrace_event_call __stop_ftrace_events[]; | ||
| 858 | |||
| 859 | #define for_each_event(event) \ | ||
| 860 | for (event = __start_ftrace_events; \ | ||
| 861 | (unsigned long)event < (unsigned long)__stop_ftrace_events; \ | ||
| 862 | event++) | ||
| 863 | |||
| 864 | extern const char *__start___trace_bprintk_fmt[]; | ||
| 865 | extern const char *__stop___trace_bprintk_fmt[]; | ||
| 866 | |||
| 867 | /* | ||
| 868 | * The double __builtin_constant_p is because gcc will give us an error | ||
| 869 | * if we try to allocate the static variable to fmt if it is not a | ||
| 870 | * constant. Even with the outer if statement optimizing out. | ||
| 871 | */ | ||
| 872 | #define event_trace_printk(ip, fmt, args...) \ | ||
| 873 | do { \ | ||
| 874 | __trace_printk_check_format(fmt, ##args); \ | ||
| 875 | tracing_record_cmdline(current); \ | ||
| 876 | if (__builtin_constant_p(fmt)) { \ | ||
| 877 | static const char *trace_printk_fmt \ | ||
| 878 | __attribute__((section("__trace_printk_fmt"))) = \ | ||
| 879 | __builtin_constant_p(fmt) ? fmt : NULL; \ | ||
| 880 | \ | ||
| 881 | __trace_bprintk(ip, trace_printk_fmt, ##args); \ | ||
| 882 | } else \ | ||
| 883 | __trace_printk(ip, fmt, ##args); \ | ||
| 884 | } while (0) | ||
| 885 | |||
| 667 | #endif /* _LINUX_KERNEL_TRACE_H */ | 886 | #endif /* _LINUX_KERNEL_TRACE_H */ |
