diff options
| author | Eric Sandeen <sandeen@sgi.com> | 2006-06-26 08:00:05 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 13:48:22 -0400 |
| commit | 4961f10e2205d0ededa291e12ec634efc58aa93c (patch) | |
| tree | 12aec4e392f3cbbdca69ab65fc41816430cb3b37 | |
| parent | a4cffb6444c327677f901323ecf1a13d6bd2df3f (diff) | |
[PATCH] x86_64: (resend) x86_64 stack overflow debugging
Take two, now without spurious whitespace :( Applies to git & 2.6.17-rc6
CONFIG_DEBUG_STACKOVERFLOW existed for x86_64 in 2.4, but seems to have gone AWOL in 2.6.
I've pretty much just copied this over from the 2.4 code, with
appropriate tweaks for the 2.6 kernel, plus a bugfix. I'd personally
rather see it printed out the way other arches do it, i.e.
bytes-remaining-until-overflow, rather than having to do the subtraction
yourself. Also, only 128 bytes remaining seems awfully late to issue a
warning. But I'll start here :)
Signed-off-by: Eric Sandeen <sandeen@sgi.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | arch/x86_64/Kconfig.debug | 7 | ||||
| -rw-r--r-- | arch/x86_64/kernel/irq.c | 28 |
2 files changed, 34 insertions, 1 deletions
diff --git a/arch/x86_64/Kconfig.debug b/arch/x86_64/Kconfig.debug index 0226f08be874..087a04868b25 100644 --- a/arch/x86_64/Kconfig.debug +++ b/arch/x86_64/Kconfig.debug | |||
| @@ -35,6 +35,13 @@ config IOMMU_LEAK | |||
| 35 | Add a simple leak tracer to the IOMMU code. This is useful when you | 35 | Add a simple leak tracer to the IOMMU code. This is useful when you |
| 36 | are debugging a buggy device driver that leaks IOMMU mappings. | 36 | are debugging a buggy device driver that leaks IOMMU mappings. |
| 37 | 37 | ||
| 38 | config DEBUG_STACKOVERFLOW | ||
| 39 | bool "Check for stack overflows" | ||
| 40 | depends on DEBUG_KERNEL | ||
| 41 | help | ||
| 42 | This option will cause messages to be printed if free stack space | ||
| 43 | drops below a certain limit. | ||
| 44 | |||
| 38 | #config X86_REMOTE_DEBUG | 45 | #config X86_REMOTE_DEBUG |
| 39 | # bool "kgdb debugging stub" | 46 | # bool "kgdb debugging stub" |
| 40 | 47 | ||
diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c index 207ecdc39822..59518d4d4358 100644 --- a/arch/x86_64/kernel/irq.c +++ b/arch/x86_64/kernel/irq.c | |||
| @@ -26,6 +26,30 @@ atomic_t irq_mis_count; | |||
| 26 | #endif | 26 | #endif |
| 27 | #endif | 27 | #endif |
| 28 | 28 | ||
| 29 | #ifdef CONFIG_DEBUG_STACKOVERFLOW | ||
| 30 | /* | ||
| 31 | * Probabilistic stack overflow check: | ||
| 32 | * | ||
| 33 | * Only check the stack in process context, because everything else | ||
| 34 | * runs on the big interrupt stacks. Checking reliably is too expensive, | ||
| 35 | * so we just check from interrupts. | ||
| 36 | */ | ||
| 37 | static inline void stack_overflow_check(struct pt_regs *regs) | ||
| 38 | { | ||
| 39 | u64 curbase = (u64) current->thread_info; | ||
| 40 | static unsigned long warned = -60*HZ; | ||
| 41 | |||
| 42 | if (regs->rsp >= curbase && regs->rsp <= curbase + THREAD_SIZE && | ||
| 43 | regs->rsp < curbase + sizeof(struct thread_info) + 128 && | ||
| 44 | time_after(jiffies, warned + 60*HZ)) { | ||
| 45 | printk("do_IRQ: %s near stack overflow (cur:%Lx,rsp:%lx)\n", | ||
| 46 | current->comm, curbase, regs->rsp); | ||
| 47 | show_stack(NULL,NULL); | ||
| 48 | warned = jiffies; | ||
| 49 | } | ||
| 50 | } | ||
| 51 | #endif | ||
| 52 | |||
| 29 | /* | 53 | /* |
| 30 | * Generic, controller-independent functions: | 54 | * Generic, controller-independent functions: |
| 31 | */ | 55 | */ |
| @@ -96,7 +120,9 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs) | |||
| 96 | 120 | ||
| 97 | exit_idle(); | 121 | exit_idle(); |
| 98 | irq_enter(); | 122 | irq_enter(); |
| 99 | 123 | #ifdef CONFIG_DEBUG_STACKOVERFLOW | |
| 124 | stack_overflow_check(regs); | ||
| 125 | #endif | ||
| 100 | __do_IRQ(irq, regs); | 126 | __do_IRQ(irq, regs); |
| 101 | irq_exit(); | 127 | irq_exit(); |
| 102 | 128 | ||
