diff options
| -rw-r--r-- | include/linux/ftrace_event.h | 4 | ||||
| -rw-r--r-- | include/trace/ftrace.h | 9 | ||||
| -rw-r--r-- | kernel/trace/ftrace.c | 2 | ||||
| -rw-r--r-- | kernel/trace/ring_buffer.c | 42 | ||||
| -rw-r--r-- | kernel/trace/ring_buffer_benchmark.c | 18 | ||||
| -rw-r--r-- | kernel/trace/trace.c | 188 | ||||
| -rw-r--r-- | kernel/trace/trace.h | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_branch.c | 1 | ||||
| -rw-r--r-- | kernel/trace/trace_events.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_export.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_functions_graph.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_irqsoff.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_kprobe.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_nop.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_output.c | 44 | ||||
| -rw-r--r-- | kernel/trace/trace_printk.c | 4 | ||||
| -rw-r--r-- | kernel/trace/trace_sched_switch.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_sched_wakeup.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_stack.c | 4 | ||||
| -rw-r--r-- | kernel/trace/trace_stat.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_uprobe.c | 2 | ||||
| -rw-r--r-- | samples/trace_events/trace-events-sample.c | 80 | ||||
| -rw-r--r-- | samples/trace_events/trace-events-sample.h | 328 |
23 files changed, 582 insertions, 164 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index d36f68b08acc..c674ee8f7fca 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
| @@ -44,6 +44,10 @@ const char *ftrace_print_bitmask_seq(struct trace_seq *p, void *bitmask_ptr, | |||
| 44 | const char *ftrace_print_hex_seq(struct trace_seq *p, | 44 | const char *ftrace_print_hex_seq(struct trace_seq *p, |
| 45 | const unsigned char *buf, int len); | 45 | const unsigned char *buf, int len); |
| 46 | 46 | ||
| 47 | const char *ftrace_print_array_seq(struct trace_seq *p, | ||
| 48 | const void *buf, int buf_len, | ||
| 49 | size_t el_size); | ||
| 50 | |||
| 47 | struct trace_iterator; | 51 | struct trace_iterator; |
| 48 | struct trace_event; | 52 | struct trace_event; |
| 49 | 53 | ||
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 27609dfcce25..41bf65f04dd9 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h | |||
| @@ -263,6 +263,14 @@ | |||
| 263 | #undef __print_hex | 263 | #undef __print_hex |
| 264 | #define __print_hex(buf, buf_len) ftrace_print_hex_seq(p, buf, buf_len) | 264 | #define __print_hex(buf, buf_len) ftrace_print_hex_seq(p, buf, buf_len) |
| 265 | 265 | ||
| 266 | #undef __print_array | ||
| 267 | #define __print_array(array, count, el_size) \ | ||
| 268 | ({ \ | ||
| 269 | BUILD_BUG_ON(el_size != 1 && el_size != 2 && \ | ||
| 270 | el_size != 4 && el_size != 8); \ | ||
| 271 | ftrace_print_array_seq(p, array, count, el_size); \ | ||
| 272 | }) | ||
| 273 | |||
| 266 | #undef DECLARE_EVENT_CLASS | 274 | #undef DECLARE_EVENT_CLASS |
| 267 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 275 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| 268 | static notrace enum print_line_t \ | 276 | static notrace enum print_line_t \ |
| @@ -674,6 +682,7 @@ static inline void ftrace_test_probe_##call(void) \ | |||
| 674 | #undef __get_dynamic_array_len | 682 | #undef __get_dynamic_array_len |
| 675 | #undef __get_str | 683 | #undef __get_str |
| 676 | #undef __get_bitmask | 684 | #undef __get_bitmask |
| 685 | #undef __print_array | ||
| 677 | 686 | ||
| 678 | #undef TP_printk | 687 | #undef TP_printk |
| 679 | #define TP_printk(fmt, args...) "\"" fmt "\", " __stringify(args) | 688 | #define TP_printk(fmt, args...) "\"" fmt "\", " __stringify(args) |
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 224e768bdc73..45e5cb143d17 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
| @@ -5456,7 +5456,7 @@ static __init int ftrace_init_debugfs(void) | |||
| 5456 | struct dentry *d_tracer; | 5456 | struct dentry *d_tracer; |
| 5457 | 5457 | ||
| 5458 | d_tracer = tracing_init_dentry(); | 5458 | d_tracer = tracing_init_dentry(); |
| 5459 | if (!d_tracer) | 5459 | if (IS_ERR(d_tracer)) |
| 5460 | return 0; | 5460 | return 0; |
| 5461 | 5461 | ||
| 5462 | ftrace_init_dyn_debugfs(d_tracer); | 5462 | ftrace_init_dyn_debugfs(d_tracer); |
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 7a4104cb95cb..5040d44fe5a3 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
| @@ -9,7 +9,6 @@ | |||
| 9 | #include <linux/trace_seq.h> | 9 | #include <linux/trace_seq.h> |
| 10 | #include <linux/spinlock.h> | 10 | #include <linux/spinlock.h> |
| 11 | #include <linux/irq_work.h> | 11 | #include <linux/irq_work.h> |
| 12 | #include <linux/debugfs.h> | ||
| 13 | #include <linux/uaccess.h> | 12 | #include <linux/uaccess.h> |
| 14 | #include <linux/hardirq.h> | 13 | #include <linux/hardirq.h> |
| 15 | #include <linux/kthread.h> /* for self test */ | 14 | #include <linux/kthread.h> /* for self test */ |
| @@ -23,7 +22,6 @@ | |||
| 23 | #include <linux/hash.h> | 22 | #include <linux/hash.h> |
| 24 | #include <linux/list.h> | 23 | #include <linux/list.h> |
| 25 | #include <linux/cpu.h> | 24 | #include <linux/cpu.h> |
| 26 | #include <linux/fs.h> | ||
| 27 | 25 | ||
| 28 | #include <asm/local.h> | 26 | #include <asm/local.h> |
| 29 | 27 | ||
| @@ -447,7 +445,10 @@ int ring_buffer_print_page_header(struct trace_seq *s) | |||
| 447 | struct rb_irq_work { | 445 | struct rb_irq_work { |
| 448 | struct irq_work work; | 446 | struct irq_work work; |
| 449 | wait_queue_head_t waiters; | 447 | wait_queue_head_t waiters; |
| 448 | wait_queue_head_t full_waiters; | ||
| 450 | bool waiters_pending; | 449 | bool waiters_pending; |
| 450 | bool full_waiters_pending; | ||
| 451 | bool wakeup_full; | ||
| 451 | }; | 452 | }; |
| 452 | 453 | ||
| 453 | /* | 454 | /* |
| @@ -529,6 +530,10 @@ static void rb_wake_up_waiters(struct irq_work *work) | |||
| 529 | struct rb_irq_work *rbwork = container_of(work, struct rb_irq_work, work); | 530 | struct rb_irq_work *rbwork = container_of(work, struct rb_irq_work, work); |
| 530 | 531 | ||
| 531 | wake_up_all(&rbwork->waiters); | 532 | wake_up_all(&rbwork->waiters); |
| 533 | if (rbwork->wakeup_full) { | ||
| 534 | rbwork->wakeup_full = false; | ||
| 535 | wake_up_all(&rbwork->full_waiters); | ||
| 536 | } | ||
| 532 | } | 537 | } |
| 533 | 538 | ||
| 534 | /** | 539 | /** |
| @@ -553,9 +558,11 @@ int ring_buffer_wait(struct ring_buffer *buffer, int cpu, bool full) | |||
| 553 | * data in any cpu buffer, or a specific buffer, put the | 558 | * data in any cpu buffer, or a specific buffer, put the |
| 554 | * caller on the appropriate wait queue. | 559 | * caller on the appropriate wait queue. |
| 555 | */ | 560 | */ |
| 556 | if (cpu == RING_BUFFER_ALL_CPUS) | 561 | if (cpu == RING_BUFFER_ALL_CPUS) { |
| 557 | work = &buffer->irq_work; | 562 | work = &buffer->irq_work; |
| 558 | else { | 563 | /* Full only makes sense on per cpu reads */ |
| 564 | full = false; | ||
| 565 | } else { | ||
| 559 | if (!cpumask_test_cpu(cpu, buffer->cpumask)) | 566 | if (!cpumask_test_cpu(cpu, buffer->cpumask)) |
| 560 | return -ENODEV; | 567 | return -ENODEV; |
| 561 | cpu_buffer = buffer->buffers[cpu]; | 568 | cpu_buffer = buffer->buffers[cpu]; |
| @@ -564,7 +571,10 @@ int ring_buffer_wait(struct ring_buffer *buffer, int cpu, bool full) | |||
| 564 | 571 | ||
| 565 | 572 | ||
| 566 | while (true) { | 573 | while (true) { |
| 567 | prepare_to_wait(&work->waiters, &wait, TASK_INTERRUPTIBLE); | 574 | if (full) |
| 575 | prepare_to_wait(&work->full_waiters, &wait, TASK_INTERRUPTIBLE); | ||
| 576 | else | ||
| 577 | prepare_to_wait(&work->waiters, &wait, TASK_INTERRUPTIBLE); | ||
| 568 | 578 | ||
| 569 | /* | 579 | /* |
| 570 | * The events can happen in critical sections where | 580 | * The events can happen in critical sections where |
| @@ -586,7 +596,10 @@ int ring_buffer_wait(struct ring_buffer *buffer, int cpu, bool full) | |||
| 586 | * that is necessary is that the wake up happens after | 596 | * that is necessary is that the wake up happens after |
| 587 | * a task has been queued. It's OK for spurious wake ups. | 597 | * a task has been queued. It's OK for spurious wake ups. |
| 588 | */ | 598 | */ |
| 589 | work->waiters_pending = true; | 599 | if (full) |
| 600 | work->full_waiters_pending = true; | ||
| 601 | else | ||
| 602 | work->waiters_pending = true; | ||
| 590 | 603 | ||
| 591 | if (signal_pending(current)) { | 604 | if (signal_pending(current)) { |
| 592 | ret = -EINTR; | 605 | ret = -EINTR; |
| @@ -615,7 +628,10 @@ int ring_buffer_wait(struct ring_buffer *buffer, int cpu, bool full) | |||
| 615 | schedule(); | 628 | schedule(); |
| 616 | } | 629 | } |
| 617 | 630 | ||
| 618 | finish_wait(&work->waiters, &wait); | 631 | if (full) |
| 632 | finish_wait(&work->full_waiters, &wait); | ||
| 633 | else | ||
| 634 | finish_wait(&work->waiters, &wait); | ||
| 619 | |||
