diff options
author | Ingo Molnar <mingo@elte.hu> | 2010-07-23 03:10:29 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-07-23 03:10:29 -0400 |
commit | 3a01736e70a7d629140695ba46a901266b4460cc (patch) | |
tree | 49ff8ce1e7c6a267f0ce84b5daddbe6666bc4253 /kernel/trace/trace.c | |
parent | 4c21adf26f8fcf86a755b9b9f55c2e9fd241e1fb (diff) | |
parent | 24a461d537f49f9da6533d83100999ea08c6c755 (diff) |
Merge branch 'tip/perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace into perf/core
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r-- | kernel/trace/trace.c | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c1752dac613e..4b1122d0df37 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -344,7 +344,7 @@ static DECLARE_WAIT_QUEUE_HEAD(trace_wait); | |||
344 | /* trace_flags holds trace_options default values */ | 344 | /* trace_flags holds trace_options default values */ |
345 | unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK | | 345 | unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK | |
346 | TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME | | 346 | TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME | |
347 | TRACE_ITER_GRAPH_TIME; | 347 | TRACE_ITER_GRAPH_TIME | TRACE_ITER_RECORD_CMD; |
348 | 348 | ||
349 | static int trace_stop_count; | 349 | static int trace_stop_count; |
350 | static DEFINE_SPINLOCK(tracing_start_lock); | 350 | static DEFINE_SPINLOCK(tracing_start_lock); |
@@ -428,6 +428,7 @@ static const char *trace_options[] = { | |||
428 | "latency-format", | 428 | "latency-format", |
429 | "sleep-time", | 429 | "sleep-time", |
430 | "graph-time", | 430 | "graph-time", |
431 | "record-cmd", | ||
431 | NULL | 432 | NULL |
432 | }; | 433 | }; |
433 | 434 | ||
@@ -659,6 +660,10 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) | |||
659 | return; | 660 | return; |
660 | 661 | ||
661 | WARN_ON_ONCE(!irqs_disabled()); | 662 | WARN_ON_ONCE(!irqs_disabled()); |
663 | if (!current_trace->use_max_tr) { | ||
664 | WARN_ON_ONCE(1); | ||
665 | return; | ||
666 | } | ||
662 | arch_spin_lock(&ftrace_max_lock); | 667 | arch_spin_lock(&ftrace_max_lock); |
663 | 668 | ||
664 | tr->buffer = max_tr.buffer; | 669 | tr->buffer = max_tr.buffer; |
@@ -685,6 +690,11 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) | |||
685 | return; | 690 | return; |
686 | 691 | ||
687 | WARN_ON_ONCE(!irqs_disabled()); | 692 | WARN_ON_ONCE(!irqs_disabled()); |
693 | if (!current_trace->use_max_tr) { | ||
694 | WARN_ON_ONCE(1); | ||
695 | return; | ||
696 | } | ||
697 | |||
688 | arch_spin_lock(&ftrace_max_lock); | 698 | arch_spin_lock(&ftrace_max_lock); |
689 | 699 | ||
690 | ftrace_disable_cpu(); | 700 | ftrace_disable_cpu(); |
@@ -729,7 +739,7 @@ __acquires(kernel_lock) | |||
729 | return -1; | 739 | return -1; |
730 | } | 740 | } |
731 | 741 | ||
732 | if (strlen(type->name) > MAX_TRACER_SIZE) { | 742 | if (strlen(type->name) >= MAX_TRACER_SIZE) { |
733 | pr_info("Tracer has a name longer than %d\n", MAX_TRACER_SIZE); | 743 | pr_info("Tracer has a name longer than %d\n", MAX_TRACER_SIZE); |
734 | return -1; | 744 | return -1; |
735 | } | 745 | } |
@@ -2508,6 +2518,9 @@ static void set_tracer_flags(unsigned int mask, int enabled) | |||
2508 | trace_flags |= mask; | 2518 | trace_flags |= mask; |
2509 | else | 2519 | else |
2510 | trace_flags &= ~mask; | 2520 | trace_flags &= ~mask; |
2521 | |||
2522 | if (mask == TRACE_ITER_RECORD_CMD) | ||
2523 | trace_event_enable_cmd_record(enabled); | ||
2511 | } | 2524 | } |
2512 | 2525 | ||
2513 | static ssize_t | 2526 | static ssize_t |
@@ -2746,6 +2759,9 @@ static int tracing_resize_ring_buffer(unsigned long size) | |||
2746 | if (ret < 0) | 2759 | if (ret < 0) |
2747 | return ret; | 2760 | return ret; |
2748 | 2761 | ||
2762 | if (!current_trace->use_max_tr) | ||
2763 | goto out; | ||
2764 | |||
2749 | ret = ring_buffer_resize(max_tr.buffer, size); | 2765 | ret = ring_buffer_resize(max_tr.buffer, size); |
2750 | if (ret < 0) { | 2766 | if (ret < 0) { |
2751 | int r; | 2767 | int r; |
@@ -2773,11 +2789,14 @@ static int tracing_resize_ring_buffer(unsigned long size) | |||
2773 | return ret; | 2789 | return ret; |
2774 | } | 2790 | } |
2775 | 2791 | ||
2792 | max_tr.entries = size; | ||
2793 | out: | ||
2776 | global_trace.entries = size; | 2794 | global_trace.entries = size; |
2777 | 2795 | ||
2778 | return ret; | 2796 | return ret; |
2779 | } | 2797 | } |
2780 | 2798 | ||
2799 | |||
2781 | /** | 2800 | /** |
2782 | * tracing_update_buffers - used by tracing facility to expand ring buffers | 2801 | * tracing_update_buffers - used by tracing facility to expand ring buffers |
2783 | * | 2802 | * |
@@ -2838,12 +2857,26 @@ static int tracing_set_tracer(const char *buf) | |||
2838 | trace_branch_disable(); | 2857 | trace_branch_disable(); |
2839 | if (current_trace && current_trace->reset) | 2858 | if (current_trace && current_trace->reset) |
2840 | current_trace->reset(tr); | 2859 | current_trace->reset(tr); |
2841 | 2860 | if (current_trace && current_trace->use_max_tr) { | |
2861 | /* | ||
2862 | * We don't free the ring buffer. instead, resize it because | ||
2863 | * The max_tr ring buffer has some state (e.g. ring->clock) and | ||
2864 | * we want preserve it. | ||
2865 | */ | ||
2866 | ring_buffer_resize(max_tr.buffer, 1); | ||
2867 | max_tr.entries = 1; | ||
2868 | } | ||
2842 | destroy_trace_option_files(topts); | 2869 | destroy_trace_option_files(topts); |
2843 | 2870 | ||
2844 | current_trace = t; | 2871 | current_trace = t; |
2845 | 2872 | ||
2846 | topts = create_trace_option_files(current_trace); | 2873 | topts = create_trace_option_files(current_trace); |
2874 | if (current_trace->use_max_tr) { | ||
2875 | ret = ring_buffer_resize(max_tr.buffer, global_trace.entries); | ||
2876 | if (ret < 0) | ||
2877 | goto out; | ||
2878 | max_tr.entries = global_trace.entries; | ||
2879 | } | ||
2847 | 2880 | ||
2848 | if (t->init) { | 2881 | if (t->init) { |
2849 | ret = tracer_init(t, tr); | 2882 | ret = tracer_init(t, tr); |
@@ -3426,7 +3459,6 @@ tracing_entries_write(struct file *filp, const char __user *ubuf, | |||
3426 | } | 3459 | } |
3427 | 3460 | ||
3428 | tracing_start(); | 3461 | tracing_start(); |
3429 | max_tr.entries = global_trace.entries; | ||
3430 | mutex_unlock(&trace_types_lock); | 3462 | mutex_unlock(&trace_types_lock); |
3431 | 3463 | ||
3432 | return cnt; | 3464 | return cnt; |
@@ -4531,16 +4563,14 @@ __init static int tracer_alloc_buffers(void) | |||
4531 | 4563 | ||
4532 | 4564 | ||
4533 | #ifdef CONFIG_TRACER_MAX_TRACE | 4565 | #ifdef CONFIG_TRACER_MAX_TRACE |
4534 | max_tr.buffer = ring_buffer_alloc(ring_buf_size, | 4566 | max_tr.buffer = ring_buffer_alloc(1, TRACE_BUFFER_FLAGS); |
4535 | TRACE_BUFFER_FLAGS); | ||
4536 | if (!max_tr.buffer) { | 4567 | if (!max_tr.buffer) { |
4537 | printk(KERN_ERR "tracer: failed to allocate max ring buffer!\n"); | 4568 | printk(KERN_ERR "tracer: failed to allocate max ring buffer!\n"); |
4538 | WARN_ON(1); | 4569 | WARN_ON(1); |
4539 | ring_buffer_free(global_trace.buffer); | 4570 | ring_buffer_free(global_trace.buffer); |
4540 | goto out_free_cpumask; | 4571 | goto out_free_cpumask; |
4541 | } | 4572 | } |
4542 | max_tr.entries = ring_buffer_size(max_tr.buffer); | 4573 | max_tr.entries = 1; |
4543 | WARN_ON(max_tr.entries != global_trace.entries); | ||
4544 | #endif | 4574 | #endif |
4545 | 4575 | ||
4546 | /* Allocate the first page for all buffers */ | 4576 | /* Allocate the first page for all buffers */ |