tree 753ea613ce334c41f835f6aac21074b137d24713 parent 3829ee6b1be03d5aa3005fe7d19f30088b539836 author Andi Kleen <[EMAIL PROTECTED]> Fri, 29 Jul 2005 11:15:49 -0700 committer Linus Torvalds <[EMAIL PROTECTED]> Fri, 29 Jul 2005 11:46:02 -0700
[PATCH] x86_64: Switch to the interrupt stack when running a softirq in local_bh_enable() This avoids some potential stack overflows with very deep softirq callchains. i386 does this too. TOADD CFI annotation Signed-off-by: Andi Kleen <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]> arch/x86_64/kernel/entry.S | 12 ++++++++++++ arch/x86_64/kernel/irq.c | 19 +++++++++++++++++++ include/asm-x86_64/irq.h | 2 ++ kernel/softirq.c | 4 ++-- 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S @@ -918,3 +918,15 @@ ENTRY(machine_check) ENTRY(call_debug) zeroentry do_call_debug +ENTRY(call_softirq) + movq %gs:pda_irqstackptr,%rax + pushq %r15 + movq %rsp,%r15 + incl %gs:pda_irqcount + cmove %rax,%rsp + call __do_softirq + movq %r15,%rsp + decl %gs:pda_irqcount + popq %r15 + ret + diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c --- a/arch/x86_64/kernel/irq.c +++ b/arch/x86_64/kernel/irq.c @@ -135,3 +135,22 @@ void fixup_irqs(cpumask_t map) local_irq_disable(); } #endif + +extern void call_softirq(void); + +asmlinkage void do_softirq(void) +{ + __u32 pending; + unsigned long flags; + + if (in_interrupt()) + return; + + local_irq_save(flags); + pending = local_softirq_pending(); + /* Switch to interrupt stack */ + if (pending) + call_softirq(); + local_irq_restore(flags); +} +EXPORT_SYMBOL(do_softirq); diff --git a/include/asm-x86_64/irq.h b/include/asm-x86_64/irq.h --- a/include/asm-x86_64/irq.h +++ b/include/asm-x86_64/irq.h @@ -57,4 +57,6 @@ int handle_IRQ_event(unsigned int, struc extern void fixup_irqs(cpumask_t map); #endif +#define __ARCH_HAS_DO_SOFTIRQ 1 + #endif /* _ASM_IRQ_H */ diff --git a/kernel/softirq.c b/kernel/softirq.c --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -86,7 +86,7 @@ restart: /* Reset the pending bitmask before enabling irqs */ local_softirq_pending() = 0; - local_irq_enable(); + //local_irq_enable(); h = softirq_vec; @@ -99,7 +99,7 @@ restart: pending >>= 1; } while (pending); - local_irq_disable(); + //local_irq_disable(); pending = local_softirq_pending(); if (pending && --max_restart) - To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html