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 3ad2598..bfd712a 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 2cb0b87..83d57a8 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 6427693..1d380de 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 5ad0752..1624e11 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