aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_umtx.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_umtx.c')
-rw-r--r--sys/kern/kern_umtx.c30
1 files changed, 17 insertions, 13 deletions
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index 57ff74f5421e..092fcade9d19 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -2520,7 +2520,8 @@ do_lock_pp(struct thread *td, struct umutex *m, uint32_t flags,
struct umtx_pi *pi;
uint32_t ceiling;
uint32_t owner, id;
- int error, pri, old_inherited_pri, su, rv;
+ int error, pri, old_inherited_pri, new_pri, rv;
+ bool su;
id = td->td_tid;
uq = td->td_umtxq;
@@ -2549,21 +2550,23 @@ do_lock_pp(struct thread *td, struct umutex *m, uint32_t flags,
error = EINVAL;
goto out;
}
+ new_pri = PRI_MIN_REALTIME + ceiling;
- mtx_lock(&umtx_lock);
- if (UPRI(td) < PRI_MIN_REALTIME + ceiling) {
- mtx_unlock(&umtx_lock);
+ if (td->td_base_user_pri < new_pri) {
error = EINVAL;
goto out;
}
- if (su && PRI_MIN_REALTIME + ceiling < uq->uq_inherited_pri) {
- uq->uq_inherited_pri = PRI_MIN_REALTIME + ceiling;
- thread_lock(td);
- if (uq->uq_inherited_pri < UPRI(td))
- sched_lend_user_prio(td, uq->uq_inherited_pri);
- thread_unlock(td);
+ if (su) {
+ mtx_lock(&umtx_lock);
+ if (new_pri < uq->uq_inherited_pri) {
+ uq->uq_inherited_pri = new_pri;
+ thread_lock(td);
+ if (new_pri < UPRI(td))
+ sched_lend_user_prio(td, new_pri);
+ thread_unlock(td);
+ }
+ mtx_unlock(&umtx_lock);
}
- mtx_unlock(&umtx_lock);
rv = casueword32(&m->m_owner, UMUTEX_CONTESTED, &owner,
id | UMUTEX_CONTESTED);
@@ -2684,7 +2687,8 @@ do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags, bool rb)
struct umtx_q *uq, *uq2;
struct umtx_pi *pi;
uint32_t id, owner, rceiling;
- int error, pri, new_inherited_pri, su;
+ int error, pri, new_inherited_pri;
+ bool su;
id = td->td_tid;
uq = td->td_umtxq;
@@ -2739,7 +2743,7 @@ do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags, bool rb)
error = EFAULT;
else {
mtx_lock(&umtx_lock);
- if (su != 0)
+ if (su || new_inherited_pri == PRI_MAX)
uq->uq_inherited_pri = new_inherited_pri;
pri = PRI_MAX;
TAILQ_FOREACH(pi, &uq->uq_pi_contested, pi_link) {