There are two IRQ stacks: softirq_ctx and hardirq_ctx do_softirq_own_stack() switches stack to softirq_ctx do_IRQ() switches stack to hardirq_ctx
However, when soft and hard IRQs are nested, only one of the two stacks is used: - When on softirq stack, do_IRQ() doesn't switch to hardirq stack. - irq_exit() runs softirqs on hardirq stack. There is no added value in having two IRQ stacks as only one is used when hard and soft irqs are nested. Remove softirq_ctx and use hardirq_ctx for both hard and soft IRQs. Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr> --- arch/powerpc/include/asm/irq.h | 1 - arch/powerpc/kernel/irq.c | 8 +++----- arch/powerpc/kernel/process.c | 4 ---- arch/powerpc/kernel/setup_32.c | 4 +--- arch/powerpc/kernel/setup_64.c | 4 +--- 5 files changed, 5 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h index e4a92f0b4ad4..7cb2c76aa3ed 100644 --- a/arch/powerpc/include/asm/irq.h +++ b/arch/powerpc/include/asm/irq.h @@ -54,7 +54,6 @@ extern void *mcheckirq_ctx[NR_CPUS]; * Per-cpu stacks for handling hard and soft interrupts. */ extern void *hardirq_ctx[NR_CPUS]; -extern void *softirq_ctx[NR_CPUS]; #ifdef CONFIG_PPC64 void call_do_softirq(void *sp); diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index a1122ef4a16c..3af0d1897354 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -680,15 +680,14 @@ void __do_irq(struct pt_regs *regs) void do_IRQ(struct pt_regs *regs) { - void *cursp, *irqsp, *sirqsp; + void *cursp, *irqsp; /* Switch to the irq stack to handle this */ cursp = (void *)(stack_pointer() & ~(THREAD_SIZE - 1)); irqsp = hardirq_ctx[raw_smp_processor_id()]; - sirqsp = softirq_ctx[raw_smp_processor_id()]; /* Already there ? Otherwise switch stack and call */ - if (unlikely(cursp == irqsp || cursp == sirqsp)) + if (unlikely(cursp == irqsp)) __do_irq(regs); else call_do_irq(regs, irqsp); @@ -706,12 +705,11 @@ void *dbgirq_ctx[NR_CPUS] __read_mostly; void *mcheckirq_ctx[NR_CPUS] __read_mostly; #endif -void *softirq_ctx[NR_CPUS] __read_mostly; void *hardirq_ctx[NR_CPUS] __read_mostly; void do_softirq_own_stack(void) { - call_do_softirq(softirq_ctx[smp_processor_id()]); + call_do_softirq(hardirq_ctx[smp_processor_id()]); } irq_hw_number_t virq_to_hw(unsigned int virq) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 49d0ebf28ab9..be3e64cf28b4 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1963,10 +1963,6 @@ static inline int valid_irq_stack(unsigned long sp, struct task_struct *p, if (sp >= stack_page && sp <= stack_page + THREAD_SIZE - nbytes) return 1; - stack_page = (unsigned long)softirq_ctx[cpu]; - if (sp >= stack_page && sp <= stack_page + THREAD_SIZE - nbytes) - return 1; - return 0; } diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index dcffe927f5b9..8752aae06177 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -155,10 +155,8 @@ void __init irqstack_early_init(void) /* interrupt stacks must be in lowmem, we get that for free on ppc32 * as the memblock is limited to lowmem by default */ - for_each_possible_cpu(i) { - softirq_ctx[i] = alloc_stack(); + for_each_possible_cpu(i) hardirq_ctx[i] = alloc_stack(); - } } #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 6104917a282d..96ee7627eda6 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -652,10 +652,8 @@ void __init irqstack_early_init(void) * cannot afford to take SLB misses on them. They are not * accessed in realmode. */ - for_each_possible_cpu(i) { - softirq_ctx[i] = alloc_stack(limit, i); + for_each_possible_cpu(i) hardirq_ctx[i] = alloc_stack(limit, i); - } } #ifdef CONFIG_PPC_BOOK3E -- 2.13.3