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>
This commit is contained in:
parent
b78807158b
commit
334c86c494
3 changed files with 35 additions and 0 deletions
|
@ -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");
|
||||||
#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)
|
||||||
#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)
|
||||||
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();
|
||||||
|
|
Loading…
Reference in a new issue