diff options
author | Huacai Chen <chenhuacai@loongson.cn> | 2024-07-20 16:40:58 +0200 |
---|---|---|
committer | Huacai Chen <chenhuacai@loongson.cn> | 2024-07-20 16:40:58 +0200 |
commit | 08f417db702c5b05150b3851af7186fee96ddd46 (patch) | |
tree | 7268a740e178602b1854e2480a9a8fc1fd602184 /arch/loongarch/kernel/smp.c | |
parent | LoongArch: Always enumerate MADT and setup logical-physical CPU mapping (diff) | |
download | linux-08f417db702c5b05150b3851af7186fee96ddd46.tar.xz linux-08f417db702c5b05150b3851af7186fee96ddd46.zip |
LoongArch: Add irq_work support via self IPIs
Add irq_work support for LoongArch via self IPIs. This make it possible
to run works in hardware interrupt context, which is a prerequisite for
NOHZ_FULL.
Implement:
- arch_irq_work_raise()
- arch_irq_work_has_interrupt()
Reviewed-by: Guo Ren <guoren@kernel.org>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Diffstat (limited to '')
-rw-r--r-- | arch/loongarch/kernel/smp.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c index 03b2b7669cf5..ca405ab86aae 100644 --- a/arch/loongarch/kernel/smp.c +++ b/arch/loongarch/kernel/smp.c @@ -13,6 +13,7 @@ #include <linux/cpumask.h> #include <linux/init.h> #include <linux/interrupt.h> +#include <linux/irq_work.h> #include <linux/profile.h> #include <linux/seq_file.h> #include <linux/smp.h> @@ -70,6 +71,7 @@ static DEFINE_PER_CPU(int, cpu_state); static const char *ipi_types[NR_IPI] __tracepoint_string = { [IPI_RESCHEDULE] = "Rescheduling interrupts", [IPI_CALL_FUNCTION] = "Function call interrupts", + [IPI_IRQ_WORK] = "IRQ work interrupts", }; void show_ipi_list(struct seq_file *p, int prec) @@ -217,6 +219,13 @@ void arch_smp_send_reschedule(int cpu) } EXPORT_SYMBOL_GPL(arch_smp_send_reschedule); +#ifdef CONFIG_IRQ_WORK +void arch_irq_work_raise(void) +{ + mp_ops.send_ipi_single(smp_processor_id(), ACTION_IRQ_WORK); +} +#endif + static irqreturn_t loongson_ipi_interrupt(int irq, void *dev) { unsigned int action; @@ -234,6 +243,11 @@ static irqreturn_t loongson_ipi_interrupt(int irq, void *dev) per_cpu(irq_stat, cpu).ipi_irqs[IPI_CALL_FUNCTION]++; } + if (action & SMP_IRQ_WORK) { + irq_work_run(); + per_cpu(irq_stat, cpu).ipi_irqs[IPI_IRQ_WORK]++; + } + return IRQ_HANDLED; } |