Commit 334c86c4 authored by From: jiang.adam@gmail.com's avatar From: jiang.adam@gmail.com Committed by Ralf Baechle

MIPS: IRQ: Add stackoverflow detection

Add stackoverflow detection to mips arch
Signed-off-by: default avatarAdam 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: default avatarRalf Baechle <ralf@linux-mips.org>
parent b7880715
...@@ -67,6 +67,15 @@ config CMDLINE_OVERRIDE ...@@ -67,6 +67,15 @@ config CMDLINE_OVERRIDE
Normally, you will choose 'N' here. 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 config DEBUG_STACK_USAGE
bool "Enable stack utilization instrumentation" bool "Enable stack utilization instrumentation"
depends on DEBUG_KERNEL depends on DEBUG_KERNEL
......
...@@ -83,6 +83,8 @@ register struct thread_info *__current_thread_info __asm__("$28"); ...@@ -83,6 +83,8 @@ register struct thread_info *__current_thread_info __asm__("$28");
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
#define THREAD_MASK (THREAD_SIZE - 1UL) #define THREAD_MASK (THREAD_SIZE - 1UL)
#define STACK_WARN (THREAD_SIZE / 8)
#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR #define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
#ifdef CONFIG_DEBUG_STACK_USAGE #ifdef CONFIG_DEBUG_STACK_USAGE
......
...@@ -151,6 +151,29 @@ void __init init_IRQ(void) ...@@ -151,6 +151,29 @@ void __init init_IRQ(void)
#endif #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 * do_IRQ handles all normal device IRQ's (the special
* SMP cross-CPU interrupts have their own specific * SMP cross-CPU interrupts have their own specific
...@@ -159,6 +182,7 @@ void __init init_IRQ(void) ...@@ -159,6 +182,7 @@ void __init init_IRQ(void)
void __irq_entry do_IRQ(unsigned int irq) void __irq_entry do_IRQ(unsigned int irq)
{ {
irq_enter(); irq_enter();
check_stack_overflow();
__DO_IRQ_SMTC_HOOK(irq); __DO_IRQ_SMTC_HOOK(irq);
generic_handle_irq(irq); generic_handle_irq(irq);
irq_exit(); irq_exit();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment