svn commit: r312426 - head/sys/kern

Andriy Gapon avg at FreeBSD.org
Thu Jan 19 18:46:42 UTC 2017


Author: avg
Date: Thu Jan 19 18:46:41 2017
New Revision: 312426
URL: https://svnweb.freebsd.org/changeset/base/312426

Log:
  fix a thread preemption regression in schedulers introduced in r270423
  
  Commit r270423 fixed a regression in sched_yield() that was introduced
  in earlier changes.  Unfortunately, at the same time it introduced an
  new regression.  The problem is that SWT_RELINQUISH (6), like all other
  SWT_* constants and unlike SW_* flags, is not a bit flag.  So, (flags &
  SWT_RELINQUISH) is true in cases where that was not really indended,
  for example, with SWT_OWEPREEMPT (2) and SWT_REMOTEPREEMPT (11).
  
  A straight forward fix would be to use (flags & SW_TYPE_MASK) ==
  SWT_RELINQUISH, but my impression is that the switch types are designed
  mostly for gathering statistics, not for influencing scheduling
  decisions.
  
  So, I decided that it would be better to check for SW_PREEMPT flag
  instead.  That's also the same flag that was checked before r239157.
  I double-checked how that flag is used and I am confident that the flag
  is set only in the places where we really have the preemption:
  - critical_exit + td_owepreempt
  - sched_preempt in the ULE scheduler
  - sched_preempt in the 4BSD scheduler
  
  Reviewed by:	kib, mav
  MFC after:	4 days
  Sponsored by:	Panzura
  Differential Revision: https://reviews.freebsd.org/D9230

Modified:
  head/sys/kern/sched_4bsd.c
  head/sys/kern/sched_ule.c

Modified: head/sys/kern/sched_4bsd.c
==============================================================================
--- head/sys/kern/sched_4bsd.c	Thu Jan 19 18:38:58 2017	(r312425)
+++ head/sys/kern/sched_4bsd.c	Thu Jan 19 18:46:41 2017	(r312426)
@@ -968,8 +968,8 @@ sched_switch(struct thread *td, struct t
 		sched_load_rem();
 
 	td->td_lastcpu = td->td_oncpu;
-	preempted = !((td->td_flags & TDF_SLICEEND) ||
-	    (flags & SWT_RELINQUISH));
+	preempted = (td->td_flags & TDF_SLICEEND) == 0 &&
+	    (flags & SW_PREEMPT) != 0;
 	td->td_flags &= ~(TDF_NEEDRESCHED | TDF_SLICEEND);
 	td->td_owepreempt = 0;
 	td->td_oncpu = NOCPU;

Modified: head/sys/kern/sched_ule.c
==============================================================================
--- head/sys/kern/sched_ule.c	Thu Jan 19 18:38:58 2017	(r312425)
+++ head/sys/kern/sched_ule.c	Thu Jan 19 18:46:41 2017	(r312426)
@@ -1898,8 +1898,8 @@ sched_switch(struct thread *td, struct t
 	ts->ts_rltick = ticks;
 	td->td_lastcpu = td->td_oncpu;
 	td->td_oncpu = NOCPU;
-	preempted = !((td->td_flags & TDF_SLICEEND) ||
-	    (flags & SWT_RELINQUISH));
+	preempted = (td->td_flags & TDF_SLICEEND) == 0 &&
+	    (flags & SW_PREEMPT) != 0;
 	td->td_flags &= ~(TDF_NEEDRESCHED | TDF_SLICEEND);
 	td->td_owepreempt = 0;
 	if (!TD_IS_IDLETHREAD(td))


More information about the svn-src-head mailing list