summaryrefslogtreecommitdiffstats
path: root/sys/kern/sched_ule.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/sched_ule.c')
-rw-r--r--sys/kern/sched_ule.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
index a655440..961f80d 100644
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -1037,6 +1037,14 @@ tdq_notify(struct tdq *tdq, struct thread *td)
ctd = pcpu_find(cpu)->pc_curthread;
if (!sched_shouldpreempt(pri, ctd->td_priority, 1))
return;
+
+ /*
+ * Make sure that tdq_load updated before calling this function
+ * is globally visible before we read tdq_cpu_idle. Idle thread
+ * accesses both of them without locks, and the order is important.
+ */
+ mb();
+
if (TD_IS_IDLETHREAD(ctd)) {
/*
* If the MD code has an idle wakeup routine try that before
@@ -2645,6 +2653,12 @@ sched_idletd(void *dummy)
/* Run main MD idle handler. */
tdq->tdq_cpu_idle = 1;
+ /*
+ * Make sure that tdq_cpu_idle update is globally visible
+ * before cpu_idle() read tdq_load. The order is important
+ * to avoid race with tdq_notify.
+ */
+ mb();
cpu_idle(switchcnt * 4 > sched_idlespinthresh);
tdq->tdq_cpu_idle = 0;
OpenPOWER on IntegriCloud