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

David Xu davidxu at FreeBSD.org
Thu Dec 9 02:42:02 UTC 2010


Author: davidxu
Date: Thu Dec  9 02:42:02 2010
New Revision: 216313
URL: http://svn.freebsd.org/changeset/base/216313

Log:
  MFp4:
  It is possible a lower priority thread lending priority to higher priority
  thread, in old code, it is ignored, however the lending should always be
  recorded, add field td_lend_user_pri to fix the problem, if a thread does
  not have borrowed priority, its value is PRI_MAX.
  
  MFC after: 1 week

Modified:
  head/sys/kern/init_main.c
  head/sys/kern/kern_fork.c
  head/sys/kern/kern_thread.c
  head/sys/kern/kern_umtx.c
  head/sys/kern/sched_4bsd.c
  head/sys/kern/sched_ule.c
  head/sys/sys/proc.h

Modified: head/sys/kern/init_main.c
==============================================================================
--- head/sys/kern/init_main.c	Wed Dec  8 23:40:41 2010	(r216312)
+++ head/sys/kern/init_main.c	Thu Dec  9 02:42:02 2010	(r216313)
@@ -460,6 +460,7 @@ proc0_init(void *dummy __unused)
 	td->td_pri_class = PRI_TIMESHARE;
 	td->td_user_pri = PUSER;
 	td->td_base_user_pri = PUSER;
+	td->td_lend_user_pri = PRI_MAX;
 	td->td_priority = PVM;
 	td->td_base_pri = PUSER;
 	td->td_oncpu = 0;

Modified: head/sys/kern/kern_fork.c
==============================================================================
--- head/sys/kern/kern_fork.c	Wed Dec  8 23:40:41 2010	(r216312)
+++ head/sys/kern/kern_fork.c	Thu Dec  9 02:42:02 2010	(r216313)
@@ -543,6 +543,7 @@ again:
 	td2->td_sigstk = td->td_sigstk;
 	td2->td_sigmask = td->td_sigmask;
 	td2->td_flags = TDF_INMEM;
+	td2->td_lend_user_pri = PRI_MAX;
 
 #ifdef VIMAGE
 	td2->td_vnet = NULL;

