diff options
author | Christoph Hellwig <hch@lst.de> | 2010-06-28 08:15:54 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2010-06-29 06:12:59 -0400 |
commit | 7974891db234467eaf1fec613ec0129cb4ac2332 (patch) | |
tree | 09de403e54e39f4f25a1c15a29f5b201d4c11729 | |
parent | 5904b3b81d25166e5e39b9727645bb47937618e3 (diff) |
x86: Always use irq stacks
IRQ stacks provide much better safety against unexpected stack use from
interrupts, at the minimal downside of slightly higher memory usage.
Enable irq stacks also for the default 8k stack on 32-bit kernels to
minimize the problem of stack overflows through interrupt activity.
This is what the 64-bit kernel and various other architectures already do.
Signed-off-by: Christoph Hellwig <hch@lst.de>
LKML-Reference: <20100628121554.GA6605@lst.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | Documentation/x86/x86_64/kernel-stacks | 6 | ||||
-rw-r--r-- | arch/x86/Kconfig.debug | 3 | ||||
-rw-r--r-- | arch/x86/include/asm/irq.h | 12 | ||||
-rw-r--r-- | arch/x86/kernel/irq_32.c | 6 |
4 files changed, 9 insertions, 18 deletions
diff --git a/Documentation/x86/x86_64/kernel-stacks b/Documentation/x86/x86_64/kernel-stacks index 5ad65d51fb95..a01eec5d1d0b 100644 --- a/Documentation/x86/x86_64/kernel-stacks +++ b/Documentation/x86/x86_64/kernel-stacks | |||
@@ -18,9 +18,9 @@ specialized stacks contain no useful data. The main CPU stacks are: | |||
18 | Used for external hardware interrupts. If this is the first external | 18 | Used for external hardware interrupts. If this is the first external |
19 | hardware interrupt (i.e. not a nested hardware interrupt) then the | 19 | hardware interrupt (i.e. not a nested hardware interrupt) then the |
20 | kernel switches from the current task to the interrupt stack. Like | 20 | kernel switches from the current task to the interrupt stack. Like |
21 | the split thread and interrupt stacks on i386 (with CONFIG_4KSTACKS), | 21 | the split thread and interrupt stacks on i386, this gives more room |
22 | this gives more room for kernel interrupt processing without having | 22 | for kernel interrupt processing without having to increase the size |
23 | to increase the size of every per thread stack. | 23 | of every per thread stack. |
24 | 24 | ||
25 | The interrupt stack is also used when processing a softirq. | 25 | The interrupt stack is also used when processing a softirq. |
26 | 26 | ||
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 75085080b63e..badda8e20e78 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug | |||
@@ -128,8 +128,7 @@ config 4KSTACKS | |||
128 | If you say Y here the kernel will use a 4Kb stacksize for the | 128 | If you say Y here the kernel will use a 4Kb stacksize for the |
129 | kernel stack attached to each process/thread. This facilitates | 129 | kernel stack attached to each process/thread. This facilitates |
130 | running more threads on a system and also reduces the pressure | 130 | running more threads on a system and also reduces the pressure |
131 | on the VM subsystem for higher order allocations. This option | 131 | on the VM subsystem for higher order allocations. |
132 | will also use IRQ stacks to compensate for the reduced stackspace. | ||
133 | 132 | ||
134 | config DOUBLEFAULT | 133 | config DOUBLEFAULT |
135 | default y | 134 | default y |
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h index 5458380b6ef8..0bf5b0083650 100644 --- a/arch/x86/include/asm/irq.h +++ b/arch/x86/include/asm/irq.h | |||
@@ -19,18 +19,16 @@ static inline int irq_canonicalize(int irq) | |||
19 | # define ARCH_HAS_NMI_WATCHDOG | 19 | # define ARCH_HAS_NMI_WATCHDOG |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #ifdef CONFIG_4KSTACKS | 22 | #ifdef CONFIG_X86_32 |
23 | extern void irq_ctx_init(int cpu); | 23 | extern void irq_ctx_init(int cpu); |
24 | extern void irq_ctx_exit(int cpu); | 24 | extern void irq_ctx_exit(int cpu); |
25 | # define __ARCH_HAS_DO_SOFTIRQ | ||
26 | #else | 25 | #else |
27 | # define irq_ctx_init(cpu) do { } while (0) | 26 | # define irq_ctx_init(cpu) do { } while (0) |
28 | # define irq_ctx_exit(cpu) do { } while (0) | 27 | # define irq_ctx_exit(cpu) do { } while (0) |
29 | # ifdef CONFIG_X86_64 | ||
30 | # define __ARCH_HAS_DO_SOFTIRQ | ||
31 | # endif | ||
32 | #endif | 28 | #endif |
33 | 29 | ||
30 | #define __ARCH_HAS_DO_SOFTIRQ | ||
31 | |||
34 | #ifdef CONFIG_HOTPLUG_CPU | 32 | #ifdef CONFIG_HOTPLUG_CPU |
35 | #include <linux/cpumask.h> | 33 | #include <linux/cpumask.h> |
36 | extern void fixup_irqs(void); | 34 | extern void fixup_irqs(void); |
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index 10709f29d166..67f5f9f5299f 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c | |||
@@ -49,7 +49,6 @@ static inline int check_stack_overflow(void) { return 0; } | |||
49 | static inline void print_stack_overflow(void) { } | 49 | static inline void print_stack_overflow(void) { } |
50 | #endif | 50 | #endif |
51 | 51 | ||
52 | #ifdef CONFIG_4KSTACKS | ||
53 | /* | 52 | /* |
54 | * per-CPU IRQ handling contexts (thread information and stack) | 53 | * per-CPU IRQ handling contexts (thread information and stack) |
55 | */ | 54 | */ |
@@ -187,11 +186,6 @@ asmlinkage void do_softirq(void) | |||
187 | local_irq_restore(flags); | 186 | local_irq_restore(flags); |
188 | } | 187 | } |
189 | 188 | ||
190 | #else | ||
191 | static inline int | ||
192 | execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq) { return 0; } | ||
193 | #endif | ||
194 | |||
195 | bool handle_irq(unsigned irq, struct pt_regs *regs) | 189 | bool handle_irq(unsigned irq, struct pt_regs *regs) |
196 | { | 190 | { |
197 | struct irq_desc *desc; | 191 | struct irq_desc *desc; |