Commit 9974f857 authored by Ard Biesheuvel's avatar Ard Biesheuvel
Browse files

ARM: run softirqs on the per-CPU IRQ stack



Now that we have enabled IRQ stacks, any softIRQs that are handled over
the back of a hard IRQ will run from the IRQ stack as well. However, any
synchronous softirq processing that happens when re-enabling softIRQs
from task context will still execute on that task's stack.

Since any call to local_bh_enable() at any level in the task's call
stack may trigger a softIRQ processing run, which could potentially
cause a task stack overflow if the combined stack footprints exceed the
stack's size, let's run these synchronous invocations of do_softirq() on
the IRQ stack as well.

Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
Reviewed-by: default avatarArnd Bergmann <arnd@arndb.de>
Acked-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Tested-by: default avatarKeith Packard <keithpac@amazon.com>
Tested-by: default avatarMarc Zyngier <maz@kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin@arm.com> # ARMv7M
parent 0b78f2e9
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1169,6 +1169,8 @@ config CURRENT_POINTER_IN_TPIDRURO
config IRQSTACKS
	def_bool y
	depends on GENERIC_IRQ_MULTI_HANDLER && THREAD_INFO_IN_TASK
	select HAVE_IRQ_EXIT_ON_IRQ_STACK
	select HAVE_SOFTIRQ_ON_OWN_STACK

config ARM_CPU_TOPOLOGY
	bool "Support cpu topology definition"
+14 −0
Original line number Diff line number Diff line
@@ -36,11 +36,14 @@
#include <asm/hardware/cache-l2x0.h>
#include <asm/hardware/cache-uniphier.h>
#include <asm/outercache.h>
#include <asm/softirq_stack.h>
#include <asm/exception.h>
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>

#include "reboot.h"

unsigned long irq_err_count;

#ifdef CONFIG_IRQSTACKS
@@ -60,6 +63,17 @@ static void __init init_irq_stacks(void)
	}
}

static void ____do_softirq(void *arg)
{
	__do_softirq();
}

void do_softirq_own_stack(void)
{
	call_with_stack(____do_softirq, NULL,
			__this_cpu_read(irq_stack_ptr));
}

#endif

int arch_show_interrupts(struct seq_file *p, int prec)