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 | |
| 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>
| -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 | } |
