summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2019-05-16 13:52:48 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2019-05-16 13:52:48 +0000
commit2dec407cd5245c6407ac374404a8f58d9751e246 (patch)
treea7f75ea1a05001ffecbabbfdc9f923042caf3ddd
parent1b68ae694a3627fa8c926fea31651ed2fafbd75e (diff)
Remove incorrect optimization. The current logic for skipping idle CPUs
does not establish strong enough ordering between CPUs. Consequently, smr_grace_wait() might incorrectly skip a CPU and invoke an SMR callback too early. Prompted by haesbaert@
-rw-r--r--sys/kern/kern_smr.c24
-rw-r--r--sys/sys/sched.h5
2 files changed, 4 insertions, 25 deletions
diff --git a/sys/kern/kern_smr.c b/sys/kern/kern_smr.c
index eadf828cfd6..50e378c1d2d 100644
--- a/sys/kern/kern_smr.c
+++ b/sys/kern/kern_smr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_smr.c,v 1.2 2019/05/14 03:27:43 visa Exp $ */
+/* $OpenBSD: kern_smr.c,v 1.3 2019/05/16 13:52:47 visa Exp $ */
/*
* Copyright (c) 2019 Visa Hankala
@@ -29,9 +29,6 @@
#include <machine/cpu.h>
-#define SMR_ACTIVE 0x01
-#define SMR_ENTERED 0x02
-
#define SMR_PAUSE 100 /* pause between rounds in msec */
void smr_create_thread(void *);
@@ -149,8 +146,6 @@ smr_grace_wait(void)
CPU_INFO_FOREACH(cii, ci) {
if (ci == ci_start)
continue;
- if (smr_cpu_is_idle(ci) && ci->ci_schedstate.spc_insmr == 0)
- continue;
sched_peg_curproc(ci);
}
atomic_clearbits_int(&curproc->p_flag, P_CPUPEG);
@@ -166,22 +161,11 @@ smr_wakeup(void *arg)
void
smr_read_enter(void)
{
- struct cpu_info *ci = curcpu();
- struct schedstate_percpu *spc = &ci->ci_schedstate;
-
#ifdef DIAGNOSTIC
+ struct schedstate_percpu *spc = &curcpu()->ci_schedstate;
+
spc->spc_smrdepth++;
#endif
-
- if (smr_cpu_is_idle(ci) && (spc->spc_insmr & SMR_ENTERED) == 0) {
- /*
- * Activate in two steps in order not to miss the memory
- * barrier with nested interrupts.
- */
- spc->spc_insmr = SMR_ACTIVE;
- membar_enter();
- spc->spc_insmr = SMR_ACTIVE | SMR_ENTERED;
- }
}
void
@@ -230,8 +214,6 @@ smr_idle(void)
SMR_ASSERT_NONCRITICAL();
- spc->spc_insmr = 0;
-
if (spc->spc_ndeferred > 0)
smr_dispatch(spc);
}
diff --git a/sys/sys/sched.h b/sys/sys/sched.h
index 30b93b4bd3c..d1ef56b7a9e 100644
--- a/sys/sys/sched.h
+++ b/sys/sys/sched.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sched.h,v 1.51 2019/02/26 14:24:21 visa Exp $ */
+/* $OpenBSD: sched.h,v 1.52 2019/05/16 13:52:47 visa Exp $ */
/* $NetBSD: sched.h,v 1.2 1999/02/28 18:14:58 ross Exp $ */
/*-
@@ -119,9 +119,6 @@ struct schedstate_percpu {
u_int spc_smrdepth; /* level of smr nesting */
u_char spc_smrexpedite; /* if set, dispatch smr entries
* without delay */
- volatile u_char spc_insmr; /* if set, CPU entered smr critical
- * section from interrupt context
- * that preempted idle state */
};
struct cpustats {