diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2019-05-06 12:56:31 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2019-05-06 12:56:31 +0000 |
commit | d117054c8a6eed492576a3cb544bcba6a4333083 (patch) | |
tree | 52fd520e4478f258eb4441268314b8cd9a4cb75f /sys/arch | |
parent | f549c0d3e21ae9c06a3de3ce324df28759a896a2 (diff) |
Issue write-write barrier before sending IPI on mips64
The barrier ensures that any lockless state changes become visible
to other CPUs before the IPI is sent. Otherwise, a receiving CPU
might still observe an old state when it processes the interrupt.
OK guenther@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/mips64/mips64/ipifuncs.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/sys/arch/mips64/mips64/ipifuncs.c b/sys/arch/mips64/mips64/ipifuncs.c index 2618f19947a..ed66352d0bf 100644 --- a/sys/arch/mips64/mips64/ipifuncs.c +++ b/sys/arch/mips64/mips64/ipifuncs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipifuncs.c,v 1.20 2019/03/16 06:23:03 visa Exp $ */ +/* $OpenBSD: ipifuncs.c,v 1.21 2019/05/06 12:56:30 visa Exp $ */ /* $NetBSD: ipifuncs.c,v 1.40 2008/04/28 20:23:10 martin Exp $ */ /*- @@ -122,11 +122,8 @@ mips64_ipi_intr(void *arg) return 1; } -/* - * Send an interprocessor interrupt. - */ -void -mips64_send_ipi(unsigned int cpuid, unsigned int ipimask) +static void +do_send_ipi(unsigned int cpuid, unsigned int ipimask) { #ifdef DEBUG if (cpuid >= CPU_MAXID || get_cpu_info(cpuid) == NULL) @@ -141,6 +138,21 @@ mips64_send_ipi(unsigned int cpuid, unsigned int ipimask) } /* + * Send an interprocessor interrupt. + */ +void +mips64_send_ipi(unsigned int cpuid, unsigned int ipimask) +{ + /* + * Ensure that preceding stores are visible to other CPUs + * before sending the IPI. + */ + membar_producer(); + + do_send_ipi(cpuid, ipimask); +} + +/* * Send an IPI to all in the list but ourselves. */ void @@ -151,11 +163,17 @@ mips64_multicast_ipi(unsigned int cpumask, unsigned int ipimask) cpumask &= ~(1 << cpu_number()); + /* + * Ensure that preceding stores are visible to other CPUs + * before sending the IPI. + */ + membar_producer(); + CPU_INFO_FOREACH(cii, ci) { if (!(cpumask & (1UL << ci->ci_cpuid)) || !cpuset_isset(&cpus_running, ci)) continue; - mips64_send_ipi(ci->ci_cpuid, ipimask); + do_send_ipi(ci->ci_cpuid, ipimask); } } @@ -218,9 +236,6 @@ smp_rendezvous_cpus(unsigned long map, smp_rv_waiters[0] = 0; smp_rv_waiters[1] = 0; - /* Ensure the parameters are visible to other CPUs. */ - membar_producer(); - /* signal other processors, which will enter the IPI with interrupts off */ mips64_multicast_ipi(map, MIPS64_IPI_RENDEZVOUS); |