diff options
Diffstat (limited to 'kernel/trace')
-rw-r--r-- | kernel/trace/ftrace.c | 4 | ||||
-rw-r--r-- | kernel/trace/ring_buffer.c | 4 | ||||
-rw-r--r-- | kernel/trace/trace.c | 22 | ||||
-rw-r--r-- | kernel/trace/trace_clock.c | 9 | ||||
-rw-r--r-- | kernel/trace/trace_events.c | 1 | ||||
-rw-r--r-- | kernel/trace/trace_uprobe.c | 46 |
6 files changed, 52 insertions, 34 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 5b372e3ed675..ac9d1dad630b 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -265,12 +265,12 @@ static void update_ftrace_function(void) | |||
265 | func = ftrace_ops_list_func; | 265 | func = ftrace_ops_list_func; |
266 | } | 266 | } |
267 | 267 | ||
268 | update_function_graph_func(); | ||
269 | |||
268 | /* If there's no change, then do nothing more here */ | 270 | /* If there's no change, then do nothing more here */ |
269 | if (ftrace_trace_function == func) | 271 | if (ftrace_trace_function == func) |
270 | return; | 272 | return; |
271 | 273 | ||
272 | update_function_graph_func(); | ||
273 | |||
274 | /* | 274 | /* |
275 | * If we are using the list function, it doesn't care | 275 | * If we are using the list function, it doesn't care |
276 | * about the function_trace_ops. | 276 | * about the function_trace_ops. |
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 7c56c3d06943..ff7027199a9a 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -616,10 +616,6 @@ int ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu, | |||
616 | struct ring_buffer_per_cpu *cpu_buffer; | 616 | struct ring_buffer_per_cpu *cpu_buffer; |
617 | struct rb_irq_work *work; | 617 | struct rb_irq_work *work; |
618 | 618 | ||
619 | if ((cpu == RING_BUFFER_ALL_CPUS && !ring_buffer_empty(buffer)) || | ||
620 | (cpu != RING_BUFFER_ALL_CPUS && !ring_buffer_empty_cpu(buffer, cpu))) | ||
621 | return POLLIN | POLLRDNORM; | ||
622 | |||
623 | if (cpu == RING_BUFFER_ALL_CPUS) | 619 | if (cpu == RING_BUFFER_ALL_CPUS) |
624 | work = &buffer->irq_work; | 620 | work = &buffer->irq_work; |
625 | else { | 621 | else { |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 384ede311717..291397e66669 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -466,6 +466,12 @@ int __trace_puts(unsigned long ip, const char *str, int size) | |||
466 | struct print_entry *entry; | 466 | struct print_entry *entry; |
467 | unsigned long irq_flags; | 467 | unsigned long irq_flags; |
468 | int alloc; | 468 | int alloc; |
469 | int pc; | ||
470 | |||
471 | if (!(trace_flags & TRACE_ITER_PRINTK)) | ||
472 | return 0; | ||
473 | |||
474 | pc = preempt_count(); | ||
469 | 475 | ||
470 | if (unlikely(tracing_selftest_running || tracing_disabled)) | 476 | if (unlikely(tracing_selftest_running || tracing_disabled)) |
471 | return 0; | 477 | return 0; |
@@ -475,7 +481,7 @@ int __trace_puts(unsigned long ip, const char *str, int size) | |||
475 | local_save_flags(irq_flags); | 481 | local_save_flags(irq_flags); |
476 | buffer = global_trace.trace_buffer.buffer; | 482 | buffer = global_trace.trace_buffer.buffer; |
477 | event = trace_buffer_lock_reserve(buffer, TRACE_PRINT, alloc, | 483 | event = trace_buffer_lock_reserve(buffer, TRACE_PRINT, alloc, |
478 | irq_flags, preempt_count()); | 484 | irq_flags, pc); |
479 | if (!event) | 485 | if (!event) |
480 | return 0; | 486 | return 0; |
481 | 487 | ||
@@ -492,6 +498,7 @@ int __trace_puts(unsigned long ip, const char *str, int size) | |||
492 | entry->buf[size] = '\0'; | 498 | entry->buf[size] = '\0'; |
493 | 499 | ||
494 | __buffer_unlock_commit(buffer, event); | 500 | __buffer_unlock_commit(buffer, event); |
501 | ftrace_trace_stack(buffer, irq_flags, 4, pc); | ||
495 | 502 | ||
496 | return size; | 503 | return size; |
497 | } | 504 | } |
@@ -509,6 +516,12 @@ int __trace_bputs(unsigned long ip, const char *str) | |||
509 | struct bputs_entry *entry; | 516 | struct bputs_entry *entry; |
510 | unsigned long irq_flags; | 517 | unsigned long irq_flags; |
511 | int size = sizeof(struct bputs_entry); | 518 | int size = sizeof(struct bputs_entry); |
519 | int pc; | ||
520 | |||
521 | if (!(trace_flags & TRACE_ITER_PRINTK)) | ||
522 | return 0; | ||
523 | |||
524 | pc = preempt_count(); | ||
512 | 525 | ||
513 | if (unlikely(tracing_selftest_running || tracing_disabled)) | 526 | if (unlikely(tracing_selftest_running || tracing_disabled)) |
514 | return 0; | 527 | return 0; |
@@ -516,7 +529,7 @@ int __trace_bputs(unsigned long ip, const char *str) | |||
516 | local_save_flags(irq_flags); | 529 | local_save_flags(irq_flags); |
517 | buffer = global_trace.trace_buffer.buffer; | 530 | buffer = global_trace.trace_buffer.buffer; |
518 | event = trace_buffer_lock_reserve(buffer, TRACE_BPUTS, size, | 531 | event = trace_buffer_lock_reserve(buffer, TRACE_BPUTS, size, |
519 | irq_flags, preempt_count()); | 532 | irq_flags, pc); |
520 | if (!event) | 533 | if (!event) |
521 | return 0; | 534 | return 0; |
522 | 535 | ||
@@ -525,6 +538,7 @@ int __trace_bputs(unsigned long ip, const char *str) | |||
525 | entry->str = str; | 538 | entry->str = str; |
526 | 539 | ||
527 | __buffer_unlock_commit(buffer, event); | 540 | __buffer_unlock_commit(buffer, event); |
541 | ftrace_trace_stack(buffer, irq_flags, 4, pc); | ||
528 | 542 | ||
529 | return 1; | 543 | return 1; |
530 | } | 544 | } |
@@ -809,7 +823,7 @@ static struct { | |||
809 | { trace_clock_local, "local", 1 }, | 823 | { trace_clock_local, "local", 1 }, |
810 | { trace_clock_global, "global", 1 }, | 824 | { trace_clock_global, "global", 1 }, |
811 | { trace_clock_counter, "counter", 0 }, | 825 | { trace_clock_counter, "counter", 0 }, |
812 | { trace_clock_jiffies, "uptime", 1 }, | 826 | { trace_clock_jiffies, "uptime", 0 }, |
813 | { trace_clock, "perf", 1 }, | 827 | { trace_clock, "perf", 1 }, |
814 | ARCH_TRACE_CLOCKS | 828 | ARCH_TRACE_CLOCKS |
815 | }; | 829 | }; |
@@ -1396,7 +1410,6 @@ void tracing_start(void) | |||
1396 | 1410 | ||
1397 | arch_spin_unlock(&global_trace.max_lock); | 1411 | arch_spin_unlock(&global_trace.max_lock); |
1398 | 1412 | ||
1399 | ftrace_start(); | ||
1400 | out: | 1413 | out: |
1401 | raw_spin_unlock_irqrestore(&global_trace.start_lock, flags); | 1414 | raw_spin_unlock_irqrestore(&global_trace.start_lock, flags); |
1402 | } | 1415 | } |
@@ -1443,7 +1456,6 @@ void tracing_stop(void) | |||
1443 | struct ring_buffer *buffer; | 1456 | struct ring_buffer *buffer; |
1444 | unsigned long flags; | 1457 | unsigned long flags; |
1445 | 1458 | ||
1446 | ftrace_stop(); | ||
1447 | raw_spin_lock_irqsave(&global_trace.start_lock, flags); | 1459 | raw_spin_lock_irqsave(&global_trace.start_lock, flags); |
1448 | if (global_trace.stop_count++) | 1460 | if (global_trace.stop_count++) |
1449 | goto out; | 1461 | goto out; |
diff --git a/kernel/trace/trace_clock.c b/kernel/trace/trace_clock.c index 26dc348332b7..57b67b1f24d1 100644 --- a/kernel/trace/trace_clock.c +++ b/kernel/trace/trace_clock.c | |||
@@ -59,13 +59,14 @@ u64 notrace trace_clock(void) | |||
59 | 59 | ||
60 | /* | 60 | /* |
61 | * trace_jiffy_clock(): Simply use jiffies as a clock counter. | 61 | * trace_jiffy_clock(): Simply use jiffies as a clock counter. |
62 | * Note that this use of jiffies_64 is not completely safe on | ||
63 | * 32-bit systems. But the window is tiny, and the effect if | ||
64 | * we are affected is that we will have an obviously bogus | ||
65 | * timestamp on a trace event - i.e. not life threatening. | ||
62 | */ | 66 | */ |
63 | u64 notrace trace_clock_jiffies(void) | 67 | u64 notrace trace_clock_jiffies(void) |
64 | { | 68 | { |
65 | u64 jiffy = jiffies - INITIAL_JIFFIES; | 69 | return jiffies_64_to_clock_t(jiffies_64 - INITIAL_JIFFIES); |
66 | |||
67 | /* Return nsecs */ | ||
68 | return (u64)jiffies_to_usecs(jiffy) * 1000ULL; | ||
69 | } | 70 | } |
70 | 71 | ||
71 | /* | 72 | /* |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index f99e0b3bca8c..2de53628689f 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -470,6 +470,7 @@ static void remove_event_file_dir(struct ftrace_event_file *file) | |||
470 | 470 | ||
471 | list_del(&file->list); | 471 | list_del(&file->list); |
472 | remove_subsystem(file->system); | 472 | remove_subsystem(file->system); |
473 | free_event_filter(file->filter); | ||
473 | kmem_cache_free(file_cachep, file); | 474 | kmem_cache_free(file_cachep, file); |
474 | } | 475 | } |
475 | 476 | ||
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 04fdb5de823c..3c9b97e6b1f4 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c | |||
@@ -893,6 +893,9 @@ probe_event_enable(struct trace_uprobe *tu, struct ftrace_event_file *file, | |||
893 | int ret; | 893 | int ret; |
894 | 894 | ||
895 | if (file) { | 895 | if (file) { |
896 | if (tu->tp.flags & TP_FLAG_PROFILE) | ||
897 | return -EINTR; | ||
898 | |||
896 | link = kmalloc(sizeof(*link), GFP_KERNEL); | 899 | link = kmalloc(sizeof(*link), GFP_KERNEL); |
897 | if (!link) | 900 | if (!link) |
898 | return -ENOMEM; | 901 | return -ENOMEM; |
@@ -901,29 +904,40 @@ probe_event_enable(struct trace_uprobe *tu, struct ftrace_event_file *file, | |||
901 | list_add_tail_rcu(&link->list, &tu->tp.files); | 904 | list_add_tail_rcu(&link->list, &tu->tp.files); |
902 | 905 | ||
903 | tu->tp.flags |= TP_FLAG_TRACE; | 906 | tu->tp.flags |= TP_FLAG_TRACE; |
904 | } else | 907 | } else { |
905 | tu->tp.flags |= TP_FLAG_PROFILE; | 908 | if (tu->tp.flags & TP_FLAG_TRACE) |
909 | return -EINTR; | ||
906 | 910 | ||
907 | ret = uprobe_buffer_enable(); | 911 | tu->tp.flags |= TP_FLAG_PROFILE; |
908 | if (ret < 0) | 912 | } |
909 | return ret; | ||
910 | 913 | ||
911 | WARN_ON(!uprobe_filter_is_empty(&tu->filter)); | 914 | WARN_ON(!uprobe_filter_is_empty(&tu->filter)); |
912 | 915 | ||
913 | if (enabled) | 916 | if (enabled) |
914 | return 0; | 917 | return 0; |
915 | 918 | ||
919 | ret = uprobe_buffer_enable(); | ||
920 | if (ret) | ||
921 | goto err_flags; | ||
922 | |||
916 | tu->consumer.filter = filter; | 923 | tu->consumer.filter = filter; |
917 | ret = uprobe_register(tu->inode, tu->offset, &tu->consumer); | 924 | ret = uprobe_register(tu->inode, tu->offset, &tu->consumer); |
918 | if (ret) { | 925 | if (ret) |
919 | if (file) { | 926 | goto err_buffer; |
920 | list_del(&link->list); | ||
921 | kfree(link); | ||
922 | tu->tp.flags &= ~TP_FLAG_TRACE; | ||
923 | } else | ||
924 | tu->tp.flags &= ~TP_FLAG_PROFILE; | ||
925 | } | ||
926 | 927 | ||
928 | return 0; | ||
929 | |||
930 | err_buffer: | ||
931 | uprobe_buffer_disable(); | ||
932 | |||
933 | err_flags: | ||
934 | if (file) { | ||
935 | list_del(&link->list); | ||
936 | kfree(link); | ||
937 | tu->tp.flags &= ~TP_FLAG_TRACE; | ||
938 | } else { | ||
939 | tu->tp.flags &= ~TP_FLAG_PROFILE; | ||
940 | } | ||
927 | return ret; | 941 | return ret; |
928 | } | 942 | } |
929 | 943 | ||
@@ -1201,12 +1215,6 @@ static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs) | |||
1201 | 1215 | ||
1202 | current->utask->vaddr = (unsigned long) &udd; | 1216 | current->utask->vaddr = (unsigned long) &udd; |
1203 | 1217 | ||
1204 | #ifdef CONFIG_PERF_EVENTS | ||
1205 | if ((tu->tp.flags & TP_FLAG_TRACE) == 0 && | ||
1206 | !uprobe_perf_filter(&tu->consumer, 0, current->mm)) | ||
1207 | return UPROBE_HANDLER_REMOVE; | ||
1208 | #endif | ||
1209 | |||
1210 | if (WARN_ON_ONCE(!uprobe_cpu_buffer)) | 1218 | if (WARN_ON_ONCE(!uprobe_cpu_buffer)) |
1211 | return 0; | 1219 | return 0; |
1212 | 1220 | ||