From 7ed09a6778d3fdd5d0484c9a60f4aa48f7ffbb83 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Mon, 26 Apr 2021 19:10:41 -0500 Subject: [PATCH] powerpc: Rework IPI message processing Summary: There's no need to use a while loop in the IPI handler, the message list is cached once and processed. Instead, since the existing code calls ffs(), sort the handlers, and use a simple 'if' sequence. Reviewed By: nwhitehorn Differential Revision: https://reviews.freebsd.org/D30018 --- sys/powerpc/powerpc/mp_machdep.c | 68 +++++++++++++++----------------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c index a9f2aaf36ad..627cde77adb 100644 --- a/sys/powerpc/powerpc/mp_machdep.c +++ b/sys/powerpc/powerpc/mp_machdep.c @@ -299,49 +299,43 @@ powerpc_ipi_handler(void *arg) { u_int cpuid; uint32_t ipimask; - int msg; CTR2(KTR_SMP, "%s: MSR 0x%08x", __func__, mfmsr()); ipimask = atomic_readandclear_32(&(pcpup->pc_ipimask)); if (ipimask == 0) return (FILTER_STRAY); - while ((msg = ffs(ipimask) - 1) != -1) { - ipimask &= ~(1u << msg); - switch (msg) { - case IPI_AST: - CTR1(KTR_SMP, "%s: IPI_AST", __func__); - break; - case IPI_PREEMPT: - CTR1(KTR_SMP, "%s: IPI_PREEMPT", __func__); - sched_preempt(curthread); - break; - case IPI_RENDEZVOUS: - CTR1(KTR_SMP, "%s: IPI_RENDEZVOUS", __func__); - smp_rendezvous_action(); - break; - case IPI_STOP: - - /* - * IPI_STOP_HARD is mapped to IPI_STOP so it is not - * necessary to add such case in the switch. - */ - CTR1(KTR_SMP, "%s: IPI_STOP or IPI_STOP_HARD (stop)", - __func__); - cpuid = PCPU_GET(cpuid); - savectx(&stoppcbs[cpuid]); - CPU_SET_ATOMIC(cpuid, &stopped_cpus); - while (!CPU_ISSET(cpuid, &started_cpus)) - cpu_spinwait(); - CPU_CLR_ATOMIC(cpuid, &stopped_cpus); - CPU_CLR_ATOMIC(cpuid, &started_cpus); - CTR1(KTR_SMP, "%s: IPI_STOP (restart)", __func__); - break; - case IPI_HARDCLOCK: - CTR1(KTR_SMP, "%s: IPI_HARDCLOCK", __func__); - hardclockintr(); - break; - } + if (ipimask & (1 << IPI_AST)) { + CTR1(KTR_SMP, "%s: IPI_AST", __func__); + } + if (ipimask & (1 << IPI_PREEMPT)) { + CTR1(KTR_SMP, "%s: IPI_PREEMPT", __func__); + sched_preempt(curthread); + } + if (ipimask & (1 << IPI_RENDEZVOUS)) { + CTR1(KTR_SMP, "%s: IPI_RENDEZVOUS", __func__); + smp_rendezvous_action(); + } + if (ipimask & (1 << IPI_STOP)) { + + /* + * IPI_STOP_HARD is mapped to IPI_STOP so it is not + * necessary to add such case. + */ + CTR1(KTR_SMP, "%s: IPI_STOP or IPI_STOP_HARD (stop)", + __func__); + cpuid = PCPU_GET(cpuid); + savectx(&stoppcbs[cpuid]); + CPU_SET_ATOMIC(cpuid, &stopped_cpus); + while (!CPU_ISSET(cpuid, &started_cpus)) + cpu_spinwait(); + CPU_CLR_ATOMIC(cpuid, &stopped_cpus); + CPU_CLR_ATOMIC(cpuid, &started_cpus); + CTR1(KTR_SMP, "%s: IPI_STOP (restart)", __func__); + } + if (ipimask & (1 << IPI_HARDCLOCK)) { + CTR1(KTR_SMP, "%s: IPI_HARDCLOCK", __func__); + hardclockintr(); } return (FILTER_HANDLED); -- 2.45.0