diff options
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r-- | kernel/trace/trace.c | 62 |
1 files changed, 26 insertions, 36 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 1c8285240152..55a9d0501ee7 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -5020,36 +5020,32 @@ void trace_init_global_iter(struct trace_iterator *iter) | |||
5020 | iter->cpu_file = TRACE_PIPE_ALL_CPU; | 5020 | iter->cpu_file = TRACE_PIPE_ALL_CPU; |
5021 | } | 5021 | } |
5022 | 5022 | ||
5023 | static void | 5023 | void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) |
5024 | __ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode) | ||
5025 | { | 5024 | { |
5026 | static arch_spinlock_t ftrace_dump_lock = | ||
5027 | (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; | ||
5028 | /* use static because iter can be a bit big for the stack */ | 5025 | /* use static because iter can be a bit big for the stack */ |
5029 | static struct trace_iterator iter; | 5026 | static struct trace_iterator iter; |
5027 | static atomic_t dump_running; | ||
5030 | unsigned int old_userobj; | 5028 | unsigned int old_userobj; |
5031 | static int dump_ran; | ||
5032 | unsigned long flags; | 5029 | unsigned long flags; |
5033 | int cnt = 0, cpu; | 5030 | int cnt = 0, cpu; |
5034 | 5031 | ||
5035 | /* only one dump */ | 5032 | /* Only allow one dump user at a time. */ |
5036 | local_irq_save(flags); | 5033 | if (atomic_inc_return(&dump_running) != 1) { |
5037 | arch_spin_lock(&ftrace_dump_lock); | 5034 | atomic_dec(&dump_running); |
5038 | if (dump_ran) | 5035 | return; |
5039 | goto out; | 5036 | } |
5040 | |||
5041 | dump_ran = 1; | ||
5042 | 5037 | ||
5038 | /* | ||
5039 | * Always turn off tracing when we dump. | ||
5040 | * We don't need to show trace output of what happens | ||
5041 | * between multiple crashes. | ||
5042 | * | ||
5043 | * If the user does a sysrq-z, then they can re-enable | ||
5044 | * tracing with echo 1 > tracing_on. | ||
5045 | */ | ||
5043 | tracing_off(); | 5046 | tracing_off(); |
5044 | 5047 | ||
5045 | /* Did function tracer already get disabled? */ | 5048 | local_irq_save(flags); |
5046 | if (ftrace_is_dead()) { | ||
5047 | printk("# WARNING: FUNCTION TRACING IS CORRUPTED\n"); | ||
5048 | printk("# MAY BE MISSING FUNCTION EVENTS\n"); | ||
5049 | } | ||
5050 | |||
5051 | if (disable_tracing) | ||
5052 | ftrace_kill(); | ||
5053 | 5049 | ||
5054 | trace_init_global_iter(&iter); | 5050 | trace_init_global_iter(&iter); |
5055 | 5051 | ||
@@ -5082,6 +5078,12 @@ __ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode) | |||
5082 | 5078 | ||
5083 | printk(KERN_TRACE "Dumping ftrace buffer:\n"); | 5079 | printk(KERN_TRACE "Dumping ftrace buffer:\n"); |
5084 | 5080 | ||
5081 | /* Did function tracer already get disabled? */ | ||
5082 | if (ftrace_is_dead()) { | ||
5083 | printk("# WARNING: FUNCTION TRACING IS CORRUPTED\n"); | ||
5084 | printk("# MAY BE MISSING FUNCTION EVENTS\n"); | ||
5085 | } | ||
5086 | |||
5085 | /* | 5087 | /* |
5086 | * We need to stop all tracing on all CPUS to read the | 5088 | * We need to stop all tracing on all CPUS to read the |
5087 | * the next buffer. This is a bit expensive, but is | 5089 | * the next buffer. This is a bit expensive, but is |
@@ -5121,26 +5123,14 @@ __ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode) | |||
5121 | printk(KERN_TRACE "---------------------------------\n"); | 5123 | printk(KERN_TRACE "---------------------------------\n"); |
5122 | 5124 | ||
5123 | out_enable: | 5125 | out_enable: |
5124 | /* Re-enable tracing if requested */ | 5126 | trace_flags |= old_userobj; |
5125 | if (!disable_tracing) { | ||
5126 | trace_flags |= old_userobj; | ||
5127 | 5127 | ||
5128 | for_each_tracing_cpu(cpu) { | 5128 | for_each_tracing_cpu(cpu) { |
5129 | atomic_dec(&iter.tr->data[cpu]->disabled); | 5129 | atomic_dec(&iter.tr->data[cpu]->disabled); |
5130 | } | ||
5131 | tracing_on(); | ||
5132 | } | 5130 | } |
5133 | 5131 | atomic_dec(&dump_running); | |
5134 | out: | ||
5135 | arch_spin_unlock(&ftrace_dump_lock); | ||
5136 | local_irq_restore(flags); | 5132 | local_irq_restore(flags); |
5137 | } | 5133 | } |
5138 | |||
5139 | /* By default: disable tracing after the dump */ | ||
5140 | void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) | ||
5141 | { | ||
5142 | __ftrace_dump(true, oops_dump_mode); | ||
5143 | } | ||
5144 | EXPORT_SYMBOL_GPL(ftrace_dump); | 5134 | EXPORT_SYMBOL_GPL(ftrace_dump); |
5145 | 5135 | ||
5146 | __init static int tracer_alloc_buffers(void) | 5136 | __init static int tracer_alloc_buffers(void) |