Blackfin arch: Add basic irq stack checking for Blackfin
authorRobin Getz <rgetz@blackfin.uclinux.org>
Wed, 7 Jan 2009 15:14:38 +0000 (23:14 +0800)
committerBryan Wu <cooloney@kernel.org>
Wed, 7 Jan 2009 15:14:38 +0000 (23:14 +0800)
Signed-off-by: Robin Getz <rgetz@blackfin.uclinux.org>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
arch/blackfin/Kconfig.debug
arch/blackfin/include/asm/processor.h
arch/blackfin/include/asm/thread_info.h
arch/blackfin/kernel/irqchip.c

index 3ad25983ec9777c97478745652217812a2674202..bfd712ab125ca276df19d7f45bda4d0ea92b44e4 100644 (file)
@@ -2,6 +2,22 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
+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.
+
+config DEBUG_STACK_USAGE
+       bool "Enable stack utilization instrumentation"
+       depends on DEBUG_KERNEL
+       help
+         Enables the display of the minimum amount of free stack which each
+         task has ever had available in the sysrq-T output.
+
+         This option will slow down process creation somewhat.
+
 config HAVE_ARCH_KGDB
        def_bool y
 
index 2cb0b8711fa4dc250396670fc359fbf224632865..83d57a85b14f22dde88f5ba625d40df06d65205e 100644 (file)
@@ -24,6 +24,14 @@ static inline void wrusp(unsigned long usp)
        __asm__ __volatile__("usp = %0;\n\t"::"da"(usp));
 }
 
+static inline unsigned long __get_SP(void)
+{
+       unsigned long sp;
+
+       __asm__ __volatile__("%0 = sp;\n\t" : "=da"(sp));
+       return sp;
+}
+
 /*
  * User space process size: 1st byte beyond user address space.
  * Fairly meaningless on nommu.  Parts of user programs can be scattered
index 642769329d12b12fde86d7fb99620a20a98f39ad..1d380def24106c5caf8c4086b1bd7a92045715c2 100644 (file)
@@ -44,6 +44,7 @@
  */
 #define THREAD_SIZE_ORDER      1
 #define THREAD_SIZE            8192    /* 2 pages */
+#define STACK_WARN             (THREAD_SIZE/8)
 
 #ifndef __ASSEMBLY__
 
index 5ad07525ea3fedc0d363f4b681962a5a6931879f..1624e1129681e9d0e71e052866fa5e879c0a1497 100644 (file)
@@ -120,7 +120,21 @@ asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
                desc = &bad_irq_desc;
 
        irq_enter();
-
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+       /* Debugging check for stack overflow: is there less than STACK_WARN free? */
+       {
+               long sp;
+
+               sp = __get_SP() & (THREAD_SIZE-1);
+
+               if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
+                       dump_stack();
+                       printk(KERN_EMERG "%s: possible stack overflow while handling irq %i "
+                                       " only %ld bytes free\n",
+                               __func__, irq, sp - sizeof(struct thread_info));
+               }
+       }
+#endif
        generic_handle_irq(irq);
 
        /* If we're the only interrupt running (ignoring IRQ15 which is for