Date: Sun, 14 Aug 2016 22:58:07 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r304105 - projects/powernv/kern Message-ID: <201608142258.u7EMw7Ym033028@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201608142258.u7EMw7Ym033028>