summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/init_main.c1
-rw-r--r--sys/kern/kern_fork.c1
-rw-r--r--sys/kern/kern_thread.c1
-rw-r--r--sys/kern/kern_umtx.c16
-rw-r--r--sys/kern/sched_4bsd.c23
-rw-r--r--sys/kern/sched_ule.c21
-rw-r--r--sys/sys/proc.h3
7 files changed, 35 insertions, 31 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index b86ea91..80a0907 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -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;
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 19d7d0f..61d9531 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -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;
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index 5f07590..3e651bb 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -110,6 +110,7 @@ thread_ctor(void *mem, int size, void *arg, int flags)
* 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);
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index 43570ce..e7b9b32 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -1407,17 +1407,19 @@ umtx_propagate_priority(struct thread *td)
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);
}
diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c
index 9face64..6278126 100644
--- a/sys/kern/sched_4bsd.c
+++ b/sys/kern/sched_4bsd.c
@@ -879,25 +879,23 @@ sched_prio(struct thread *td, u_char prio)
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, u_char prio)
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
diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
index 030c98d..fb30fdb 100644
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -1677,8 +1677,8 @@ sched_user_prio(struct thread *td, u_char prio)
{
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, u_char prio)
{
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, u_char prio)
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;
}
/*
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 02f228c..48ef012 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -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. */
OpenPOWER on IntegriCloud