If the 4BSD scheduler tries to schedule a thread that has been pinned or

bound to an AP before SMP has started, the system will panic when we try
to touch per-CPU state for that AP because that state has not been
initialized yet.  Fix this in the same way as ULE: place all threads in
the global run queue before SMP has started.

Reviewed by:	jhb
MFC after:	1 month
This commit is contained in:
Ryan Stone 2011-04-26 20:34:30 +00:00
parent dc0a06319e
commit 60dd73b78b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=221081

View File

@ -1246,25 +1246,27 @@ sched_add(struct thread *td, int flags)
}
TD_SET_RUNQ(td);
if (td->td_pinned != 0) {
cpu = td->td_lastcpu;
ts->ts_runq = &runq_pcpu[cpu];
single_cpu = 1;
CTR3(KTR_RUNQ,
"sched_add: Put td_sched:%p(td:%p) on cpu%d runq", ts, td,
cpu);
} else if (td->td_flags & TDF_BOUND) {
/* Find CPU from bound runq. */
KASSERT(SKE_RUNQ_PCPU(ts),
("sched_add: bound td_sched not on cpu runq"));
cpu = ts->ts_runq - &runq_pcpu[0];
single_cpu = 1;
CTR3(KTR_RUNQ,
"sched_add: Put td_sched:%p(td:%p) on cpu%d runq", ts, td,
cpu);
} else if (ts->ts_flags & TSF_AFFINITY) {
/* Find a valid CPU for our cpuset */
cpu = sched_pickcpu(td);
/*
* If SMP is started and the thread is pinned or otherwise limited to
* a specific set of CPUs, queue the thread to a per-CPU run queue.
* Otherwise, queue the thread to the global run queue.
*
* If SMP has not yet been started we must use the global run queue
* as per-CPU state may not be initialized yet and we may crash if we
* try to access the per-CPU run queues.
*/
if (smp_started && (td->td_pinned != 0 || td->td_flags & TDF_BOUND ||
ts->ts_flags & TSF_AFFINITY)) {
if (td->td_pinned != 0)
cpu = td->td_lastcpu;
else if (td->td_flags & TDF_BOUND) {
/* Find CPU from bound runq. */
KASSERT(SKE_RUNQ_PCPU(ts),
("sched_add: bound td_sched not on cpu runq"));
cpu = ts->ts_runq - &runq_pcpu[0];
} else
/* Find a valid CPU for our cpuset */
cpu = sched_pickcpu(td);
ts->ts_runq = &runq_pcpu[cpu];
single_cpu = 1;
CTR3(KTR_RUNQ,