Added configuration support for:
authorMarc Fiuczynski <mef@cs.princeton.edu>
Mon, 13 Dec 2004 22:00:04 +0000 (22:00 +0000)
committerMarc Fiuczynski <mef@cs.princeton.edu>
Mon, 13 Dec 2004 22:00:04 +0000 (22:00 +0000)
1) 4KB, 8KB, and 16KB stacks
2) separate IRQSTACKS
3) stack overflow warnings at a user-specified size

The original FC code only supports 4KB kernel stacks w/ a separate,
per-cpu, IRQ stack and the stack overflow warning was printed whenever
the kernel approached 1/8 of the current stack size.

The new support permits one to select different stack sizes and
separate IRQ stack using configuration options.  The default right
now is to use a 8KB kernel stack with a separate IRQ stack.

arch/i386/Kconfig
arch/i386/defconfig
arch/i386/kernel/asm-offsets.c
arch/i386/kernel/irq.c
configs/kernel-2.6.8-i686-planetlab.config
include/asm-i386/irq.h
include/asm-i386/module.h
include/asm-i386/processor.h
include/asm-i386/thread_info.h

index 15b003b..4599ce6 100644 (file)
@@ -926,6 +926,32 @@ config REGPARM
        generate incorrect output with certain kernel constructs when
        -mregparm=3 is used.
 
+config IRQSTACKS
+       bool "Use separate IRQ stacks"
+       help
+       If you say Y here the kernel will use a separate IRQ stack on each
+       cpu to handle interrupts.
+
+config STACK_SIZE_SHIFT
+       int "Kernel stack size (12 => 4KB, 13 => 8KB, 14 => 16KB)"
+       range 12 14
+       default 12 if IRQSTACKS
+       default 13
+       help
+       Select kernel stack size.  4KB stacks are best as they let
+       the system scale further.  Use 8KB stacks if you have an 
+       experimental kernel where a stack overlow with a 4KB stack
+       might occur.  Use 16KB stacks if you want to safely support
+       Windows device drivers using either Linuxant or ndiswrapper.
+
+config STACK_WARN
+       int "Print stack trace when stack grows beyond specified bytes"
+       default 4096 if IRQSTACKS
+       default 4096
+       help
+       The kernel will print a stack trace when the current stack exceeds
+       the specified size.
+
 endmenu
 
 
index aed3bc2..ed2bbb5 100644 (file)
@@ -1221,7 +1221,7 @@ CONFIG_OPROFILE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_FRAME_POINTER is not set
-CONFIG_4KSTACKS=y
+# CONFIG_4KSTACKS is not set
 CONFIG_X86_FIND_SMP_CONFIG=y
 CONFIG_X86_MPPARSE=y
 
index 43943f8..b03f579 100644 (file)
@@ -7,11 +7,11 @@
 #include <linux/sched.h>
 #include <linux/signal.h>
 #include <linux/personality.h>
+#include <linux/thread_info.h>
 #include <asm/ucontext.h>
 #include "sigframe.h"
 #include <asm/fixmap.h>
 #include <asm/processor.h>
