diff options
author | Vegard Nossum <vegard.nossum@gmail.com> | 2008-06-27 12:06:54 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-06-27 12:09:16 -0400 |
commit | 4e6a0535dd036377961027262aecb138099f925d (patch) | |
tree | 0594ca7b386ca7953b909e3077b13fda5c26907b /kernel | |
parent | ad118c54a3587b2c69a769d0ba37d4d8dce4559d (diff) |
backtrace: replace timer with tasklet + completions
On qemu, the backtrace would show up _after_ the "end of backtrace
testing" message.
This patch changes it to use completions instead, which will guarantee
that no such race exists.
Cc: Arjan van de Ven <arjan@infradead.org>
Signed-off-by: Vegard Nossum <vegard.nossum@gmail.com>
Cc: Arjan van de Ven <arjan@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/backtracetest.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/kernel/backtracetest.c b/kernel/backtracetest.c index 50f7abd0813d..a5e026bc45c4 100644 --- a/kernel/backtracetest.c +++ b/kernel/backtracetest.c | |||
@@ -10,18 +10,39 @@ | |||
10 | * of the License. | 10 | * of the License. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/completion.h> | ||
13 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/interrupt.h> | ||
14 | #include <linux/module.h> | 16 | #include <linux/module.h> |
15 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
16 | #include <linux/stacktrace.h> | 18 | #include <linux/stacktrace.h> |
17 | 19 | ||
18 | static struct timer_list backtrace_timer; | 20 | static void backtrace_test_normal(void) |
21 | { | ||
22 | printk("Testing a backtrace from process context.\n"); | ||
23 | printk("The following trace is a kernel self test and not a bug!\n"); | ||
24 | |||
25 | dump_stack(); | ||
26 | } | ||
27 | |||
28 | static DECLARE_COMPLETION(backtrace_work); | ||
29 | |||
30 | static void backtrace_test_irq_callback(unsigned long data) | ||
31 | { | ||
32 | dump_stack(); | ||
33 | complete(&backtrace_work); | ||
34 | } | ||
35 | |||
36 | static DECLARE_TASKLET(backtrace_tasklet, &backtrace_test_irq_callback, 0); | ||
19 | 37 | ||
20 | static void backtrace_test_timer(unsigned long data) | 38 | static void backtrace_test_irq(void) |
21 | { | 39 | { |
22 | printk("Testing a backtrace from irq context.\n"); | 40 | printk("Testing a backtrace from irq context.\n"); |
23 | printk("The following trace is a kernel self test and not a bug!\n"); | 41 | printk("The following trace is a kernel self test and not a bug!\n"); |
24 | dump_stack(); | 42 | |
43 | init_completion(&backtrace_work); | ||
44 | tasklet_schedule(&backtrace_tasklet); | ||
45 | wait_for_completion(&backtrace_work); | ||
25 | } | 46 | } |
26 | 47 | ||
27 | #ifdef CONFIG_STACKTRACE | 48 | #ifdef CONFIG_STACKTRACE |
@@ -51,17 +72,11 @@ static void backtrace_test_saved(void) | |||
51 | static int backtrace_regression_test(void) | 72 | static int backtrace_regression_test(void) |
52 | { | 73 | { |
53 | printk("====[ backtrace testing ]===========\n"); | 74 | printk("====[ backtrace testing ]===========\n"); |
54 | printk("Testing a backtrace from process context.\n"); | ||
55 | printk("The following trace is a kernel self test and not a bug!\n"); | ||
56 | dump_stack(); | ||
57 | 75 | ||
76 | backtrace_test_normal(); | ||
77 | backtrace_test_irq(); | ||
58 | backtrace_test_saved(); | 78 | backtrace_test_saved(); |
59 | 79 | ||
60 | init_timer(&backtrace_timer); | ||
61 | backtrace_timer.function = backtrace_test_timer; | ||
62 | mod_timer(&backtrace_timer, jiffies + 10); | ||
63 | |||
64 | msleep(10); | ||
65 | printk("====[ end of backtrace testing ]====\n"); | 80 | printk("====[ end of backtrace testing ]====\n"); |
66 | return 0; | 81 | return 0; |
67 | } | 82 | } |