Messages in this thread Patch in this message | | | From | Anup Patel <> | Subject | [RFC PATCH v1 3/3] RISC-V: Add handle_IPI_noregs() for irqchip drivers | Date | Thu, 11 Mar 2021 22:17:12 +0530 |
| |
We will be having IPI handled through nested interrupt controllers (such as AIA IMSIC). The irqchip driver of such nested interrupt controller will not do irq_enter() and save pt_regs because this would have been already done by the irqchip driver of the parent interrupt controller.
This patch adds handle_IPI_noregs() for nested irqchip drivers.
Signed-off-by: Anup Patel <anup.patel@wdc.com> --- arch/riscv/include/asm/smp.h | 6 ++++++ arch/riscv/kernel/smp.c | 20 ++++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/arch/riscv/include/asm/smp.h b/arch/riscv/include/asm/smp.h index 82c23e5f22f6..b31d3ec2f71b 100644 --- a/arch/riscv/include/asm/smp.h +++ b/arch/riscv/include/asm/smp.h @@ -33,6 +33,12 @@ void show_ipi_stats(struct seq_file *p, int prec); /* SMP initialization hook for setup_arch */ void __init setup_smp(void); +/* + * Called from C code, this handles an IPI assuming irq_enter() and + * pt_regs already saved by caller. + */ +void handle_IPI_noregs(void); + /* Called from C code, this handles an IPI. */ void handle_IPI(struct pt_regs *regs); diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c index 9258e3eaa8c6..19e102e2d5e6 100644 --- a/arch/riscv/kernel/smp.c +++ b/arch/riscv/kernel/smp.c @@ -144,14 +144,11 @@ void arch_irq_work_raise(void) } #endif -void handle_IPI(struct pt_regs *regs) +void handle_IPI_noregs(void) { - struct pt_regs *old_regs = set_irq_regs(regs); unsigned long *pending_ipis = &ipi_data[smp_processor_id()].bits; unsigned long *stats = ipi_data[smp_processor_id()].stats; - irq_enter(); - riscv_clear_ipi(); while (true) { @@ -162,7 +159,7 @@ void handle_IPI(struct pt_regs *regs) ops = xchg(pending_ipis, 0); if (ops == 0) - goto done; + break; if (ops & (1 << IPI_RESCHEDULE)) { stats[IPI_RESCHEDULE]++; @@ -189,9 +186,20 @@ void handle_IPI(struct pt_regs *regs) /* Order data access and bit testing. */ mb(); } +} + +void handle_IPI(struct pt_regs *regs) +{ + struct pt_regs *old_regs = set_irq_regs(regs); + + irq_enter(); + + handle_IPI_noregs(); + + riscv_clear_ipi(); -done: irq_exit(); + set_irq_regs(old_regs); } -- 2.25.1
| |