diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2008-11-18 18:06:35 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-11-18 21:54:50 +0100 |
commit | a22506347d038a66506c6f57e9b97104128e280d (patch) | |
tree | 88a21ea77883d13f92c4eda322b44bbddcd48aee | |
parent | 1c80025a49855b12fa09bb6db71820e3367b1369 (diff) | |
download | linux-a22506347d038a66506c6f57e9b97104128e280d.tar.gz linux-a22506347d038a66506c6f57e9b97104128e280d.tar.bz2 linux-a22506347d038a66506c6f57e9b97104128e280d.zip |
ftrace: preemptoff selftest not working
Impact: fix preemptoff and preemptirqsoff tracer self-tests
I was wondering why the preemptoff and preemptirqsoff tracer selftests
don't work on s390. After all its just that they get called from
non-preemptible context:
kernel_init() will execute all initcalls, however the first line in
kernel_init() is lock_kernel(), which causes the preempt_count to be
increased. Any later calls to add_preempt_count() (especially those
from the selftests) will therefore not result in a call to
trace_preempt_off() since the check below in add_preempt_count()
will be false:
if (preempt_count() == val)
trace_preempt_off(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1));
Hence the trace buffer will be empty.
Fix this by releasing the BKL during the self-tests.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | kernel/trace/trace.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 396fda034e3f..16892121cb7c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -532,6 +532,13 @@ int register_tracer(struct tracer *type) } #ifdef CONFIG_FTRACE_STARTUP_TEST + /* + * When this gets called we hold the BKL which means that preemption + * is disabled. Various trace selftests however need to disable + * and enable preemption for successful tests. So we drop the BKL here + * and grab it after the tests again. + */ + unlock_kernel(); if (type->selftest) { struct tracer *saved_tracer = current_trace; struct trace_array *tr = &global_trace; @@ -562,6 +569,7 @@ int register_tracer(struct tracer *type) } printk(KERN_CONT "PASSED\n"); } + lock_kernel(); #endif type->next = trace_types; |