diff options
author | Eric Sandeen <sandeen@sgi.com> | 2006-06-26 14:00:05 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 10:48:22 -0700 |
commit | 4961f10e2205d0ededa291e12ec634efc58aa93c (patch) | |
tree | 12aec4e392f3cbbdca69ab65fc41816430cb3b37 /arch/x86_64/kernel/irq.c | |
parent | a4cffb6444c327677f901323ecf1a13d6bd2df3f (diff) | |
download | blackbird-op-linux-4961f10e2205d0ededa291e12ec634efc58aa93c.tar.gz blackbird-op-linux-4961f10e2205d0ededa291e12ec634efc58aa93c.zip |
[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>
Diffstat (limited to 'arch/x86_64/kernel/irq.c')
-rw-r--r-- | arch/x86_64/kernel/irq.c | 28 |
1 files changed, 27 insertions, 1 deletions
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; #endif #endif +#ifdef CONFIG_DEBUG_STACKOVERFLOW +/* + * Probabilistic stack overflow check: + * + * Only check the stack in process context, because everything else + * runs on the big interrupt stacks. Checking reliably is too expensive, + * so we just check from interrupts. + */ +static inline void stack_overflow_check(struct pt_regs *regs) +{ + u64 curbase = (u64) current->thread_info; + static unsigned long warned = -60*HZ; + + if (regs->rsp >= curbase && regs->rsp <= curbase + THREAD_SIZE && + regs->rsp < curbase + sizeof(struct thread_info) + 128 && + time_after(jiffies, warned + 60*HZ)) { + printk("do_IRQ: %s near stack overflow (cur:%Lx,rsp:%lx)\n", + current->comm, curbase, regs->rsp); + show_stack(NULL,NULL); + warned = jiffies; + } +} +#endif + /* * Generic, controller-independent functions: */ @@ -96,7 +120,9 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs) exit_idle(); irq_enter(); - +#ifdef CONFIG_DEBUG_STACKOVERFLOW + stack_overflow_check(regs); +#endif __do_IRQ(irq, regs); irq_exit(); |