* Lock a PP mutex. */
| 2127 | * Lock a PP mutex. |
| 2128 | */ |
| 2129 | static int |
| 2130 | do_lock_pp(struct thread *td, struct umutex *m, uint32_t flags, |
| 2131 | struct _umtx_time *timeout, int try) |
| 2132 | { |
| 2133 | struct abs_timeout timo; |
| 2134 | struct umtx_q *uq, *uq2; |
| 2135 | struct umtx_pi *pi; |
| 2136 | uint32_t ceiling; |
| 2137 | uint32_t owner, id; |
| 2138 | int error, pri, old_inherited_pri, su, rv; |
| 2139 | |
| 2140 | id = td->td_tid; |
| 2141 | uq = td->td_umtxq; |
| 2142 | if ((error = umtx_key_get(m, (flags & UMUTEX_ROBUST) != 0 ? |
| 2143 | TYPE_PP_ROBUST_UMUTEX : TYPE_PP_UMUTEX, GET_SHARE(flags), |
| 2144 | &uq->uq_key)) != 0) |
| 2145 | return (error); |
| 2146 | |
| 2147 | if (timeout != NULL) |
| 2148 | abs_timeout_init2(&timo, timeout); |
| 2149 | |
| 2150 | su = (priv_check(td, PRIV_SCHED_RTPRIO) == 0); |
| 2151 | for (;;) { |
| 2152 | old_inherited_pri = uq->uq_inherited_pri; |
| 2153 | umtxq_lock(&uq->uq_key); |
| 2154 | umtxq_busy(&uq->uq_key); |
| 2155 | umtxq_unlock(&uq->uq_key); |
| 2156 | |
| 2157 | rv = fueword32(&m->m_ceilings[0], &ceiling); |
| 2158 | if (rv == -1) { |
| 2159 | error = EFAULT; |
| 2160 | goto out; |
| 2161 | } |
| 2162 | ceiling = RTP_PRIO_MAX - ceiling; |
| 2163 | if (ceiling > RTP_PRIO_MAX) { |
| 2164 | error = EINVAL; |
| 2165 | goto out; |
| 2166 | } |
| 2167 | |
| 2168 | mtx_lock(&umtx_lock); |
| 2169 | if (UPRI(td) < PRI_MIN_REALTIME + ceiling) { |
| 2170 | mtx_unlock(&umtx_lock); |
| 2171 | error = EINVAL; |
| 2172 | goto out; |
| 2173 | } |
| 2174 | if (su && PRI_MIN_REALTIME + ceiling < uq->uq_inherited_pri) { |
| 2175 | uq->uq_inherited_pri = PRI_MIN_REALTIME + ceiling; |
| 2176 | thread_lock(td); |
| 2177 | if (uq->uq_inherited_pri < UPRI(td)) |
| 2178 | sched_lend_user_prio(td, uq->uq_inherited_pri); |
| 2179 | thread_unlock(td); |
| 2180 | } |
| 2181 | mtx_unlock(&umtx_lock); |
| 2182 | |
| 2183 | rv = casueword32(&m->m_owner, UMUTEX_CONTESTED, &owner, |
| 2184 | id | UMUTEX_CONTESTED); |
| 2185 | /* The address was invalid. */ |
| 2186 | if (rv == -1) { |
no test coverage detected