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

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
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
/* 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 */
+15 −0
Original line number Diff line number Diff line
@@ -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)