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