svn commit: r304105 - projects/powernv/kern
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Sun Aug 14 22:58:08 UTC 2016
Author: nwhitehorn
Date: Sun Aug 14 22:58:06 2016
New Revision: 304105
URL: https://svnweb.freebsd.org/changeset/base/304105
Log:
Fix yet another bug when the system has no CPU 0. When created, threads
were implicitly assigned to CPU 0. This had no practical effect since a real
CPU was chosen immediately by the scheduler. However, on systems without a
CPU 0, sched_ule attempted to access the scheduler queue of the "old" CPU
when assigned the initial choice of the old one. This caused an attempt to
use illegal memory and a crash (or, more usually, a deadlock). Fix this by
assigned new threads to the BSP explicitly and add some asserts to see that
this problem does not recur.
Modified:
projects/powernv/kern/sched_ule.c
Modified: projects/powernv/kern/sched_ule.c
==============================================================================
--- projects/powernv/kern/sched_ule.c Sun Aug 14 22:43:48 2016 (r304104)
+++ projects/powernv/kern/sched_ule.c Sun Aug 14 22:58:06 2016 (r304105)
@@ -1224,6 +1224,8 @@ sched_pickcpu(struct thread *td, int fla
self = PCPU_GET(cpuid);
ts = td_get_sched(td);
+ KASSERT(!CPU_ABSENT(ts->ts_cpu), ("sched_pickcpu: Start scheduler on "
+ "absent CPU %d for thread %s.", ts->ts_cpu, td->td_name));
if (smp_started == 0)
return (self);
/*
@@ -1294,6 +1296,7 @@ sched_pickcpu(struct thread *td, int fla
if (cpu == -1)
cpu = sched_lowest(cpu_top, mask, -1, INT_MAX, ts->ts_cpu);
KASSERT(cpu != -1, ("sched_pickcpu: Failed to find a cpu."));
+ KASSERT(!CPU_ABSENT(cpu), ("sched_pickcpu: Picked absent CPU %d.", cpu));
/*
* Compare the lowest loaded cpu to current cpu.
*/
@@ -1400,6 +1403,7 @@ sched_setup(void *dummy)
/* Add thread0's load since it's running. */
TDQ_LOCK(tdq);
+ td_get_sched(&thread0)->ts_cpu = curcpu; /* Something valid to start */
thread0.td_lock = TDQ_LOCKPTR(TDQ_SELF());
tdq_load_add(tdq, &thread0);
tdq->tdq_lowpri = thread0.td_priority;
@@ -1833,6 +1837,9 @@ sched_switch_migrate(struct tdq *tdq, st
{
struct tdq *tdn;
+ KASSERT(!CPU_ABSENT(td_get_sched(td)->ts_cpu), ("sched_switch_migrate: "
+ "thread %s queued on absent CPU %d.", td->td_name,
+ td_get_sched(td)->ts_cpu));
tdn = TDQ_CPU(td_get_sched(td)->ts_cpu);
#ifdef SMP
tdq_load_rem(tdq, td);
@@ -2425,6 +2432,7 @@ sched_add(struct thread *td, int flags)
* Pick the destination cpu and if it isn't ours transfer to the
* target cpu.
*/
+ td_get_sched(td)->ts_cpu = curcpu; /* Pick something valid to start */
cpu = sched_pickcpu(td, flags);
tdq = sched_setcpu(td, cpu, flags);
tdq_add(tdq, td, flags);
More information about the svn-src-projects
mailing list