From owner-svn-src-stable-8@FreeBSD.ORG Wed Sep 15 15:53:05 2010 Return-Path: Delivered-To: svn-src-stable-8@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id ED69B1065672; Wed, 15 Sep 2010 15:53:05 +0000 (UTC) (envelope-from mdf@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id C2E378FC18; Wed, 15 Sep 2010 15:53:05 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o8FFr5eG041411; Wed, 15 Sep 2010 15:53:05 GMT (envelope-from mdf@svn.freebsd.org) Received: (from mdf@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o8FFr58H041409; Wed, 15 Sep 2010 15:53:05 GMT (envelope-from mdf@svn.freebsd.org) Message-Id: <201009151553.o8FFr58H041409@svn.freebsd.org> From: Matthew D Fleming Date: Wed, 15 Sep 2010 15:53:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r212666 - stable/8/sys/kern X-BeenThere: svn-src-stable-8@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 8-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Sep 2010 15:53:06 -0000 Author: mdf Date: Wed Sep 15 15:53:05 2010 New Revision: 212666 URL: http://svn.freebsd.org/changeset/base/212666 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/8/sys/kern/sched_ule.c Modified: stable/8/sys/kern/sched_ule.c ============================================================================== --- stable/8/sys/kern/sched_ule.c Wed Sep 15 15:38:47 2010 (r212665) +++ stable/8/sys/kern/sched_ule.c Wed Sep 15 15:53:05 2010 (r212666) @@ -1803,10 +1803,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_runq_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); @@ -2389,7 +2395,6 @@ sched_affinity(struct thread *td) { #ifdef SMP struct td_sched *ts; - int cpu; THREAD_LOCK_ASSERT(td, MA_OWNED); ts = td->td_sched; @@ -2403,17 +2408,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. + * 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); + if (td != curthread) + ipi_selected(1 << ts->ts_cpu, IPI_PREEMPT); #endif } @@ -2430,6 +2431,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; sched_pin(); if (PCPU_GET(cpuid) == cpu)