-#include <asm/thread_info.h>
 
 #define DEFINE(sym, val) \
         asm volatile("\n->" #sym " %0 " #val : : "i" (val))
index 22f7fc7..1c8beda 100644 (file)
@@ -76,8 +76,10 @@ static void register_irq_proc (unsigned int irq);
 /*
  * per-CPU IRQ handling stacks
  */
+#ifdef CONFIG_IRQSTACKS
 union irq_ctx *hardirq_ctx[NR_CPUS];
 union irq_ctx *softirq_ctx[NR_CPUS];
+#endif
 
 /*
  * Special irq handlers.
@@ -220,6 +222,9 @@ asmlinkage int handle_IRQ_event(unsigned int irq,
        int status = 1; /* Force the "do bottom halves" bit */
        int retval = 0;
 
+       if (!(action->flags & SA_INTERRUPT))
+               local_irq_enable();
+
        do {
                status |= action->flags;
                retval |= action->handler(irq, action->dev_id, regs);
@@ -489,10 +494,12 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs)
                u32 *isp;
                union irq_ctx * curctx;
                union irq_ctx * irqctx;
-
+#ifdef CONFIG_IRQSTACKS
                curctx = (union irq_ctx *) current_thread_info();
                irqctx = hardirq_ctx[smp_processor_id()];
-
+#else
+               curctx = irqctx = (union irq_ctx *)0;
+#endif
                spin_unlock(&desc->lock);
 
                /*
@@ -536,7 +543,6 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs)
                        break;
                desc->status &= ~IRQ_PENDING;
        }
-
        desc->status &= ~IRQ_INPROGRESS;
 
 out:
@@ -1095,6 +1101,7 @@ void init_irq_proc (void)
 }
 
 
+#ifdef CONFIG_IRQSTACKS
 /*
  * These should really be __section__(".bss.page_aligned") as well, but
  * gcc's 3.0 and earlier don't handle that correctly.
@@ -1174,3 +1181,4 @@ asmlinkage void do_softirq(void)
 }
 
 EXPORT_SYMBOL(do_softirq);
+#endif
index ea66387..c23865c 100644 (file)
@@ -97,6 +97,7 @@ CONFIG_M686=y
 # CONFIG_MCYRIXIII is not set
 # CONFIG_MVIAC3_2 is not set
 CONFIG_X86_GENERIC=y
+# CONFIG_QEMU is not set
 CONFIG_X86_CMPXCHG=y
 CONFIG_X86_XADD=y
 CONFIG_X86_L1_CACHE_SHIFT=7
@@ -140,6 +141,9 @@ CONFIG_HIGHPTE=y
 # CONFIG_MATH_EMULATION is not set
 CONFIG_MTRR=y
 CONFIG_REGPARM=y
+CONFIG_IRQSTACKS=y
+CONFIG_STACK_SIZE_SHIFT=13
+CONFIG_STACK_WARN=4000
 
 #
 # Power management options (ACPI, APM)
index d1a4dd6..43917d9 100644 (file)
@@ -39,6 +39,7 @@ union irq_ctx {
        u32                     stack[THREAD_SIZE/sizeof(u32)];
 };
 
+#ifdef CONFIG_IRQSTACKS
 extern union irq_ctx *hardirq_ctx[NR_CPUS];
 extern union irq_ctx *softirq_ctx[NR_CPUS];
 
@@ -46,6 +47,10 @@ extern void irq_ctx_init(int cpu);
 
 #define __ARCH_HAS_DO_SOFTIRQ
 
+#else
+#define irq_ctx_init(cpu) do { ; } while (0)
+#endif
+
 struct irqaction;
 struct pt_regs;
 asmlinkage int handle_IRQ_event(unsigned int, struct pt_regs *,
index 614d05f..263c6f7 100644 (file)
@@ -60,7 +60,19 @@ struct mod_arch_specific
 #define MODULE_REGPARM ""
 #endif
 
+#if (CONFIG_STACK_SIZE_SHIFT < 12)
+#define MODULE_STACKSIZE "TINYSTACKS "
+#elif (CONFIG_STACK_SIZE_SHIFT == 12)
 #define MODULE_STACKSIZE "4KSTACKS "
+#elif (CONFIG_STACK_SIZE_SHIFT == 13)
+#define MODULE_STACKSIZE "8KSTACKS "
+#elif (CONFIG_STACK_SIZE_SHIFT == 14)
+#define MODULE_STACKSIZE "16KSTACKS "
+#elif (CONFIG_STACK_SIZE_SHIFT > 14)
+#define MODULE_STACKSIZE "HUGESTACKS "
+#else
+#define MODULE_STACKSIZE ""
+#endif
 
 #define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE
 
index cd8708b..3651a3b 100644 (file)
@@ -400,10 +400,10 @@ struct tss_struct {
 
 #define ARCH_MIN_TASKALIGN     16
 
-
-#define STACK_PAGE_COUNT       (4096/PAGE_SIZE)
-
-
+#if ((1<<CONFIG_STACK_SIZE_SHIFT) < PAGE_SIZE)
+#error (1<<CONFIG_STACK_SIZE_SHIFT) must be at least PAGE_SIZE
+#endif
+#define STACK_PAGE_COUNT       ((1<<CONFIG_STACK_SIZE_SHIFT)/PAGE_SIZE)
 
 
 struct thread_struct {
index d941e6d..d4fe6a5 100644 (file)
@@ -54,9 +54,9 @@ struct thread_info {
 #endif
 
 #define PREEMPT_ACTIVE         0x4000000
-#define THREAD_SIZE            (4096)
+#define THREAD_SIZE            (1<<CONFIG_STACK_SIZE_SHIFT)
+#define STACK_WARN             (CONFIG_STACK_WARN)
 
-#define STACK_WARN             (THREAD_SIZE/8)
 /*
  * macros/functions for gaining access to the thread information structure
  *