Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

+34 -1
+2 -1
arch/loongarch/include/asm/hardirq.h
··· 12 12 extern void ack_bad_irq(unsigned int irq); 13 13 #define ack_bad_irq ack_bad_irq 14 14 15 - #define NR_IPI 2 15 + #define NR_IPI 3 16 16 17 17 enum ipi_msg_type { 18 18 IPI_RESCHEDULE, 19 19 IPI_CALL_FUNCTION, 20 + IPI_IRQ_WORK, 20 21 }; 21 22 22 23 typedef struct {
+10
arch/loongarch/include/asm/irq_work.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _ASM_LOONGARCH_IRQ_WORK_H 3 + #define _ASM_LOONGARCH_IRQ_WORK_H 4 + 5 + static inline bool arch_irq_work_has_interrupt(void) 6 + { 7 + return IS_ENABLED(CONFIG_SMP); 8 + } 9 + 10 + #endif /* _ASM_LOONGARCH_IRQ_WORK_H */
+2
arch/loongarch/include/asm/smp.h
··· 69 69 #define ACTION_BOOT_CPU 0 70 70 #define ACTION_RESCHEDULE 1 71 71 #define ACTION_CALL_FUNCTION 2 72 + #define ACTION_IRQ_WORK 3 72 73 #define SMP_BOOT_CPU BIT(ACTION_BOOT_CPU) 73 74 #define SMP_RESCHEDULE BIT(ACTION_RESCHEDULE) 74 75 #define SMP_CALL_FUNCTION BIT(ACTION_CALL_FUNCTION) 76 + #define SMP_IRQ_WORK BIT(ACTION_IRQ_WORK) 75 77 76 78 struct secondary_data { 77 79 unsigned long stack;
+6
arch/loongarch/kernel/paravirt.c
··· 2 2 #include <linux/export.h> 3 3 #include <linux/types.h> 4 4 #include <linux/interrupt.h> 5 + #include <linux/irq_work.h> 5 6 #include <linux/jump_label.h> 6 7 #include <linux/kvm_para.h> 7 8 #include <linux/static_call.h> ··· 96 95 if (action & SMP_CALL_FUNCTION) { 97 96 generic_smp_call_function_interrupt(); 98 97 info->ipi_irqs[IPI_CALL_FUNCTION]++; 98 + } 99 + 100 + if (action & SMP_IRQ_WORK) { 101 + irq_work_run(); 102 + info->ipi_irqs[IPI_IRQ_WORK]++; 99 103 } 100 104 101 105 return IRQ_HANDLED;
+14
arch/loongarch/kernel/smp.c
··· 13 13 #include <linux/cpumask.h> 14 14 #include <linux/init.h> 15 15 #include <linux/interrupt.h> 16 + #include <linux/irq_work.h> 16 17 #include <linux/profile.h> 17 18 #include <linux/seq_file.h> 18 19 #include <linux/smp.h> ··· 71 70 static const char *ipi_types[NR_IPI] __tracepoint_string = { 72 71 [IPI_RESCHEDULE] = "Rescheduling interrupts", 73 72 [IPI_CALL_FUNCTION] = "Function call interrupts", 73 + [IPI_IRQ_WORK] = "IRQ work interrupts", 74 74 }; 75 75 76 76 void show_ipi_list(struct seq_file *p, int prec) ··· 219 217 } 220 218 EXPORT_SYMBOL_GPL(arch_smp_send_reschedule); 221 219 220 + #ifdef CONFIG_IRQ_WORK 221 + void arch_irq_work_raise(void) 222 + { 223 + mp_ops.send_ipi_single(smp_processor_id(), ACTION_IRQ_WORK); 224 + } 225 + #endif 226 + 222 227 static irqreturn_t loongson_ipi_interrupt(int irq, void *dev) 223 228 { 224 229 unsigned int action; ··· 241 232 if (action & SMP_CALL_FUNCTION) { 242 233 generic_smp_call_function_interrupt(); 243 234 per_cpu(irq_stat, cpu).ipi_irqs[IPI_CALL_FUNCTION]++; 235 + } 236 + 237 + if (action & SMP_IRQ_WORK) { 238 + irq_work_run(); 239 + per_cpu(irq_stat, cpu).ipi_irqs[IPI_IRQ_WORK]++; 244 240 } 245 241 246 242 return IRQ_HANDLED;