svn commit: r333344 - in head/sys: kern sys

Mateusz Guzik mjg at FreeBSD.org
Mon May 7 23:36:17 UTC 2018


Author: mjg
Date: Mon May  7 23:36:16 2018
New Revision: 333344
URL: https://svnweb.freebsd.org/changeset/base/333344

Log:
  Inlined sched_userret.
  
  The tested condition is rarely true and it induces a function call
  on each return to userspace.
  
  Bumps getuid rate by about 1% on Broadwell.

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

Modified: head/sys/kern/sched_4bsd.c
==============================================================================
--- head/sys/kern/sched_4bsd.c	Mon May  7 23:23:11 2018	(r333343)
+++ head/sys/kern/sched_4bsd.c	Mon May  7 23:36:16 2018	(r333344)
@@ -1481,25 +1481,13 @@ sched_preempt(struct thread *td)
 }
 
 void
-sched_userret(struct thread *td)
+sched_userret_slowpath(struct thread *td)
 {
-	/*
-	 * XXX we cheat slightly on the locking here to avoid locking in
-	 * the usual case.  Setting td_priority here is essentially an
-	 * incomplete workaround for not setting it properly elsewhere.
-	 * Now that some interrupt handlers are threads, not setting it
-	 * properly elsewhere can clobber it in the window between setting
-	 * it here and returning to user mode, so don't waste time setting
-	 * it perfectly here.
-	 */
-	KASSERT((td->td_flags & TDF_BORROWING) == 0,
-	    ("thread with borrowed priority returning to userland"));
-	if (td->td_priority != td->td_user_pri) {
-		thread_lock(td);
-		td->td_priority = td->td_user_pri;
-		td->td_base_pri = td->td_user_pri;
-		thread_unlock(td);
-	}
+
+	thread_lock(td);
+	td->td_priority = td->td_user_pri;
+	td->td_base_pri = td->td_user_pri;
+	thread_unlock(td);
 }
 
 void

Modified: head/sys/kern/sched_ule.c
==============================================================================
--- head/sys/kern/sched_ule.c	Mon May  7 23:23:11 2018	(r333343)
+++ head/sys/kern/sched_ule.c	Mon May  7 23:36:16 2018	(r333344)
@@ -2356,26 +2356,14 @@ sched_preempt(struct thread *td)
  * to static priorities in msleep() or similar.
  */
 void
-sched_userret(struct thread *td)
+sched_userret_slowpath(struct thread *td)
 {
-	/*
-	 * XXX we cheat slightly on the locking here to avoid locking in  
-	 * the usual case.  Setting td_priority here is essentially an
-	 * incomplete workaround for not setting it properly elsewhere.
-	 * Now that some interrupt handlers are threads, not setting it
-	 * properly elsewhere can clobber it in the window between setting
-	 * it here and returning to user mode, so don't waste time setting
-	 * it perfectly here.
-	 */
-	KASSERT((td->td_flags & TDF_BORROWING) == 0,
-	    ("thread with borrowed priority returning to userland"));
-	if (td->td_priority != td->td_user_pri) {
-		thread_lock(td);
-		td->td_priority = td->td_user_pri;
-		td->td_base_pri = td->td_user_pri;
-		tdq_setlowpri(TDQ_SELF(), td);
-		thread_unlock(td);
-        }
+
+	thread_lock(td);
+	td->td_priority = td->td_user_pri;
+	td->td_base_pri = td->td_user_pri;
+	tdq_setlowpri(TDQ_SELF(), td);
+	thread_unlock(td);
 }
 
 /*

Modified: head/sys/sys/sched.h
==============================================================================
--- head/sys/sys/sched.h	Mon May  7 23:23:11 2018	(r333343)
+++ head/sys/sys/sched.h	Mon May  7 23:36:16 2018	(r333344)
@@ -103,13 +103,32 @@ void	sched_switch(struct thread *td, struct thread *ne
 void	sched_throw(struct thread *td);
 void	sched_unlend_prio(struct thread *td, u_char prio);
 void	sched_user_prio(struct thread *td, u_char prio);
-void	sched_userret(struct thread *td);
+void	sched_userret_slowpath(struct thread *td);
 void	sched_wakeup(struct thread *td);
 #ifdef	RACCT
 #ifdef	SCHED_4BSD
 fixpt_t	sched_pctcpu_delta(struct thread *td);
 #endif
 #endif
+
+static inline void
+sched_userret(struct thread *td)
+{
+
+	/*
+	 * XXX we cheat slightly on the locking here to avoid locking in
+	 * the usual case.  Setting td_priority here is essentially an
+	 * incomplete workaround for not setting it properly elsewhere.
+	 * Now that some interrupt handlers are threads, not setting it
+	 * properly elsewhere can clobber it in the window between setting
+	 * it here and returning to user mode, so don't waste time setting
+	 * it perfectly here.
+	 */
+	KASSERT((td->td_flags & TDF_BORROWING) == 0,
+	    ("thread with borrowed priority returning to userland"));
+	if (__predict_false(td->td_priority != td->td_user_pri))
+		sched_userret_slowpath(td);
+}
 
 /*
  * Threads are moved on and off of run queues


More information about the svn-src-all mailing list