diff options
author | From: jiang.adam@gmail.com <From: jiang.adam@gmail.com> | 2010-08-27 18:32:06 +0900 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2010-10-29 19:08:27 +0100 |
commit | 334c86c494b9a5754d4c0ffa3110b18c9771013b (patch) | |
tree | ab0ceed9ff00fd7a0b7bbd194b537f8d1a271aef /arch/mips | |
parent | b78807158be93c4756f88b5fc0790863f2690fdc (diff) |
MIPS: IRQ: Add stackoverflow detection
Add stackoverflow detection to mips arch
Signed-off-by: Adam Jiang <jiang.adam@gmail.com>
Cc: dmitri.vorobiev@movial.com
Cc: wuzhangjin@gmail.com
Cc: ddaney@caviumnetworks.com
Cc: peterz@infradead.org
Cc: fweisbec@gmail.com
Cc: tj@kernel.org
Cc: tglx@linutronix.de
Cc: mingo@elte.hu
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/1559/
Patchwork: https://patchwork.linux-mips.org/patch/1651/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/Kconfig.debug | 9 | ||||
-rw-r--r-- | arch/mips/include/asm/thread_info.h | 2 | ||||
-rw-r--r-- | arch/mips/kernel/irq.c | 24 |
3 files changed, 35 insertions, 0 deletions
diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug index 43dc2799773..f437cd1fafb 100644 --- a/arch/mips/Kconfig.debug +++ b/arch/mips/Kconfig.debug @@ -67,6 +67,15 @@ config CMDLINE_OVERRIDE Normally, you will choose 'N' here. +config DEBUG_STACKOVERFLOW + bool "Check for stack overflows" + depends on DEBUG_KERNEL + help + This option will cause messages to be printed if free stack space + drops below a certain limit(2GB on MIPS). The debugging option + provides another way to check stack overflow happened on kernel mode + stack usually caused by nested interruption. + config DEBUG_STACK_USAGE bool "Enable stack utilization instrumentation" depends on DEBUG_KERNEL diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 70df9c0d3c5..d309556cacf 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h @@ -83,6 +83,8 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) #define THREAD_MASK (THREAD_SIZE - 1UL) +#define STACK_WARN (THREAD_SIZE / 8) + #define __HAVE_ARCH_THREAD_INFO_ALLOCATOR #ifdef CONFIG_DEBUG_STACK_USAGE diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index c6345f579a8..4f93db58a79 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -151,6 +151,29 @@ void __init init_IRQ(void) #endif } +#ifdef DEBUG_STACKOVERFLOW +static inline void check_stack_overflow(void) +{ + unsigned long sp; + + __asm__ __volatile__("move %0, $sp" : "=r" (sp)); + sp &= THREAD_MASK; + + /* + * Check for stack overflow: is there less than STACK_WARN free? + * STACK_WARN is defined as 1/8 of THREAD_SIZE by default. + */ + if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) { + printk("do_IRQ: stack overflow: %ld\n", + sp - sizeof(struct thread_info)); + dump_stack(); + } +} +#else +static inline void check_stack_overflow(void) {} +#endif + + /* * do_IRQ handles all normal device IRQ's (the special * SMP cross-CPU interrupts have their own specific @@ -159,6 +182,7 @@ void __init init_IRQ(void) void __irq_entry do_IRQ(unsigned int irq) { irq_enter(); + check_stack_overflow(); __DO_IRQ_SMTC_HOOK(irq); generic_handle_irq(irq); irq_exit(); |