diff options
author | Qi Zheng <zhengqi.arch@bytedance.com> | 2022-08-15 14:47:39 +0200 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2022-09-09 20:01:38 +0200 |
commit | 8eb858c44b98e0326bb32fca34ae671995cd73bb (patch) | |
tree | 0d31b053090bfd35ecd4b502d8b169132548e484 /arch/arm64/kernel/irq.c | |
parent | arm64: compat: Implement misalignment fixups for multiword loads (diff) | |
download | linux-8eb858c44b98e0326bb32fca34ae671995cd73bb.tar.xz linux-8eb858c44b98e0326bb32fca34ae671995cd73bb.zip |
arm64: run softirqs on the per-CPU IRQ stack
Currently arm64 supports per-CPU IRQ stack, but softirqs
are still handled in the task context.
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 softirqs
on the IRQ stack as well.
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20220815124739.15948-1-zhengqi.arch@bytedance.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/kernel/irq.c')
-rw-r--r-- | arch/arm64/kernel/irq.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c index bda49430c9ea..38dbd3828f13 100644 --- a/arch/arm64/kernel/irq.c +++ b/arch/arm64/kernel/irq.c @@ -21,7 +21,9 @@ #include <linux/seq_file.h> #include <linux/vmalloc.h> #include <asm/daifflags.h> +#include <asm/exception.h> #include <asm/vmap_stack.h> +#include <asm/softirq_stack.h> /* Only access this in an NMI enter/exit */ DEFINE_PER_CPU(struct nmi_ctx, nmi_contexts); @@ -71,6 +73,18 @@ static void init_irq_stacks(void) } #endif +#ifndef CONFIG_PREEMPT_RT +static void ____do_softirq(struct pt_regs *regs) +{ + __do_softirq(); +} + +void do_softirq_own_stack(void) +{ + call_on_irq_stack(NULL, ____do_softirq); +} +#endif + static void default_handle_irq(struct pt_regs *regs) { panic("IRQ taken without a root IRQ handler\n"); |