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. */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to