[PATCH v8 4/4] arm64: switch to irq_stack during softirq

James Morse james.morse at arm.com
Fri Dec 4 03:02:28 PST 2015


do_softirq_own_stack() was added in a previous patch, but was only used
to increase the irq_count value before __do_softirq() re-enables interrupts.

This patch adds a helper to call __do_softirq() on the irq stack. This means
do_softirq() can be called by a task that is running out of stack space,
as the work will be done on the irq_stack.

Signed-off-by: James Morse <james.morse at arm.com>
---
 arch/arm64/include/asm/irq.h |  2 ++
 arch/arm64/kernel/entry.S    | 25 +++++++++++++++++++++++++
 arch/arm64/kernel/irq.c      |  4 +---
 3 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h
index fa2a8d0e4792..6fd25ab534ca 100644
--- a/arch/arm64/include/asm/irq.h
+++ b/arch/arm64/include/asm/irq.h
@@ -31,6 +31,8 @@ DECLARE_PER_CPU(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack);
 
 extern void set_handle_irq(void (*handle_irq)(struct pt_regs *));
 
+void __do_softirq_on_irqstack(void);
+
 static inline int nr_legacy_irqs(void)
 {
 	return 0;
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 81cc5380977d..2963050e5e9e 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -779,3 +779,28 @@ ENTRY(sys_rt_sigreturn_wrapper)
 	mov	x0, sp
 	b	sys_rt_sigreturn
 ENDPROC(sys_rt_sigreturn_wrapper)
+
+ENTRY(__do_softirq_on_irqstack)
+	push	x19, lr
+	push	x25, x26
+
+	irq_stack_entry lr
+
+	/* irq_stack_entry leaves irq_count in x25 */
+	ldr	x1, [x25]
+	add	x1, x1, #1
+	str	x1, [x25]
+
+	bl	__do_softirq
+
+	ldr	x1, [x25]
+	sub	x1, x1, #1
+	str	x1, [x25]
+
+	irq_stack_exit
+
+	pop x25, x26
+	pop x19, lr
+	ret
+ENDPROC(__do_softirq_on_irqstack)
+
diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c
index ff7ebb710e51..cbf1f00993ef 100644
--- a/arch/arm64/kernel/irq.c
+++ b/arch/arm64/kernel/irq.c
@@ -75,8 +75,6 @@ void __init init_IRQ(void)
  *
  * Called with interrupts disabled, so we don't worry about moving cpu, or
  * being interrupted while modifying irq_count.
- *
- * This function doesn't actually switch stack.
  */
 void do_softirq_own_stack(void)
 {
@@ -89,6 +87,6 @@ void do_softirq_own_stack(void)
 		__do_softirq();
 		IRQ_COUNT()--;
 	} else {
-		__do_softirq();
+		__do_softirq_on_irqstack();
 	}
 }
-- 
2.6.2




More information about the linux-arm-kernel mailing list