diff options
author | Greentime Hu <greentime.hu@sifive.com> | 2020-06-24 17:03:15 +0800 |
---|---|---|
committer | Palmer Dabbelt <palmerdabbelt@google.com> | 2020-07-30 11:37:33 -0700 |
commit | 298447928bb1c6bda9ad6f2ce3958d15c329816b (patch) | |
tree | 1c80e10c6a2bb076ea09dd0bf807deaf01427902 /arch/riscv/kernel | |
parent | 3c46979829824da5af8766d89fa877976bdae884 (diff) |
riscv: Support irq_work via self IPIs
Support for arch_irq_work_raise() and arch_irq_work_has_interrupt() was
missing from riscv (a prerequisite for FULL_NOHZ).
Signed-off-by: Greentime Hu <greentime.hu@sifive.com>
Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
Diffstat (limited to 'arch/riscv/kernel')
-rw-r--r-- | arch/riscv/kernel/smp.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c index b1d4f452f843..554b0fb47060 100644 --- a/arch/riscv/kernel/smp.c +++ b/arch/riscv/kernel/smp.c @@ -16,6 +16,7 @@ #include <linux/sched.h> #include <linux/seq_file.h> #include <linux/delay.h> +#include <linux/irq_work.h> #include <asm/clint.h> #include <asm/sbi.h> @@ -26,6 +27,7 @@ enum ipi_message_type { IPI_RESCHEDULE, IPI_CALL_FUNC, IPI_CPU_STOP, + IPI_IRQ_WORK, IPI_MAX }; @@ -123,6 +125,13 @@ static inline void clear_ipi(void) clint_clear_ipi(cpuid_to_hartid_map(smp_processor_id())); } +#ifdef CONFIG_IRQ_WORK +void arch_irq_work_raise(void) +{ + send_ipi_single(smp_processor_id(), IPI_IRQ_WORK); +} +#endif + void handle_IPI(struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); @@ -158,6 +167,11 @@ void handle_IPI(struct pt_regs *regs) ipi_stop(); } + if (ops & (1 << IPI_IRQ_WORK)) { + stats[IPI_IRQ_WORK]++; + irq_work_run(); + } + BUG_ON((ops >> IPI_MAX) != 0); /* Order data access and bit testing. */ @@ -173,6 +187,7 @@ static const char * const ipi_names[] = { [IPI_RESCHEDULE] = "Rescheduling interrupts", [IPI_CALL_FUNC] = "Function call interrupts", [IPI_CPU_STOP] = "CPU stop interrupts", + [IPI_IRQ_WORK] = "IRQ work interrupts", }; void show_ipi_stats(struct seq_file *p, int prec) |