Modified: head/sys/kern/kern_thread.c
==============================================================================
--- head/sys/kern/kern_thread.c	Wed Dec  8 23:40:41 2010	(r216312)
+++ head/sys/kern/kern_thread.c	Thu Dec  9 02:42:02 2010	(r216313)
@@ -110,6 +110,7 @@ thread_ctor(void *mem, int size, void *a
 	 * end of a context switch.
 	 */
 	td->td_critnest = 1;
+	td->td_lend_user_pri = PRI_MAX;
 	EVENTHANDLER_INVOKE(thread_ctor, td);
 #ifdef AUDIT
 	audit_thread_alloc(td);

Modified: head/sys/kern/kern_umtx.c
==============================================================================
--- head/sys/kern/kern_umtx.c	Wed Dec  8 23:40:41 2010	(r216312)
+++ head/sys/kern/kern_umtx.c	Thu Dec  9 02:42:02 2010	(r216313)
@@ -1407,17 +1407,19 @@ umtx_propagate_priority(struct thread *t
 
 	for (;;) {
 		td = pi->pi_owner;
-		if (td == NULL)
+		if (td == NULL || td == curthread)
 			return;
 
 		MPASS(td->td_proc != NULL);
 		MPASS(td->td_proc->p_magic == P_MAGIC);
 
-		if (UPRI(td) <= pri)
-			return;
-
 		thread_lock(td);
-		sched_lend_user_prio(td, pri);
+		if (td->td_lend_user_pri > pri)
+			sched_lend_user_prio(td, pri);
+		else {
+			thread_unlock(td);
+			break;
+		}
 		thread_unlock(td);
 
 		/*
@@ -3587,8 +3589,8 @@ umtx_thread_cleanup(struct thread *td)
 		pi->pi_owner = NULL;
 		TAILQ_REMOVE(&uq->uq_pi_contested, pi, pi_link);
 	}
+	mtx_unlock_spin(&umtx_lock);
 	thread_lock(td);
-	td->td_flags &= ~TDF_UBORROWING;
+	sched_unlend_user_prio(td, PRI_MAX);
 	thread_unlock(td);
-	mtx_unlock_spin(&umtx_lock);
 }

Modified: head/sys/kern/sched_4bsd.c
==============================================================================
--- head/sys/kern/sched_4bsd.c	Wed Dec  8 23:40:41 2010	(r216312)
+++ head/sys/kern/sched_4bsd.c	Thu Dec  9 02:42:02 2010	(r216313)
@@ -879,25 +879,23 @@ sched_prio(struct thread *td, u_char pri
 void
 sched_user_prio(struct thread *td, u_char prio)
 {
-	u_char oldprio;
 
 	THREAD_LOCK_ASSERT(td, MA_OWNED);
 	td->td_base_user_pri = prio;
-	if (td->td_flags & TDF_UBORROWING && td->td_user_pri <= prio)
+	if (td->td_lend_user_pri <= prio)
 		return;
-	oldprio = td->td_user_pri;
 	td->td_user_pri = prio;
 }
 
 void
 sched_lend_user_prio(struct thread *td, u_char prio)
 {
-	u_char oldprio;
 
 	THREAD_LOCK_ASSERT(td, MA_OWNED);
-	td->td_flags |= TDF_UBORROWING;
-	oldprio = td->td_user_pri;
-	td->td_user_pri = prio;
+	if (prio < td->td_lend_user_pri)
+		td->td_lend_user_pri = prio;
+	if (prio < td->td_user_pri)
+		td->td_user_pri = prio;
 }
 
 void
@@ -907,12 +905,11 @@ sched_unlend_user_prio(struct thread *td
 
 	THREAD_LOCK_ASSERT(td, MA_OWNED);
 	base_pri = td->td_base_user_pri;
-	if (prio >= base_pri) {
-		td->td_flags &= ~TDF_UBORROWING;
-		sched_user_prio(td, base_pri);
-	} else {
-		sched_lend_user_prio(td, prio);
-	}
+	td->td_lend_user_pri = prio;
+	if (prio > base_pri)
+		td->td_user_pri = base_pri;
+	else
+		td->td_user_pri = prio;
 }
 
 void

Modified: head/sys/kern/sched_ule.c
==============================================================================
--- head/sys/kern/sched_ule.c	Wed Dec  8 23:40:41 2010	(r216312)
+++ head/sys/kern/sched_ule.c	Thu Dec  9 02:42:02 2010	(r216313)
@@ -1677,8 +1677,8 @@ sched_user_prio(struct thread *td, u_cha
 {
 
 	td->td_base_user_pri = prio;
-	if (td->td_flags & TDF_UBORROWING && td->td_user_pri <= prio)
-                return;
+	if (td->td_lend_user_pri <= prio)
+		return;
 	td->td_user_pri = prio;
 }
 
@@ -1687,8 +1687,10 @@ sched_lend_user_prio(struct thread *td, 
 {
 
 	THREAD_LOCK_ASSERT(td, MA_OWNED);
-	td->td_flags |= TDF_UBORROWING;
-	td->td_user_pri = prio;
+	if (prio < td->td_lend_user_pri)
+		td->td_lend_user_pri = prio;
+	if (prio < td->td_user_pri)
+		td->td_user_pri = prio;
 }
 
 void
@@ -1698,12 +1700,11 @@ sched_unlend_user_prio(struct thread *td
 
 	THREAD_LOCK_ASSERT(td, MA_OWNED);
 	base_pri = td->td_base_user_pri;
-	if (prio >= base_pri) {
-		td->td_flags &= ~TDF_UBORROWING;
-		sched_user_prio(td, base_pri);
-	} else {
-		sched_lend_user_prio(td, prio);
-	}
+	td->td_lend_user_pri = prio;
+	if (prio > base_pri)
+		td->td_user_pri = base_pri;
+	else
+		td->td_user_pri = prio;
 }
 
 /*

Modified: head/sys/sys/proc.h
==============================================================================
--- head/sys/sys/proc.h	Wed Dec  8 23:40:41 2010	(r216312)
+++ head/sys/sys/proc.h	Thu Dec  9 02:42:02 2010	(r216313)
@@ -214,6 +214,7 @@ struct thread {
 	lwpid_t		td_tid;		/* (b) Thread ID. */
 	sigqueue_t	td_sigqueue;	/* (c) Sigs arrived, not delivered. */
 #define	td_siglist	td_sigqueue.sq_signals
+	u_char		td_lend_user_pri; /* (t) Lend user pri. */
 
 /* Cleared during fork1() */
 #define	td_startzero td_flags
@@ -343,7 +344,7 @@ do {									\
 #define	TDF_CANSWAP	0x00000040 /* Thread can be swapped. */
 #define	TDF_SLEEPABORT	0x00000080 /* sleepq_abort was called. */
 #define	TDF_KTH_SUSP	0x00000100 /* kthread is suspended */
-#define	TDF_UBORROWING	0x00000200 /* Thread is borrowing user pri. */
+#define	TDF_UNUSED09	0x00000200 /* --available-- */
 #define	TDF_BOUNDARY	0x00000400 /* Thread suspended at user boundary */
 #define	TDF_ASTPENDING	0x00000800 /* Thread has some asynchronous events. */
 #define	TDF_TIMOFAIL	0x00001000 /* Timeout from sleep after we were awake. */


More information about the svn-src-all mailing list