Commit 29844792 authored by Greentime Hu's avatar Greentime Hu Committed by Palmer Dabbelt

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: default avatarGreentime Hu <greentime.hu@sifive.com>
Signed-off-by: default avatarPalmer Dabbelt <palmerdabbelt@google.com>
parent 3c469798
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_RISCV_IRQ_WORK_H
#define _ASM_RISCV_IRQ_WORK_H
static inline bool arch_irq_work_has_interrupt(void)
{
return true;
}
extern void arch_irq_work_raise(void);
#endif /* _ASM_RISCV_IRQ_WORK_H */
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/irq_work.h>
#include <asm/clint.h> #include <asm/clint.h>
#include <asm/sbi.h> #include <asm/sbi.h>
...@@ -26,6 +27,7 @@ enum ipi_message_type { ...@@ -26,6 +27,7 @@ enum ipi_message_type {
IPI_RESCHEDULE, IPI_RESCHEDULE,
IPI_CALL_FUNC, IPI_CALL_FUNC,
IPI_CPU_STOP, IPI_CPU_STOP,
IPI_IRQ_WORK,
IPI_MAX IPI_MAX
}; };
...@@ -123,6 +125,13 @@ static inline void clear_ipi(void) ...@@ -123,6 +125,13 @@ static inline void clear_ipi(void)
clint_clear_ipi(cpuid_to_hartid_map(smp_processor_id())); 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) void handle_IPI(struct pt_regs *regs)
{ {
struct pt_regs *old_regs = set_irq_regs(regs); struct pt_regs *old_regs = set_irq_regs(regs);
...@@ -158,6 +167,11 @@ void handle_IPI(struct pt_regs *regs) ...@@ -158,6 +167,11 @@ void handle_IPI(struct pt_regs *regs)
ipi_stop(); ipi_stop();
} }
if (ops & (1 << IPI_IRQ_WORK)) {
stats[IPI_IRQ_WORK]++;
irq_work_run();
}
BUG_ON((ops >> IPI_MAX) != 0); BUG_ON((ops >> IPI_MAX) != 0);
/* Order data access and bit testing. */ /* Order data access and bit testing. */
...@@ -173,6 +187,7 @@ static const char * const ipi_names[] = { ...@@ -173,6 +187,7 @@ static const char * const ipi_names[] = {
[IPI_RESCHEDULE] = "Rescheduling interrupts", [IPI_RESCHEDULE] = "Rescheduling interrupts",
[IPI_CALL_FUNC] = "Function call interrupts", [IPI_CALL_FUNC] = "Function call interrupts",
[IPI_CPU_STOP] = "CPU stop interrupts", [IPI_CPU_STOP] = "CPU stop interrupts",
[IPI_IRQ_WORK] = "IRQ work interrupts",
}; };
void show_ipi_stats(struct seq_file *p, int prec) void show_ipi_stats(struct seq_file *p, int prec)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment