svn commit: r212667 - stable/7/sys/kern

Matthew D Fleming mdf at FreeBSD.org
Wed Sep 15 15:55:59 UTC 2010


Author: mdf
Date: Wed Sep 15 15:55:58 2010
New Revision: 212667
URL: http://svn.freebsd.org/changeset/base/212667

Log:
  MFC r212115:
  
  Fix a bug with sched_affinity() where it checks td_pinned of another
  thread in a racy manner, which can lead to attempting to migrate a
  thread that is pinned to a CPU.  Instead, have sched_switch() determine
  which CPU a thread should run on if the current one is not allowed.
  
  KASSERT in sched_bind() that the thread is not yet pinned to a CPU.
  
  KASSERT in sched_switch() that only migratable threads or those moving
  due to a sched_bind() are changing CPUs.
  
  Note that this is direct commit as ipi_cpu() only exists in CURRENT.

Modified:
  stable/7/sys/kern/sched_ule.c

Modified: stable/7/sys/kern/sched_ule.c
==============================================================================
--- stable/7/sys/kern/sched_ule.c	Wed Sep 15 15:53:05 2010	(r212666)
+++ stable/7/sys/kern/sched_ule.c	Wed Sep 15 15:55:58 2010	(r212667)
@@ -1885,10 +1885,16 @@ sched_switch(struct thread *td, struct t
 		srqflag = (flags & SW_PREEMPT) ?
 		    SRQ_OURSELF|SRQ_YIELDING|SRQ_PREEMPTED :
 		    SRQ_OURSELF|SRQ_YIELDING;
+		if (THREAD_CAN_MIGRATE(td) && !THREAD_CAN_SCHED(td, ts->ts_cpu))
+			ts->ts_cpu = sched_pickcpu(td, 0);
 		if (ts->ts_cpu == cpuid)
 			tdq_add(tdq, td, srqflag);
-		else
+		else {
+			KASSERT(THREAD_CAN_MIGRATE(td) ||
+			    (ts->ts_flags & TSF_BOUND) != 0,
+			    ("Thread %p shouldn't migrate", td));
 			mtx = sched_switch_migrate(tdq, td, srqflag);
+		}
 	} else {
 		/* This thread must be going to sleep. */
 		TDQ_LOCK(tdq);
@@ -2536,7 +2542,6 @@ sched_affinity(struct thread *td)
 {
 #ifdef SMP
 	struct td_sched *ts;
-	int cpu;
 
 	THREAD_LOCK_ASSERT(td, MA_OWNED);
 	ts = td->td_sched;
@@ -2550,17 +2555,13 @@ sched_affinity(struct thread *td)
 	if (!TD_IS_RUNNING(td))
 		return;
 	td->td_flags |= TDF_NEEDRESCHED;
-	if (!THREAD_CAN_MIGRATE(td))
-		return;
 	/*
-	 * Assign the new cpu and force a switch before returning to
-	 * userspace.  If the target thread is not running locally send
-	 * an ipi to force the issue.
-	 */
-	cpu = ts->ts_cpu;
-	ts->ts_cpu = sched_pickcpu(td, 0);
-	if (cpu != PCPU_GET(cpuid))
-		ipi_selected(1 << cpu, IPI_PREEMPT);
+	 * Force a switch before returning to userspace.  If the
+	 * target thread is not running locally send an ipi to force
+	 * the issue.
+	 */
+	if (td != curthread)
+		ipi_selected(1 << ts->ts_cpu, IPI_PREEMPT);
 #endif
 }
 
@@ -2577,6 +2578,7 @@ sched_bind(struct thread *td, int cpu)
 	ts = td->td_sched;
 	if (ts->ts_flags & TSF_BOUND)
 		sched_unbind(td);
+	KASSERT(THREAD_CAN_MIGRATE(td), ("%p must be migratable", td));
 	ts->ts_flags |= TSF_BOUND;
 #ifdef SMP
 	sched_pin();


More information about the svn-src-all mailing list