1 /*- 2 * Copyright (c) 2004, David Xu <davidxu@freebsd.org> 3 * Copyright (c) 2002, Jeffrey Roberson <jeff@freebsd.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice unmodified, this list of conditions, and the following 11 * disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include "opt_compat.h" 32 #include <sys/param.h> 33 #include <sys/kernel.h> 34 #include <sys/limits.h> 35 #include <sys/lock.h> 36 #include <sys/malloc.h> 37 #include <sys/mutex.h> 38 #include <sys/priv.h> 39 #include <sys/proc.h> 40 #include <sys/sched.h> 41 #include <sys/smp.h> 42 #include <sys/sysctl.h> 43 #include <sys/sysent.h> 44 #include <sys/systm.h> 45 #include <sys/sysproto.h> 46 #include <sys/syscallsubr.h> 47 #include <sys/eventhandler.h> 48 #include <sys/umtx.h> 49 50 #include <vm/vm.h> 51 #include <vm/vm_param.h> 52 #include <vm/pmap.h> 53 #include <vm/vm_map.h> 54 #include <vm/vm_object.h> 55 56 #include <machine/cpu.h> 57 58 #ifdef COMPAT_FREEBSD32 59 #include <compat/freebsd32/freebsd32_proto.h> 60 #endif 61 62 #define _UMUTEX_TRY 1 63 #define _UMUTEX_WAIT 2 64 65 /* Priority inheritance mutex info. */ 66 struct umtx_pi { 67 /* Owner thread */ 68 struct thread *pi_owner; 69 70 /* Reference count */ 71 int pi_refcount; 72 73 /* List entry to link umtx holding by thread */ 74 TAILQ_ENTRY(umtx_pi) pi_link; 75 76 /* List entry in hash */ 77 TAILQ_ENTRY(umtx_pi) pi_hashlink; 78 79 /* List for waiters */ 80 TAILQ_HEAD(,umtx_q) pi_blocked; 81 82 /* Identify a userland lock object */ 83 struct umtx_key pi_key; 84 }; 85 86 /* A userland synchronous object user. */ 87 struct umtx_q { 88 /* Linked list for the hash. */ 89 TAILQ_ENTRY(umtx_q) uq_link; 90 91 /* Umtx key. */ 92 struct umtx_key uq_key; 93 94 /* Umtx flags. */ 95 int uq_flags; 96 #define UQF_UMTXQ 0x0001 97 98 /* The thread waits on. */ 99 struct thread *uq_thread; 100 101 /* 102 * Blocked on PI mutex. read can use chain lock 103 * or umtx_lock, write must have both chain lock and 104 * umtx_lock being hold. 105 */ 106 struct umtx_pi *uq_pi_blocked; 107 108 /* On blocked list */ 109 TAILQ_ENTRY(umtx_q) uq_lockq; 110 111 /* Thread contending with us */ 112 TAILQ_HEAD(,umtx_pi) uq_pi_contested; 113 114 /* Inherited priority from PP mutex */ 115 u_char uq_inherited_pri; 116 117 /* Spare queue ready to be reused */ 118 struct umtxq_queue *uq_spare_queue; 119 120 /* The queue we on */ 121 struct umtxq_queue *uq_cur_queue; 122 }; 123 124 TAILQ_HEAD(umtxq_head, umtx_q); 125 126 /* Per-key wait-queue */ 127 struct umtxq_queue { 128 struct umtxq_head head; 129 struct umtx_key key; 130 LIST_ENTRY(umtxq_queue) link; 131 int length; 132 }; 133 134 LIST_HEAD(umtxq_list, umtxq_queue); 135 136 /* Userland lock object's wait-queue chain */ 137 struct umtxq_chain { 138 /* Lock for this chain. */ 139 struct mtx uc_lock; 140 141 /* List of sleep queues. */ 142 struct umtxq_list uc_queue[2]; 143 #define UMTX_SHARED_QUEUE 0 144 #define UMTX_EXCLUSIVE_QUEUE 1 145 146 LIST_HEAD(, umtxq_queue) uc_spare_queue; 147 148 /* Busy flag */ 149 char uc_busy; 150 151 /* Chain lock waiters */ 152 int uc_waiters; 153 154 /* All PI in the list */ 155 TAILQ_HEAD(,umtx_pi) uc_pi_list; 156 157 }; 158 159 #define UMTXQ_LOCKED_ASSERT(uc) mtx_assert(&(uc)->uc_lock, MA_OWNED) 160 #define UMTXQ_BUSY_ASSERT(uc) KASSERT(&(uc)->uc_busy, ("umtx chain is not busy")) 161 162 /* 163 * Don't propagate time-sharing priority, there is a security reason, 164 * a user can simply introduce PI-mutex, let thread A lock the mutex, 165 * and let another thread B block on the mutex, because B is 166 * sleeping, its priority will be boosted, this causes A's priority to 167 * be boosted via priority propagating too and will never be lowered even 168 * if it is using 100%CPU, this is unfair to other processes. 169 */ 170 171 #define UPRI(td) (((td)->td_user_pri >= PRI_MIN_TIMESHARE &&\ 172 (td)->td_user_pri <= PRI_MAX_TIMESHARE) ?\ 173 PRI_MAX_TIMESHARE : (td)->td_user_pri) 174 175 #define GOLDEN_RATIO_PRIME 2654404609U 176 #define UMTX_CHAINS 512 177 #define UMTX_SHIFTS (__WORD_BIT - 9) 178 179 #define GET_SHARE(flags) \ 180 (((flags) & USYNC_PROCESS_SHARED) == 0 ? THREAD_SHARE : PROCESS_SHARE) 181 182 #define BUSY_SPINS 200 183 184 static uma_zone_t umtx_pi_zone; 185 static struct umtxq_chain umtxq_chains[2][UMTX_CHAINS]; 186 static MALLOC_DEFINE(M_UMTX, "umtx", "UMTX queue memory"); 187 static int umtx_pi_allocated; 188 189 static SYSCTL_NODE(_debug, OID_AUTO, umtx, CTLFLAG_RW, 0, "umtx debug"); 190 SYSCTL_INT(_debug_umtx, OID_AUTO, umtx_pi_allocated, CTLFLAG_RD, 191 &umtx_pi_allocated, 0, "Allocated umtx_pi"); 192 193 static void umtxq_sysinit(void *); 194 static void umtxq_hash(struct umtx_key *key); 195 static struct umtxq_chain *umtxq_getchain(struct umtx_key *key); 196 static void umtxq_lock(struct umtx_key *key); 197 static void umtxq_unlock(struct umtx_key *key); 198 static void umtxq_busy(struct umtx_key *key); 199 static void umtxq_unbusy(struct umtx_key *key); 200 static void umtxq_insert_queue(struct umtx_q *uq, int q); 201 static void umtxq_remove_queue(struct umtx_q *uq, int q); 202 static int umtxq_sleep(struct umtx_q *uq, const char *wmesg, int timo); 203 static int umtxq_count(struct umtx_key *key); 204 static struct umtx_pi *umtx_pi_alloc(int); 205 static void umtx_pi_free(struct umtx_pi *pi); 206 static int do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags); 207 static void umtx_thread_cleanup(struct thread *td); 208 static void umtx_exec_hook(void *arg __unused, struct proc *p __unused, 209 struct image_params *imgp __unused); 210 SYSINIT(umtx, SI_SUB_EVENTHANDLER+1, SI_ORDER_MIDDLE, umtxq_sysinit, NULL); 211 212 #define umtxq_signal(key, nwake) umtxq_signal_queue((key), (nwake), UMTX_SHARED_QUEUE) 213 #define umtxq_insert(uq) umtxq_insert_queue((uq), UMTX_SHARED_QUEUE) 214 #define umtxq_remove(uq) umtxq_remove_queue((uq), UMTX_SHARED_QUEUE) 215 216 static struct mtx umtx_lock; 217 218 static void 219 umtxq_sysinit(void *arg __unused) 220 { 221 int i, j; 222 223 umtx_pi_zone = uma_zcreate("umtx pi", sizeof(struct umtx_pi), 224 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 225 for (i = 0; i < 2; ++i) { 226 for (j = 0; j < UMTX_CHAINS; ++j) { 227 mtx_init(&umtxq_chains[i][j].uc_lock, "umtxql", NULL, 228 MTX_DEF | MTX_DUPOK); 229 LIST_INIT(&umtxq_chains[i][j].uc_queue[0]); 230 LIST_INIT(&umtxq_chains[i][j].uc_queue[1]); 231 LIST_INIT(&umtxq_chains[i][j].uc_spare_queue); 232 TAILQ_INIT(&umtxq_chains[i][j].uc_pi_list); 233 umtxq_chains[i][j].uc_busy = 0; 234 umtxq_chains[i][j].uc_waiters = 0; 235 } 236 } 237 mtx_init(&umtx_lock, "umtx lock", NULL, MTX_SPIN); 238 EVENTHANDLER_REGISTER(process_exec, umtx_exec_hook, NULL, 239 EVENTHANDLER_PRI_ANY); 240 } 241 242 struct umtx_q * 243 umtxq_alloc(void) 244 { 245 struct umtx_q *uq; 246 247 uq = malloc(sizeof(struct umtx_q), M_UMTX, M_WAITOK | M_ZERO); 248 uq->uq_spare_queue = malloc(sizeof(struct umtxq_queue), M_UMTX, M_WAITOK | M_ZERO); 249 TAILQ_INIT(&uq->uq_spare_queue->head); 250 TAILQ_INIT(&uq->uq_pi_contested); 251 uq->uq_inherited_pri = PRI_MAX; 252 return (uq); 253 } 254 255 void 256 umtxq_free(struct umtx_q *uq) 257 { 258 MPASS(uq->uq_spare_queue != NULL); 259 free(uq->uq_spare_queue, M_UMTX); 260 free(uq, M_UMTX); 261 } 262 263 static inline void 264 umtxq_hash(struct umtx_key *key) 265 { 266 unsigned n = (uintptr_t)key->info.both.a + key->info.both.b; 267 key->hash = ((n * GOLDEN_RATIO_PRIME) >> UMTX_SHIFTS) % UMTX_CHAINS; 268 } 269 270 static inline struct umtxq_chain * 271 umtxq_getchain(struct umtx_key *key) 272 { 273 if (key->type <= TYPE_SEM) 274 return (&umtxq_chains[1][key->hash]); 275 return (&umtxq_chains[0][key->hash]); 276 } 277 278 /* 279 * Lock a chain. 280 */ 281 static inline void 282 umtxq_lock(struct umtx_key *key) 283 { 284 struct umtxq_chain *uc; 285 286 uc = umtxq_getchain(key); 287 mtx_lock(&uc->uc_lock); 288 } 289 290 /* 291 * Unlock a chain. 292 */ 293 static inline void 294 umtxq_unlock(struct umtx_key *key) 295 { 296 struct umtxq_chain *uc; 297 298 uc = umtxq_getchain(key); 299 mtx_unlock(&uc->uc_lock); 300 } 301 302 /* 303 * Set chain to busy state when following operation 304 * may be blocked (kernel mutex can not be used). 305 */ 306 static inline void 307 umtxq_busy(struct umtx_key *key) 308 { 309 struct umtxq_chain *uc; 310 311 uc = umtxq_getchain(key); 312 mtx_assert(&uc->uc_lock, MA_OWNED); 313 if (uc->uc_busy) { 314 #ifdef SMP 315 if (smp_cpus > 1) { 316 int count = BUSY_SPINS; 317 if (count > 0) { 318 umtxq_unlock(key); 319 while (uc->uc_busy && --count > 0) 320 cpu_spinwait(); 321 umtxq_lock(key); 322 } 323 } 324 #endif 325 while (uc->uc_busy) { 326 uc->uc_waiters++; 327 msleep(uc, &uc->uc_lock, 0, "umtxqb", 0); 328 uc->uc_waiters--; 329 } 330 } 331 uc->uc_busy = 1; 332 } 333 334 /* 335 * Unbusy a chain. 336 */ 337 static inline void 338 umtxq_unbusy(struct umtx_key *key) 339 { 340 struct umtxq_chain *uc; 341 342 uc = umtxq_getchain(key); 343 mtx_assert(&uc->uc_lock, MA_OWNED); 344 KASSERT(uc->uc_busy != 0, ("not busy")); 345 uc->uc_busy = 0; 346 if (uc->uc_waiters) 347 wakeup_one(uc); 348 } 349 350 static struct umtxq_queue * 351 umtxq_queue_lookup(struct umtx_key *key, int q) 352 { 353 struct umtxq_queue *uh; 354 struct umtxq_chain *uc; 355 356 uc = umtxq_getchain(key); 357 UMTXQ_LOCKED_ASSERT(uc); 358 LIST_FOREACH(uh, &uc->uc_queue[q], link) { 359 if (umtx_key_match(&uh->key, key)) 360 return (uh); 361 } 362 363 return (NULL); 364 } 365 366 static inline void 367 umtxq_insert_queue(struct umtx_q *uq, int q) 368 { 369 struct umtxq_queue *uh; 370 struct umtxq_chain *uc; 371 372 uc = umtxq_getchain(&uq->uq_key); 373 UMTXQ_LOCKED_ASSERT(uc); 374 KASSERT((uq->uq_flags & UQF_UMTXQ) == 0, ("umtx_q is already on queue")); 375 uh = umtxq_queue_lookup(&uq->uq_key, q); 376 if (uh != NULL) { 377 LIST_INSERT_HEAD(&uc->uc_spare_queue, uq->uq_spare_queue, link); 378 } else { 379 uh = uq->uq_spare_queue; 380 uh->key = uq->uq_key; 381 LIST_INSERT_HEAD(&uc->uc_queue[q], uh, link); 382 } 383 uq->uq_spare_queue = NULL; 384 385 TAILQ_INSERT_TAIL(&uh->head, uq, uq_link); 386 uh->length++; 387 uq->uq_flags |= UQF_UMTXQ; 388 uq->uq_cur_queue = uh; 389 return; 390 } 391 392 static inline void 393 umtxq_remove_queue(struct umtx_q *uq, int q) 394 { 395 struct umtxq_chain *uc; 396 struct umtxq_queue *uh; 397 398 uc = umtxq_getchain(&uq->uq_key); 399 UMTXQ_LOCKED_ASSERT(uc); 400 if (uq->uq_flags & UQF_UMTXQ) { 401 uh = uq->uq_cur_queue; 402 TAILQ_REMOVE(&uh->head, uq, uq_link); 403 uh->length--; 404 uq->uq_flags &= ~UQF_UMTXQ; 405 if (TAILQ_EMPTY(&uh->head)) { 406 KASSERT(uh->length == 0, 407 ("inconsistent umtxq_queue length")); 408 LIST_REMOVE(uh, link); 409 } else { 410 uh = LIST_FIRST(&uc->uc_spare_queue); 411 KASSERT(uh != NULL, ("uc_spare_queue is empty")); 412 LIST_REMOVE(uh, link); 413 } 414 uq->uq_spare_queue = uh; 415 uq->uq_cur_queue = NULL; 416 } 417 } 418 419 /* 420 * Check if there are multiple waiters 421 */ 422 static int 423 umtxq_count(struct umtx_key *key) 424 { 425 struct umtxq_chain *uc; 426 struct umtxq_queue *uh; 427 428 uc = umtxq_getchain(key); 429 UMTXQ_LOCKED_ASSERT(uc); 430 uh = umtxq_queue_lookup(key, UMTX_SHARED_QUEUE); 431 if (uh != NULL) 432 return (uh->length); 433 return (0); 434 } 435 436 /* 437 * Check if there are multiple PI waiters and returns first 438 * waiter. 439 */ 440 static int 441 umtxq_count_pi(struct umtx_key *key, struct umtx_q **first) 442 { 443 struct umtxq_chain *uc; 444 struct umtxq_queue *uh; 445 446 *first = NULL; 447 uc = umtxq_getchain(key); 448 UMTXQ_LOCKED_ASSERT(uc); 449 uh = umtxq_queue_lookup(key, UMTX_SHARED_QUEUE); 450 if (uh != NULL) { 451 *first = TAILQ_FIRST(&uh->head); 452 return (uh->length); 453 } 454 return (0); 455 } 456 457 /* 458 * Wake up threads waiting on an userland object. 459 */ 460 461 static int 462 umtxq_signal_queue(struct umtx_key *key, int n_wake, int q) 463 { 464 struct umtxq_chain *uc; 465 struct umtxq_queue *uh; 466 struct umtx_q *uq; 467 int ret; 468 469 ret = 0; 470 uc = umtxq_getchain(key); 471 UMTXQ_LOCKED_ASSERT(uc); 472 uh = umtxq_queue_lookup(key, q); 473 if (uh != NULL) { 474 while ((uq = TAILQ_FIRST(&uh->head)) != NULL) { 475 umtxq_remove_queue(uq, q); 476 wakeup(uq); 477 if (++ret >= n_wake) 478 return (ret); 479 } 480 } 481 return (ret); 482 } 483 484 485 /* 486 * Wake up specified thread. 487 */ 488 static inline void 489 umtxq_signal_thread(struct umtx_q *uq) 490 { 491 struct umtxq_chain *uc; 492 493 uc = umtxq_getchain(&uq->uq_key); 494 UMTXQ_LOCKED_ASSERT(uc); 495 umtxq_remove(uq); 496 wakeup(uq); 497 } 498 499 /* 500 * Put thread into sleep state, before sleeping, check if 501 * thread was removed from umtx queue. 502 */ 503 static inline int 504 umtxq_sleep(struct umtx_q *uq, const char *wmesg, int timo) 505 { 506 struct umtxq_chain *uc; 507 int error; 508 509 uc = umtxq_getchain(&uq->uq_key); 510 UMTXQ_LOCKED_ASSERT(uc); 511 if (!(uq->uq_flags & UQF_UMTXQ)) 512 return (0); 513 error = msleep(uq, &uc->uc_lock, PCATCH, wmesg, timo); 514 if (error == EWOULDBLOCK) 515 error = ETIMEDOUT; 516 return (error); 517 } 518 519 /* 520 * Convert userspace address into unique logical address. 521 */ 522 int 523 umtx_key_get(void *addr, int type, int share, struct umtx_key *key) 524 { 525 struct thread *td = curthread; 526 vm_map_t map; 527 vm_map_entry_t entry; 528 vm_pindex_t pindex; 529 vm_prot_t prot; 530 boolean_t wired; 531 532 key->type = type; 533 if (share == THREAD_SHARE) { 534 key->shared = 0; 535 key->info.private.vs = td->td_proc->p_vmspace; 536 key->info.private.addr = (uintptr_t)addr; 537 } else { 538 MPASS(share == PROCESS_SHARE || share == AUTO_SHARE); 539 map = &td->td_proc->p_vmspace->vm_map; 540 if (vm_map_lookup(&map, (vm_offset_t)addr, VM_PROT_WRITE, 541 &entry, &key->info.shared.object, &pindex, &prot, 542 &wired) != KERN_SUCCESS) { 543 return EFAULT; 544 } 545 546 if ((share == PROCESS_SHARE) || 547 (share == AUTO_SHARE && 548 VM_INHERIT_SHARE == entry->inheritance)) { 549 key->shared = 1; 550 key->info.shared.offset = entry->offset + entry->start - 551 (vm_offset_t)addr; 552 vm_object_reference(key->info.shared.object); 553 } else { 554 key->shared = 0; 555 key->info.private.vs = td->td_proc->p_vmspace; 556 key->info.private.addr = (uintptr_t)addr; 557 } 558 vm_map_lookup_done(map, entry); 559 } 560 561 umtxq_hash(key); 562 return (0); 563 } 564 565 /* 566 * Release key. 567 */ 568 void 569 umtx_key_release(struct umtx_key *key) 570 { 571 if (key->shared) 572 vm_object_deallocate(key->info.shared.object); 573 } 574 575 /* 576 * Lock a umtx object. 577 */ 578 static int 579 _do_lock_umtx(struct thread *td, struct umtx *umtx, u_long id, int timo) 580 { 581 struct umtx_q *uq; 582 u_long owner; 583 u_long old; 584 int error = 0; 585 586 uq = td->td_umtxq; 587 588 /* 589 * Care must be exercised when dealing with umtx structure. It 590 * can fault on any access. 591 */ 592 for (;;) { 593 /* 594 * Try the uncontested case. This should be done in userland. 595 */ 596 owner = casuword(&umtx->u_owner, UMTX_UNOWNED, id); 597 598 /* The acquire succeeded. */ 599 if (owner == UMTX_UNOWNED) 600 return (0); 601 602 /* The address was invalid. */ 603 if (owner == -1) 604 return (EFAULT); 605 606 /* If no one owns it but it is contested try to acquire it. */ 607 if (owner == UMTX_CONTESTED) { 608 owner = casuword(&umtx->u_owner, 609 UMTX_CONTESTED, id | UMTX_CONTESTED); 610 611 if (owner == UMTX_CONTESTED) 612 return (0); 613 614 /* The address was invalid. */ 615 if (owner == -1) 616 return (EFAULT); 617 618 /* If this failed the lock has changed, restart. */ 619 continue; 620 } 621 622 /* 623 * If we caught a signal, we have retried and now 624 * exit immediately. 625 */ 626 if (error != 0) 627 return (error); 628 629 if ((error = umtx_key_get(umtx, TYPE_SIMPLE_LOCK, 630 AUTO_SHARE, &uq->uq_key)) != 0) 631 return (error); 632 633 umtxq_lock(&uq->uq_key); 634 umtxq_busy(&uq->uq_key); 635 umtxq_insert(uq); 636 umtxq_unbusy(&uq->uq_key); 637 umtxq_unlock(&uq->uq_key); 638 639 /* 640 * Set the contested bit so that a release in user space 641 * knows to use the system call for unlock. If this fails 642 * either some one else has acquired the lock or it has been 643 * released. 644 */ 645 old = casuword(&umtx->u_owner, owner, owner | UMTX_CONTESTED); 646 647 /* The address was invalid. */ 648 if (old == -1) { 649 umtxq_lock(&uq->uq_key); 650 umtxq_remove(uq); 651 umtxq_unlock(&uq->uq_key); 652 umtx_key_release(&uq->uq_key); 653 return (EFAULT); 654 } 655 656 /* 657 * We set the contested bit, sleep. Otherwise the lock changed 658 * and we need to retry or we lost a race to the thread 659 * unlocking the umtx. 660 */ 661 umtxq_lock(&uq->uq_key); 662 if (old == owner) 663 error = umtxq_sleep(uq, "umtx", timo); 664 umtxq_remove(uq); 665 umtxq_unlock(&uq->uq_key); 666 umtx_key_release(&uq->uq_key); 667 } 668 669 return (0); 670 } 671 672 /* 673 * Lock a umtx object. 674 */ 675 static int 676 do_lock_umtx(struct thread *td, struct umtx *umtx, u_long id, 677 struct timespec *timeout) 678 { 679 struct timespec ts, ts2, ts3; 680 struct timeval tv; 681 int error; 682 683 if (timeout == NULL) { 684 error = _do_lock_umtx(td, umtx, id, 0); 685 /* Mutex locking is restarted if it is interrupted. */ 686 if (error == EINTR) 687 error = ERESTART; 688 } else { 689 getnanouptime(&ts); 690 timespecadd(&ts, timeout); 691 TIMESPEC_TO_TIMEVAL(&tv, timeout); 692 for (;;) { 693 error = _do_lock_umtx(td, umtx, id, tvtohz(&tv)); 694 if (error != ETIMEDOUT) 695 break; 696 getnanouptime(&ts2); 697 if (timespeccmp(&ts2, &ts, >=)) { 698 error = ETIMEDOUT; 699 break; 700 } 701 ts3 = ts; 702 timespecsub(&ts3, &ts2); 703 TIMESPEC_TO_TIMEVAL(&tv, &ts3); 704 } 705 /* Timed-locking is not restarted. */ 706 if (error == ERESTART) 707 error = EINTR; 708 } 709 return (error); 710 } 711 712 /* 713 * Unlock a umtx object. 714 */ 715 static int 716 do_unlock_umtx(struct thread *td, struct umtx *umtx, u_long id) 717 { 718 struct umtx_key key; 719 u_long owner; 720 u_long old; 721 int error; 722 int count; 723 724 /* 725 * Make sure we own this mtx. 726 */ 727 owner = fuword(__DEVOLATILE(u_long *, &umtx->u_owner)); 728 if (owner == -1) 729 return (EFAULT); 730 731 if ((owner & ~UMTX_CONTESTED) != id) 732 return (EPERM); 733 734 /* This should be done in userland */ 735 if ((owner & UMTX_CONTESTED) == 0) { 736 old = casuword(&umtx->u_owner, owner, UMTX_UNOWNED); 737 if (old == -1) 738 return (EFAULT); 739 if (old == owner) 740 return (0); 741 owner = old; 742 } 743 744 /* We should only ever be in here for contested locks */ 745 if ((error = umtx_key_get(umtx, TYPE_SIMPLE_LOCK, AUTO_SHARE, 746 &key)) != 0) 747 return (error); 748 749 umtxq_lock(&key); 750 umtxq_busy(&key); 751 count = umtxq_count(&key); 752 umtxq_unlock(&key); 753 754 /* 755 * When unlocking the umtx, it must be marked as unowned if 756 * there is zero or one thread only waiting for it. 757 * Otherwise, it must be marked as contested. 758 */ 759 old = casuword(&umtx->u_owner, owner, 760 count <= 1 ? UMTX_UNOWNED : UMTX_CONTESTED); 761 umtxq_lock(&key); 762 umtxq_signal(&key,1); 763 umtxq_unbusy(&key); 764 umtxq_unlock(&key); 765 umtx_key_release(&key); 766 if (old == -1) 767 return (EFAULT); 768 if (old != owner) 769 return (EINVAL); 770 return (0); 771 } 772 773 #ifdef COMPAT_FREEBSD32 774 775 /* 776 * Lock a umtx object. 777 */ 778 static int 779 _do_lock_umtx32(struct thread *td, uint32_t *m, uint32_t id, int timo) 780 { 781 struct umtx_q *uq; 782 uint32_t owner; 783 uint32_t old; 784 int error = 0; 785 786 uq = td->td_umtxq; 787 788 /* 789 * Care must be exercised when dealing with umtx structure. It 790 * can fault on any access. 791 */ 792 for (;;) { 793 /* 794 * Try the uncontested case. This should be done in userland. 795 */ 796 owner = casuword32(m, UMUTEX_UNOWNED, id); 797 798 /* The acquire succeeded. */ 799 if (owner == UMUTEX_UNOWNED) 800 return (0); 801 802 /* The address was invalid. */ 803 if (owner == -1) 804 return (EFAULT); 805 806 /* If no one owns it but it is contested try to acquire it. */ 807 if (owner == UMUTEX_CONTESTED) { 808 owner = casuword32(m, 809 UMUTEX_CONTESTED, id | UMUTEX_CONTESTED); 810 if (owner == UMUTEX_CONTESTED) 811 return (0); 812 813 /* The address was invalid. */ 814 if (owner == -1) 815 return (EFAULT); 816 817 /* If this failed the lock has changed, restart. */ 818 continue; 819 } 820 821 /* 822 * If we caught a signal, we have retried and now 823 * exit immediately. 824 */ 825 if (error != 0) 826 return (error); 827 828 if ((error = umtx_key_get(m, TYPE_SIMPLE_LOCK, 829 AUTO_SHARE, &uq->uq_key)) != 0) 830 return (error); 831 832 umtxq_lock(&uq->uq_key); 833 umtxq_busy(&uq->uq_key); 834 umtxq_insert(uq); 835 umtxq_unbusy(&uq->uq_key); 836 umtxq_unlock(&uq->uq_key); 837 838 /* 839 * Set the contested bit so that a release in user space 840 * knows to use the system call for unlock. If this fails 841 * either some one else has acquired the lock or it has been 842 * released. 843 */ 844 old = casuword32(m, owner, owner | UMUTEX_CONTESTED); 845 846 /* The address was invalid. */ 847 if (old == -1) { 848 umtxq_lock(&uq->uq_key); 849 umtxq_remove(uq); 850 umtxq_unlock(&uq->uq_key); 851 umtx_key_release(&uq->uq_key); 852 return (EFAULT); 853 } 854 855 /* 856 * We set the contested bit, sleep. Otherwise the lock changed 857 * and we need to retry or we lost a race to the thread 858 * unlocking the umtx. 859 */ 860 umtxq_lock(&uq->uq_key); 861 if (old == owner) 862 error = umtxq_sleep(uq, "umtx", timo); 863 umtxq_remove(uq); 864 umtxq_unlock(&uq->uq_key); 865 umtx_key_release(&uq->uq_key); 866 } 867 868 return (0); 869 } 870 871 /* 872 * Lock a umtx object. 873 */ 874 static int 875 do_lock_umtx32(struct thread *td, void *m, uint32_t id, 876 struct timespec *timeout) 877 { 878 struct timespec ts, ts2, ts3; 879 struct timeval tv; 880 int error; 881 882 if (timeout == NULL) { 883 error = _do_lock_umtx32(td, m, id, 0); 884 /* Mutex locking is restarted if it is interrupted. */ 885 if (error == EINTR) 886 error = ERESTART; 887 } else { 888 getnanouptime(&ts); 889 timespecadd(&ts, timeout); 890 TIMESPEC_TO_TIMEVAL(&tv, timeout); 891 for (;;) { 892 error = _do_lock_umtx32(td, m, id, tvtohz(&tv)); 893 if (error != ETIMEDOUT) 894 break; 895 getnanouptime(&ts2); 896 if (timespeccmp(&ts2, &ts, >=)) { 897 error = ETIMEDOUT; 898 break; 899 } 900 ts3 = ts; 901 timespecsub(&ts3, &ts2); 902 TIMESPEC_TO_TIMEVAL(&tv, &ts3); 903 } 904 /* Timed-locking is not restarted. */ 905 if (error == ERESTART) 906 error = EINTR; 907 } 908 return (error); 909 } 910 911 /* 912 * Unlock a umtx object. 913 */ 914 static int 915 do_unlock_umtx32(struct thread *td, uint32_t *m, uint32_t id) 916 { 917 struct umtx_key key; 918 uint32_t owner; 919 uint32_t old; 920 int error; 921 int count; 922 923 /* 924 * Make sure we own this mtx. 925 */ 926 owner = fuword32(m); 927 if (owner == -1) 928 return (EFAULT); 929 930 if ((owner & ~UMUTEX_CONTESTED) != id) 931 return (EPERM); 932 933 /* This should be done in userland */ 934 if ((owner & UMUTEX_CONTESTED) == 0) { 935 old = casuword32(m, owner, UMUTEX_UNOWNED); 936 if (old == -1) 937 return (EFAULT); 938 if (old == owner) 939 return (0); 940 owner = old; 941 } 942 943 /* We should only ever be in here for contested locks */ 944 if ((error = umtx_key_get(m, TYPE_SIMPLE_LOCK, AUTO_SHARE, 945 &key)) != 0) 946 return (error); 947 948 umtxq_lock(&key); 949 umtxq_busy(&key); 950 count = umtxq_count(&key); 951 umtxq_unlock(&key); 952 953 /* 954 * When unlocking the umtx, it must be marked as unowned if 955 * there is zero or one thread only waiting for it. 956 * Otherwise, it must be marked as contested. 957 */ 958 old = casuword32(m, owner, 959 count <= 1 ? UMUTEX_UNOWNED : UMUTEX_CONTESTED); 960 umtxq_lock(&key); 961 umtxq_signal(&key,1); 962 umtxq_unbusy(&key); 963 umtxq_unlock(&key); 964 umtx_key_release(&key); 965 if (old == -1) 966 return (EFAULT); 967 if (old != owner) 968 return (EINVAL); 969 return (0); 970 } 971 #endif 972 973 /* 974 * Fetch and compare value, sleep on the address if value is not changed. 975 */ 976 static int 977 do_wait(struct thread *td, void *addr, u_long id, 978 struct timespec *timeout, int compat32, int is_private) 979 { 980 struct umtx_q *uq; 981 struct timespec ts, ts2, ts3; 982 struct timeval tv; 983 u_long tmp; 984 int error = 0; 985 986 uq = td->td_umtxq; 987 if ((error = umtx_key_get(addr, TYPE_SIMPLE_WAIT, 988 is_private ? THREAD_SHARE : AUTO_SHARE, &uq->uq_key)) != 0) 989 return (error); 990 991 umtxq_lock(&uq->uq_key); 992 umtxq_insert(uq); 993 umtxq_unlock(&uq->uq_key); 994 if (compat32 == 0) 995 tmp = fuword(addr); 996 else 997 tmp = (unsigned int)fuword32(addr); 998 if (tmp != id) { 999 umtxq_lock(&uq->uq_key); 1000 umtxq_remove(uq); 1001 umtxq_unlock(&uq->uq_key); 1002 } else if (timeout == NULL) { 1003 umtxq_lock(&uq->uq_key); 1004 error = umtxq_sleep(uq, "uwait", 0); 1005 umtxq_remove(uq); 1006 umtxq_unlock(&uq->uq_key); 1007 } else { 1008 getnanouptime(&ts); 1009 timespecadd(&ts, timeout); 1010 TIMESPEC_TO_TIMEVAL(&tv, timeout); 1011 umtxq_lock(&uq->uq_key); 1012 for (;;) { 1013 error = umtxq_sleep(uq, "uwait", tvtohz(&tv)); 1014 if (!(uq->uq_flags & UQF_UMTXQ)) { 1015 error = 0; 1016 break; 1017 } 1018 if (error != ETIMEDOUT) 1019 break; 1020 umtxq_unlock(&uq->uq_key); 1021 getnanouptime(&ts2); 1022 if (timespeccmp(&ts2, &ts, >=)) { 1023 error = ETIMEDOUT; 1024 umtxq_lock(&uq->uq_key); 1025 break; 1026 } 1027 ts3 = ts; 1028 timespecsub(&ts3, &ts2); 1029 TIMESPEC_TO_TIMEVAL(&tv, &ts3); 1030 umtxq_lock(&uq->uq_key); 1031 } 1032 umtxq_remove(uq); 1033 umtxq_unlock(&uq->uq_key); 1034 } 1035 umtx_key_release(&uq->uq_key); 1036 if (error == ERESTART) 1037 error = EINTR; 1038 return (error); 1039 } 1040 1041 /* 1042 * Wake up threads sleeping on the specified address. 1043 */ 1044 int 1045 kern_umtx_wake(struct thread *td, void *uaddr, int n_wake, int is_private) 1046 { 1047 struct umtx_key key; 1048 int ret; 1049 1050 if ((ret = umtx_key_get(uaddr, TYPE_SIMPLE_WAIT, 1051 is_private ? THREAD_SHARE : AUTO_SHARE, &key)) != 0) 1052 return (ret); 1053 umtxq_lock(&key); 1054 ret = umtxq_signal(&key, n_wake); 1055 umtxq_unlock(&key); 1056 umtx_key_release(&key); 1057 return (0); 1058 } 1059 1060 /* 1061 * Lock PTHREAD_PRIO_NONE protocol POSIX mutex. 1062 */ 1063 static int 1064 _do_lock_normal(struct thread *td, struct umutex *m, uint32_t flags, int timo, 1065 int mode) 1066 { 1067 struct umtx_q *uq; 1068 uint32_t owner, old, id; 1069 int error = 0; 1070 1071 id = td->td_tid; 1072 uq = td->td_umtxq; 1073 1074 /* 1075 * Care must be exercised when dealing with umtx structure. It 1076 * can fault on any access. 1077 */ 1078 for (;;) { 1079 owner = fuword32(__DEVOLATILE(void *, &m->m_owner)); 1080 if (mode == _UMUTEX_WAIT) { 1081 if (owner == UMUTEX_UNOWNED || owner == UMUTEX_CONTESTED) 1082 return (0); 1083 } else { 1084 /* 1085 * Try the uncontested case. This should be done in userland. 1086 */ 1087 owner = casuword32(&m->m_owner, UMUTEX_UNOWNED, id); 1088 1089 /* The acquire succeeded. */ 1090 if (owner == UMUTEX_UNOWNED) 1091 return (0); 1092 1093 /* The address was invalid. */ 1094 if (owner == -1) 1095 return (EFAULT); 1096 1097 /* If no one owns it but it is contested try to acquire it. */ 1098 if (owner == UMUTEX_CONTESTED) { 1099 owner = casuword32(&m->m_owner, 1100 UMUTEX_CONTESTED, id | UMUTEX_CONTESTED); 1101 1102 if (owner == UMUTEX_CONTESTED) 1103 return (0); 1104 1105 /* The address was invalid. */ 1106 if (owner == -1) 1107 return (EFAULT); 1108 1109 /* If this failed the lock has changed, restart. */ 1110 continue; 1111 } 1112 } 1113 1114 if ((flags & UMUTEX_ERROR_CHECK) != 0 && 1115 (owner & ~UMUTEX_CONTESTED) == id) 1116 return (EDEADLK); 1117 1118 if (mode == _UMUTEX_TRY) 1119 return (EBUSY); 1120 1121 /* 1122 * If we caught a signal, we have retried and now 1123 * exit immediately. 1124 */ 1125 if (error != 0) 1126 return (error); 1127 1128 if ((error = umtx_key_get(m, TYPE_NORMAL_UMUTEX, 1129 GET_SHARE(flags), &uq->uq_key)) != 0) 1130 return (error); 1131 1132 umtxq_lock(&uq->uq_key); 1133 umtxq_busy(&uq->uq_key); 1134 umtxq_insert(uq); 1135 umtxq_unlock(&uq->uq_key); 1136 1137 /* 1138 * Set the contested bit so that a release in user space 1139 * knows to use the system call for unlock. If this fails 1140 * either some one else has acquired the lock or it has been 1141 * released. 1142 */ 1143 old = casuword32(&m->m_owner, owner, owner | UMUTEX_CONTESTED); 1144 1145 /* The address was invalid. */ 1146 if (old == -1) { 1147 umtxq_lock(&uq->uq_key); 1148 umtxq_remove(uq); 1149 umtxq_unbusy(&uq->uq_key); 1150 umtxq_unlock(&uq->uq_key); 1151 umtx_key_release(&uq->uq_key); 1152 return (EFAULT); 1153 } 1154 1155 /* 1156 * We set the contested bit, sleep. Otherwise the lock changed 1157 * and we need to retry or we lost a race to the thread 1158 * unlocking the umtx. 1159 */ 1160 umtxq_lock(&uq->uq_key); 1161 umtxq_unbusy(&uq->uq_key); 1162 if (old == owner) 1163 error = umtxq_sleep(uq, "umtxn", timo); 1164 umtxq_remove(uq); 1165 umtxq_unlock(&uq->uq_key); 1166 umtx_key_release(&uq->uq_key); 1167 } 1168 1169 return (0); 1170 } 1171 1172 /* 1173 * Lock PTHREAD_PRIO_NONE protocol POSIX mutex. 1174 */ 1175 /* 1176 * Unlock PTHREAD_PRIO_NONE protocol POSIX mutex. 1177 */ 1178 static int 1179 do_unlock_normal(struct thread *td, struct umutex *m, uint32_t flags) 1180 { 1181 struct umtx_key key; 1182 uint32_t owner, old, id; 1183 int error; 1184 int count; 1185 1186 id = td->td_tid; 1187 /* 1188 * Make sure we own this mtx. 1189 */ 1190 owner = fuword32(__DEVOLATILE(uint32_t *, &m->m_owner)); 1191 if (owner == -1) 1192 return (EFAULT); 1193 1194 if ((owner & ~UMUTEX_CONTESTED) != id) 1195 return (EPERM); 1196 1197 if ((owner & UMUTEX_CONTESTED) == 0) { 1198 old = casuword32(&m->m_owner, owner, UMUTEX_UNOWNED); 1199 if (old == -1) 1200 return (EFAULT); 1201 if (old == owner) 1202 return (0); 1203 owner = old; 1204 } 1205 1206 /* We should only ever be in here for contested locks */ 1207 if ((error = umtx_key_get(m, TYPE_NORMAL_UMUTEX, GET_SHARE(flags), 1208 &key)) != 0) 1209 return (error); 1210 1211 umtxq_lock(&key); 1212 umtxq_busy(&key); 1213 count = umtxq_count(&key); 1214 umtxq_unlock(&key); 1215 1216 /* 1217 * When unlocking the umtx, it must be marked as unowned if 1218 * there is zero or one thread only waiting for it. 1219 * Otherwise, it must be marked as contested. 1220 */ 1221 old = casuword32(&m->m_owner, owner, 1222 count <= 1 ? UMUTEX_UNOWNED : UMUTEX_CONTESTED); 1223 umtxq_lock(&key); 1224 umtxq_signal(&key,1); 1225 umtxq_unbusy(&key); 1226 umtxq_unlock(&key); 1227 umtx_key_release(&key); 1228 if (old == -1) 1229 return (EFAULT); 1230 if (old != owner) 1231 return (EINVAL); 1232 return (0); 1233 } 1234 1235 /* 1236 * Check if the mutex is available and wake up a waiter, 1237 * only for simple mutex. 1238 */ 1239 static int 1240 do_wake_umutex(struct thread *td, struct umutex *m) 1241 { 1242 struct umtx_key key; 1243 uint32_t owner; 1244 uint32_t flags; 1245 int error; 1246 int count; 1247 1248 owner = fuword32(__DEVOLATILE(uint32_t *, &m->m_owner)); 1249 if (owner == -1) 1250 return (EFAULT); 1251 1252 if ((owner & ~UMUTEX_CONTESTED) != 0) 1253 return (0); 1254 1255 flags = fuword32(&m->m_flags); 1256 1257 /* We should only ever be in here for contested locks */ 1258 if ((error = umtx_key_get(m, TYPE_NORMAL_UMUTEX, GET_SHARE(flags), 1259 &key)) != 0) 1260 return (error); 1261 1262 umtxq_lock(&key); 1263 umtxq_busy(&key); 1264 count = umtxq_count(&key); 1265 umtxq_unlock(&key); 1266 1267 if (count <= 1) 1268 owner = casuword32(&m->m_owner, UMUTEX_CONTESTED, UMUTEX_UNOWNED); 1269 1270 umtxq_lock(&key); 1271 if (count != 0 && (owner & ~UMUTEX_CONTESTED) == 0) 1272 umtxq_signal(&key, 1); 1273 umtxq_unbusy(&key); 1274 umtxq_unlock(&key); 1275 umtx_key_release(&key); 1276 return (0); 1277 } 1278 1279 static inline struct umtx_pi * 1280 umtx_pi_alloc(int flags) 1281 { 1282 struct umtx_pi *pi; 1283 1284 pi = uma_zalloc(umtx_pi_zone, M_ZERO | flags); 1285 TAILQ_INIT(&pi->pi_blocked); 1286 atomic_add_int(&umtx_pi_allocated, 1); 1287 return (pi); 1288 } 1289 1290 static inline void 1291 umtx_pi_free(struct umtx_pi *pi) 1292 { 1293 uma_zfree(umtx_pi_zone, pi); 1294 atomic_add_int(&umtx_pi_allocated, -1); 1295 } 1296 1297 /* 1298 * Adjust the thread's position on a pi_state after its priority has been 1299 * changed. 1300 */ 1301 static int 1302 umtx_pi_adjust_thread(struct umtx_pi *pi, struct thread *td) 1303 { 1304 struct umtx_q *uq, *uq1, *uq2; 1305 struct thread *td1; 1306 1307 mtx_assert(&umtx_lock, MA_OWNED); 1308 if (pi == NULL) 1309 return (0); 1310 1311 uq = td->td_umtxq; 1312 1313 /* 1314 * Check if the thread needs to be moved on the blocked chain. 1315 * It needs to be moved if either its priority is lower than 1316 * the previous thread or higher than the next thread. 1317 */ 1318 uq1 = TAILQ_PREV(uq, umtxq_head, uq_lockq); 1319 uq2 = TAILQ_NEXT(uq, uq_lockq); 1320 if ((uq1 != NULL && UPRI(td) < UPRI(uq1->uq_thread)) || 1321 (uq2 != NULL && UPRI(td) > UPRI(uq2->uq_thread))) { 1322 /* 1323 * Remove thread from blocked chain and determine where 1324 * it should be moved to. 1325 */ 1326 TAILQ_REMOVE(&pi->pi_blocked, uq, uq_lockq); 1327 TAILQ_FOREACH(uq1, &pi->pi_blocked, uq_lockq) { 1328 td1 = uq1->uq_thread; 1329 MPASS(td1->td_proc->p_magic == P_MAGIC); 1330 if (UPRI(td1) > UPRI(td)) 1331 break; 1332 } 1333 1334 if (uq1 == NULL) 1335 TAILQ_INSERT_TAIL(&pi->pi_blocked, uq, uq_lockq); 1336 else 1337 TAILQ_INSERT_BEFORE(uq1, uq, uq_lockq); 1338 } 1339 return (1); 1340 } 1341 1342 /* 1343 * Propagate priority when a thread is blocked on POSIX 1344 * PI mutex. 1345 */ 1346 static void 1347 umtx_propagate_priority(struct thread *td) 1348 { 1349 struct umtx_q *uq; 1350 struct umtx_pi *pi; 1351 int pri; 1352 1353 mtx_assert(&umtx_lock, MA_OWNED); 1354 pri = UPRI(td); 1355 uq = td->td_umtxq; 1356 pi = uq->uq_pi_blocked; 1357 if (pi == NULL) 1358 return; 1359 1360 for (;;) { 1361 td = pi->pi_owner; 1362 if (td == NULL || td == curthread) 1363 return; 1364 1365 MPASS(td->td_proc != NULL); 1366 MPASS(td->td_proc->p_magic == P_MAGIC); 1367 1368 thread_lock(td); 1369 if (td->td_lend_user_pri > pri) 1370 sched_lend_user_prio(td, pri); 1371 else { 1372 thread_unlock(td); 1373 break; 1374 } 1375 thread_unlock(td); 1376 1377 /* 1378 * Pick up the lock that td is blocked on. 1379 */ 1380 uq = td->td_umtxq; 1381 pi = uq->uq_pi_blocked; 1382 if (pi == NULL) 1383 break; 1384 /* Resort td on the list if needed. */ 1385 umtx_pi_adjust_thread(pi, td); 1386 } 1387 } 1388 1389 /* 1390 * Unpropagate priority for a PI mutex when a thread blocked on 1391 * it is interrupted by signal or resumed by others. 1392 */ 1393 static void 1394 umtx_repropagate_priority(struct umtx_pi *pi) 1395 { 1396 struct umtx_q *uq, *uq_owner; 1397 struct umtx_pi *pi2; 1398 int pri; 1399 1400 mtx_assert(&umtx_lock, MA_OWNED); 1401 1402 while (pi != NULL && pi->pi_owner != NULL) { 1403 pri = PRI_MAX; 1404 uq_owner = pi->pi_owner->td_umtxq; 1405 1406 TAILQ_FOREACH(pi2, &uq_owner->uq_pi_contested, pi_link) { 1407 uq = TAILQ_FIRST(&pi2->pi_blocked); 1408 if (uq != NULL) { 1409 if (pri > UPRI(uq->uq_thread)) 1410 pri = UPRI(uq->uq_thread); 1411 } 1412 } 1413 1414 if (pri > uq_owner->uq_inherited_pri) 1415 pri = uq_owner->uq_inherited_pri; 1416 thread_lock(pi->pi_owner); 1417 sched_lend_user_prio(pi->pi_owner, pri); 1418 thread_unlock(pi->pi_owner); 1419 if ((pi = uq_owner->uq_pi_blocked) != NULL) 1420 umtx_pi_adjust_thread(pi, uq_owner->uq_thread); 1421 } 1422 } 1423 1424 /* 1425 * Insert a PI mutex into owned list. 1426 */ 1427 static void 1428 umtx_pi_setowner(struct umtx_pi *pi, struct thread *owner) 1429 { 1430 struct umtx_q *uq_owner; 1431 1432 uq_owner = owner->td_umtxq; 1433 mtx_assert(&umtx_lock, MA_OWNED); 1434 if (pi->pi_owner != NULL) 1435 panic("pi_ower != NULL"); 1436 pi->pi_owner = owner; 1437 TAILQ_INSERT_TAIL(&uq_owner->uq_pi_contested, pi, pi_link); 1438 } 1439 1440 /* 1441 * Claim ownership of a PI mutex. 1442 */ 1443 static int 1444 umtx_pi_claim(struct umtx_pi *pi, struct thread *owner) 1445 { 1446 struct umtx_q *uq, *uq_owner; 1447 1448 uq_owner = owner->td_umtxq; 1449 mtx_lock_spin(&umtx_lock); 1450 if (pi->pi_owner == owner) { 1451 mtx_unlock_spin(&umtx_lock); 1452 return (0); 1453 } 1454 1455 if (pi->pi_owner != NULL) { 1456 /* 1457 * userland may have already messed the mutex, sigh. 1458 */ 1459 mtx_unlock_spin(&umtx_lock); 1460 return (EPERM); 1461 } 1462 umtx_pi_setowner(pi, owner); 1463 uq = TAILQ_FIRST(&pi->pi_blocked); 1464 if (uq != NULL) { 1465 int pri; 1466 1467 pri = UPRI(uq->uq_thread); 1468 thread_lock(owner); 1469 if (pri < UPRI(owner)) 1470 sched_lend_user_prio(owner, pri); 1471 thread_unlock(owner); 1472 } 1473 mtx_unlock_spin(&umtx_lock); 1474 return (0); 1475 } 1476 1477 /* 1478 * Adjust a thread's order position in its blocked PI mutex, 1479 * this may result new priority propagating process. 1480 */ 1481 void 1482 umtx_pi_adjust(struct thread *td, u_char oldpri) 1483 { 1484 struct umtx_q *uq; 1485 struct umtx_pi *pi; 1486 1487 uq = td->td_umtxq; 1488 mtx_lock_spin(&umtx_lock); 1489 /* 1490 * Pick up the lock that td is blocked on. 1491 */ 1492 pi = uq->uq_pi_blocked; 1493 if (pi != NULL) { 1494 umtx_pi_adjust_thread(pi, td); 1495 umtx_repropagate_priority(pi); 1496 } 1497 mtx_unlock_spin(&umtx_lock); 1498 } 1499 1500 /* 1501 * Sleep on a PI mutex. 1502 */ 1503 static int 1504 umtxq_sleep_pi(struct umtx_q *uq, struct umtx_pi *pi, 1505 uint32_t owner, const char *wmesg, int timo) 1506 { 1507 struct umtxq_chain *uc; 1508 struct thread *td, *td1; 1509 struct umtx_q *uq1; 1510 int pri; 1511 int error = 0; 1512 1513 td = uq->uq_thread; 1514 KASSERT(td == curthread, ("inconsistent uq_thread")); 1515 uc = umtxq_getchain(&uq->uq_key); 1516 UMTXQ_LOCKED_ASSERT(uc); 1517 UMTXQ_BUSY_ASSERT(uc); 1518 umtxq_insert(uq); 1519 mtx_lock_spin(&umtx_lock); 1520 if (pi->pi_owner == NULL) { 1521 mtx_unlock_spin(&umtx_lock); 1522 /* XXX Only look up thread in current process. */ 1523 td1 = tdfind(owner, curproc->p_pid); 1524 mtx_lock_spin(&umtx_lock); 1525 if (td1 != NULL) { 1526 if (pi->pi_owner == NULL) 1527 umtx_pi_setowner(pi, td1); 1528 PROC_UNLOCK(td1->td_proc); 1529 } 1530 } 1531 1532 TAILQ_FOREACH(uq1, &pi->pi_blocked, uq_lockq) { 1533 pri = UPRI(uq1->uq_thread); 1534 if (pri > UPRI(td)) 1535 break; 1536 } 1537 1538 if (uq1 != NULL) 1539 TAILQ_INSERT_BEFORE(uq1, uq, uq_lockq); 1540 else 1541 TAILQ_INSERT_TAIL(&pi->pi_blocked, uq, uq_lockq); 1542 1543 uq->uq_pi_blocked = pi; 1544 thread_lock(td); 1545 td->td_flags |= TDF_UPIBLOCKED; 1546 thread_unlock(td); 1547 umtx_propagate_priority(td); 1548 mtx_unlock_spin(&umtx_lock); 1549 umtxq_unbusy(&uq->uq_key); 1550 1551 if (uq->uq_flags & UQF_UMTXQ) { 1552 error = msleep(uq, &uc->uc_lock, PCATCH, wmesg, timo); 1553 if (error == EWOULDBLOCK) 1554 error = ETIMEDOUT; 1555 if (uq->uq_flags & UQF_UMTXQ) { 1556 umtxq_remove(uq); 1557 } 1558 } 1559 mtx_lock_spin(&umtx_lock); 1560 uq->uq_pi_blocked = NULL; 1561 thread_lock(td); 1562 td->td_flags &= ~TDF_UPIBLOCKED; 1563 thread_unlock(td); 1564 TAILQ_REMOVE(&pi->pi_blocked, uq, uq_lockq); 1565 umtx_repropagate_priority(pi); 1566 mtx_unlock_spin(&umtx_lock); 1567 umtxq_unlock(&uq->uq_key); 1568 1569 return (error); 1570 } 1571 1572 /* 1573 * Add reference count for a PI mutex. 1574 */ 1575 static void 1576 umtx_pi_ref(struct umtx_pi *pi) 1577 { 1578 struct umtxq_chain *uc; 1579 1580 uc = umtxq_getchain(&pi->pi_key); 1581 UMTXQ_LOCKED_ASSERT(uc); 1582 pi->pi_refcount++; 1583 } 1584 1585 /* 1586 * Decrease reference count for a PI mutex, if the counter 1587 * is decreased to zero, its memory space is freed. 1588 */ 1589 static void 1590 umtx_pi_unref(struct umtx_pi *pi) 1591 { 1592 struct umtxq_chain *uc; 1593 1594 uc = umtxq_getchain(&pi->pi_key); 1595 UMTXQ_LOCKED_ASSERT(uc); 1596 KASSERT(pi->pi_refcount > 0, ("invalid reference count")); 1597 if (--pi->pi_refcount == 0) { 1598 mtx_lock_spin(&umtx_lock); 1599 if (pi->pi_owner != NULL) { 1600 TAILQ_REMOVE(&pi->pi_owner->td_umtxq->uq_pi_contested, 1601 pi, pi_link); 1602 pi->pi_owner = NULL; 1603 } 1604 KASSERT(TAILQ_EMPTY(&pi->pi_blocked), 1605 ("blocked queue not empty")); 1606 mtx_unlock_spin(&umtx_lock); 1607 TAILQ_REMOVE(&uc->uc_pi_list, pi, pi_hashlink); 1608 umtx_pi_free(pi); 1609 } 1610 } 1611 1612 /* 1613 * Find a PI mutex in hash table. 1614 */ 1615 static struct umtx_pi * 1616 umtx_pi_lookup(struct umtx_key *key) 1617 { 1618 struct umtxq_chain *uc; 1619 struct umtx_pi *pi; 1620 1621 uc = umtxq_getchain(key); 1622 UMTXQ_LOCKED_ASSERT(uc); 1623 1624 TAILQ_FOREACH(pi, &uc->uc_pi_list, pi_hashlink) { 1625 if (umtx_key_match(&pi->pi_key, key)) { 1626 return (pi); 1627 } 1628 } 1629 return (NULL); 1630 } 1631 1632 /* 1633 * Insert a PI mutex into hash table. 1634 */ 1635 static inline void 1636 umtx_pi_insert(struct umtx_pi *pi) 1637 { 1638 struct umtxq_chain *uc; 1639 1640 uc = umtxq_getchain(&pi->pi_key); 1641 UMTXQ_LOCKED_ASSERT(uc); 1642 TAILQ_INSERT_TAIL(&uc->uc_pi_list, pi, pi_hashlink); 1643 } 1644 1645 /* 1646 * Lock a PI mutex. 1647 */ 1648 static int 1649 _do_lock_pi(struct thread *td, struct umutex *m, uint32_t flags, int timo, 1650 int try) 1651 { 1652 struct umtx_q *uq; 1653 struct umtx_pi *pi, *new_pi; 1654 uint32_t id, owner, old; 1655 int error; 1656 1657 id = td->td_tid; 1658 uq = td->td_umtxq; 1659 1660 if ((error = umtx_key_get(m, TYPE_PI_UMUTEX, GET_SHARE(flags), 1661 &uq->uq_key)) != 0) 1662 return (error); 1663 umtxq_lock(&uq->uq_key); 1664 pi = umtx_pi_lookup(&uq->uq_key); 1665 if (pi == NULL) { 1666 new_pi = umtx_pi_alloc(M_NOWAIT); 1667 if (new_pi == NULL) { 1668 umtxq_unlock(&uq->uq_key); 1669 new_pi = umtx_pi_alloc(M_WAITOK); 1670 umtxq_lock(&uq->uq_key); 1671 pi = umtx_pi_lookup(&uq->uq_key); 1672 if (pi != NULL) { 1673 umtx_pi_free(new_pi); 1674 new_pi = NULL; 1675 } 1676 } 1677 if (new_pi != NULL) { 1678 new_pi->pi_key = uq->uq_key; 1679 umtx_pi_insert(new_pi); 1680 pi = new_pi; 1681 } 1682 } 1683 umtx_pi_ref(pi); 1684 umtxq_unlock(&uq->uq_key); 1685 1686 /* 1687 * Care must be exercised when dealing with umtx structure. It 1688 * can fault on any access. 1689 */ 1690 for (;;) { 1691 /* 1692 * Try the uncontested case. This should be done in userland. 1693 */ 1694 owner = casuword32(&m->m_owner, UMUTEX_UNOWNED, id); 1695 1696 /* The acquire succeeded. */ 1697 if (owner == UMUTEX_UNOWNED) { 1698 error = 0; 1699 break; 1700 } 1701 1702 /* The address was invalid. */ 1703 if (owner == -1) { 1704 error = EFAULT; 1705 break; 1706 } 1707 1708 /* If no one owns it but it is contested try to acquire it. */ 1709 if (owner == UMUTEX_CONTESTED) { 1710 owner = casuword32(&m->m_owner, 1711 UMUTEX_CONTESTED, id | UMUTEX_CONTESTED); 1712 1713 if (owner == UMUTEX_CONTESTED) { 1714 umtxq_lock(&uq->uq_key); 1715 umtxq_busy(&uq->uq_key); 1716 error = umtx_pi_claim(pi, td); 1717 umtxq_unbusy(&uq->uq_key); 1718 umtxq_unlock(&uq->uq_key); 1719 break; 1720 } 1721 1722 /* The address was invalid. */ 1723 if (owner == -1) { 1724 error = EFAULT; 1725 break; 1726 } 1727 1728 /* If this failed the lock has changed, restart. */ 1729 continue; 1730 } 1731 1732 if ((flags & UMUTEX_ERROR_CHECK) != 0 && 1733 (owner & ~UMUTEX_CONTESTED) == id) { 1734 error = EDEADLK; 1735 break; 1736 } 1737 1738 if (try != 0) { 1739 error = EBUSY; 1740 break; 1741 } 1742 1743 /* 1744 * If we caught a signal, we have retried and now 1745 * exit immediately. 1746 */ 1747 if (error != 0) 1748 break; 1749 1750 umtxq_lock(&uq->uq_key); 1751 umtxq_busy(&uq->uq_key); 1752 umtxq_unlock(&uq->uq_key); 1753 1754 /* 1755 * Set the contested bit so that a release in user space 1756 * knows to use the system call for unlock. If this fails 1757 * either some one else has acquired the lock or it has been 1758 * released. 1759 */ 1760 old = casuword32(&m->m_owner, owner, owner | UMUTEX_CONTESTED); 1761 1762 /* The address was invalid. */ 1763 if (old == -1) { 1764 umtxq_lock(&uq->uq_key); 1765 umtxq_unbusy(&uq->uq_key); 1766 umtxq_unlock(&uq->uq_key); 1767 error = EFAULT; 1768 break; 1769 } 1770 1771 umtxq_lock(&uq->uq_key); 1772 /* 1773 * We set the contested bit, sleep. Otherwise the lock changed 1774 * and we need to retry or we lost a race to the thread 1775 * unlocking the umtx. 1776 */ 1777 if (old == owner) 1778 error = umtxq_sleep_pi(uq, pi, owner & ~UMUTEX_CONTESTED, 1779 "umtxpi", timo); 1780 else { 1781 umtxq_unbusy(&uq->uq_key); 1782 umtxq_unlock(&uq->uq_key); 1783 } 1784 } 1785 1786 umtxq_lock(&uq->uq_key); 1787 umtx_pi_unref(pi); 1788 umtxq_unlock(&uq->uq_key); 1789 1790 umtx_key_release(&uq->uq_key); 1791 return (error); 1792 } 1793 1794 /* 1795 * Unlock a PI mutex. 1796 */ 1797 static int 1798 do_unlock_pi(struct thread *td, struct umutex *m, uint32_t flags) 1799 { 1800 struct umtx_key key; 1801 struct umtx_q *uq_first, *uq_first2, *uq_me; 1802 struct umtx_pi *pi, *pi2; 1803 uint32_t owner, old, id; 1804 int error; 1805 int count; 1806 int pri; 1807 1808 id = td->td_tid; 1809 /* 1810 * Make sure we own this mtx. 1811 */ 1812 owner = fuword32(__DEVOLATILE(uint32_t *, &m->m_owner)); 1813 if (owner == -1) 1814 return (EFAULT); 1815 1816 if ((owner & ~UMUTEX_CONTESTED) != id) 1817 return (EPERM); 1818 1819 /* This should be done in userland */ 1820 if ((owner & UMUTEX_CONTESTED) == 0) { 1821 old = casuword32(&m->m_owner, owner, UMUTEX_UNOWNED); 1822 if (old == -1) 1823 return (EFAULT); 1824 if (old == owner) 1825 return (0); 1826 owner = old; 1827 } 1828 1829 /* We should only ever be in here for contested locks */ 1830 if ((error = umtx_key_get(m, TYPE_PI_UMUTEX, GET_SHARE(flags), 1831 &key)) != 0) 1832 return (error); 1833 1834 umtxq_lock(&key); 1835 umtxq_busy(&key); 1836 count = umtxq_count_pi(&key, &uq_first); 1837 if (uq_first != NULL) { 1838 mtx_lock_spin(&umtx_lock); 1839 pi = uq_first->uq_pi_blocked; 1840 KASSERT(pi != NULL, ("pi == NULL?")); 1841 if (pi->pi_owner != curthread) { 1842 mtx_unlock_spin(&umtx_lock); 1843 umtxq_unbusy(&key); 1844 umtxq_unlock(&key); 1845 umtx_key_release(&key); 1846 /* userland messed the mutex */ 1847 return (EPERM); 1848 } 1849 uq_me = curthread->td_umtxq; 1850 pi->pi_owner = NULL; 1851 TAILQ_REMOVE(&uq_me->uq_pi_contested, pi, pi_link); 1852 /* get highest priority thread which is still sleeping. */ 1853 uq_first = TAILQ_FIRST(&pi->pi_blocked); 1854 while (uq_first != NULL && 1855 (uq_first->uq_flags & UQF_UMTXQ) == 0) { 1856 uq_first = TAILQ_NEXT(uq_first, uq_lockq); 1857 } 1858 pri = PRI_MAX; 1859 TAILQ_FOREACH(pi2, &uq_me->uq_pi_contested, pi_link) { 1860 uq_first2 = TAILQ_FIRST(&pi2->pi_blocked); 1861 if (uq_first2 != NULL) { 1862 if (pri > UPRI(uq_first2->uq_thread)) 1863 pri = UPRI(uq_first2->uq_thread); 1864 } 1865 } 1866 thread_lock(curthread); 1867 sched_lend_user_prio(curthread, pri); 1868 thread_unlock(curthread); 1869 mtx_unlock_spin(&umtx_lock); 1870 if (uq_first) 1871 umtxq_signal_thread(uq_first); 1872 } 1873 umtxq_unlock(&key); 1874 1875 /* 1876 * When unlocking the umtx, it must be marked as unowned if 1877 * there is zero or one thread only waiting for it. 1878 * Otherwise, it must be marked as contested. 1879 */ 1880 old = casuword32(&m->m_owner, owner, 1881 count <= 1 ? UMUTEX_UNOWNED : UMUTEX_CONTESTED); 1882 1883 umtxq_lock(&key); 1884 umtxq_unbusy(&key); 1885 umtxq_unlock(&key); 1886 umtx_key_release(&key); 1887 if (old == -1) 1888 return (EFAULT); 1889 if (old != owner) 1890 return (EINVAL); 1891 return (0); 1892 } 1893 1894 /* 1895 * Lock a PP mutex. 1896 */ 1897 static int 1898 _do_lock_pp(struct thread *td, struct umutex *m, uint32_t flags, int timo, 1899 int try) 1900 { 1901 struct umtx_q *uq, *uq2; 1902 struct umtx_pi *pi; 1903 uint32_t ceiling; 1904 uint32_t owner, id; 1905 int error, pri, old_inherited_pri, su; 1906 1907 id = td->td_tid; 1908 uq = td->td_umtxq; 1909 if ((error = umtx_key_get(m, TYPE_PP_UMUTEX, GET_SHARE(flags), 1910 &uq->uq_key)) != 0) 1911 return (error); 1912 su = (priv_check(td, PRIV_SCHED_RTPRIO) == 0); 1913 for (;;) { 1914 old_inherited_pri = uq->uq_inherited_pri; 1915 umtxq_lock(&uq->uq_key); 1916 umtxq_busy(&uq->uq_key); 1917 umtxq_unlock(&uq->uq_key); 1918 1919 ceiling = RTP_PRIO_MAX - fuword32(&m->m_ceilings[0]); 1920 if (ceiling > RTP_PRIO_MAX) { 1921 error = EINVAL; 1922 goto out; 1923 } 1924 1925 mtx_lock_spin(&umtx_lock); 1926 if (UPRI(td) < PRI_MIN_REALTIME + ceiling) { 1927 mtx_unlock_spin(&umtx_lock); 1928 error = EINVAL; 1929 goto out; 1930 } 1931 if (su && PRI_MIN_REALTIME + ceiling < uq->uq_inherited_pri) { 1932 uq->uq_inherited_pri = PRI_MIN_REALTIME + ceiling; 1933 thread_lock(td); 1934 if (uq->uq_inherited_pri < UPRI(td)) 1935 sched_lend_user_prio(td, uq->uq_inherited_pri); 1936 thread_unlock(td); 1937 } 1938 mtx_unlock_spin(&umtx_lock); 1939 1940 owner = casuword32(&m->m_owner, 1941 UMUTEX_CONTESTED, id | UMUTEX_CONTESTED); 1942 1943 if (owner == UMUTEX_CONTESTED) { 1944 error = 0; 1945 break; 1946 } 1947 1948 /* The address was invalid. */ 1949 if (owner == -1) { 1950 error = EFAULT; 1951 break; 1952 } 1953 1954 if ((flags & UMUTEX_ERROR_CHECK) != 0 && 1955 (owner & ~UMUTEX_CONTESTED) == id) { 1956 error = EDEADLK; 1957 break; 1958 } 1959 1960 if (try != 0) { 1961 error = EBUSY; 1962 break; 1963 } 1964 1965 /* 1966 * If we caught a signal, we have retried and now 1967 * exit immediately. 1968 */ 1969 if (error != 0) 1970 break; 1971 1972 umtxq_lock(&uq->uq_key); 1973 umtxq_insert(uq); 1974 umtxq_unbusy(&uq->uq_key); 1975 error = umtxq_sleep(uq, "umtxpp", timo); 1976 umtxq_remove(uq); 1977 umtxq_unlock(&uq->uq_key); 1978 1979 mtx_lock_spin(&umtx_lock); 1980 uq->uq_inherited_pri = old_inherited_pri; 1981 pri = PRI_MAX; 1982 TAILQ_FOREACH(pi, &uq->uq_pi_contested, pi_link) { 1983 uq2 = TAILQ_FIRST(&pi->pi_blocked); 1984 if (uq2 != NULL) { 1985 if (pri > UPRI(uq2->uq_thread)) 1986 pri = UPRI(uq2->uq_thread); 1987 } 1988 } 1989 if (pri > uq->uq_inherited_pri) 1990 pri = uq->uq_inherited_pri; 1991 thread_lock(td); 1992 sched_lend_user_prio(td, pri); 1993 thread_unlock(td); 1994 mtx_unlock_spin(&umtx_lock); 1995 } 1996 1997 if (error != 0) { 1998 mtx_lock_spin(&umtx_lock); 1999 uq->uq_inherited_pri = old_inherited_pri; 2000 pri = PRI_MAX; 2001 TAILQ_FOREACH(pi, &uq->uq_pi_contested, pi_link) { 2002 uq2 = TAILQ_FIRST(&pi->pi_blocked); 2003 if (uq2 != NULL) { 2004 if (pri > UPRI(uq2->uq_thread)) 2005 pri = UPRI(uq2->uq_thread); 2006 } 2007 } 2008 if (pri > uq->uq_inherited_pri) 2009 pri = uq->uq_inherited_pri; 2010 thread_lock(td); 2011 sched_lend_user_prio(td, pri); 2012 thread_unlock(td); 2013 mtx_unlock_spin(&umtx_lock); 2014 } 2015 2016 out: 2017 umtxq_lock(&uq->uq_key); 2018 umtxq_unbusy(&uq->uq_key); 2019 umtxq_unlock(&uq->uq_key); 2020 umtx_key_release(&uq->uq_key); 2021 return (error); 2022 } 2023 2024 /* 2025 * Unlock a PP mutex. 2026 */ 2027 static int 2028 do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags) 2029 { 2030 struct umtx_key key; 2031 struct umtx_q *uq, *uq2; 2032 struct umtx_pi *pi; 2033 uint32_t owner, id; 2034 uint32_t rceiling; 2035 int error, pri, new_inherited_pri, su; 2036 2037 id = td->td_tid; 2038 uq = td->td_umtxq; 2039 su = (priv_check(td, PRIV_SCHED_RTPRIO) == 0); 2040 2041 /* 2042 * Make sure we own this mtx. 2043 */ 2044 owner = fuword32(__DEVOLATILE(uint32_t *, &m->m_owner)); 2045 if (owner == -1) 2046 return (EFAULT); 2047 2048 if ((owner & ~UMUTEX_CONTESTED) != id) 2049 return (EPERM); 2050 2051 error = copyin(&m->m_ceilings[1], &rceiling, sizeof(uint32_t)); 2052 if (error != 0) 2053 return (error); 2054 2055 if (rceiling == -1) 2056 new_inherited_pri = PRI_MAX; 2057 else { 2058 rceiling = RTP_PRIO_MAX - rceiling; 2059 if (rceiling > RTP_PRIO_MAX) 2060 return (EINVAL); 2061 new_inherited_pri = PRI_MIN_REALTIME + rceiling; 2062 } 2063 2064 if ((error = umtx_key_get(m, TYPE_PP_UMUTEX, GET_SHARE(flags), 2065 &key)) != 0) 2066 return (error); 2067 umtxq_lock(&key); 2068 umtxq_busy(&key); 2069 umtxq_unlock(&key); 2070 /* 2071 * For priority protected mutex, always set unlocked state 2072 * to UMUTEX_CONTESTED, so that userland always enters kernel 2073 * to lock the mutex, it is necessary because thread priority 2074 * has to be adjusted for such mutex. 2075 */ 2076 error = suword32(__DEVOLATILE(uint32_t *, &m->m_owner), 2077 UMUTEX_CONTESTED); 2078 2079 umtxq_lock(&key); 2080 if (error == 0) 2081 umtxq_signal(&key, 1); 2082 umtxq_unbusy(&key); 2083 umtxq_unlock(&key); 2084 2085 if (error == -1) 2086 error = EFAULT; 2087 else { 2088 mtx_lock_spin(&umtx_lock); 2089 if (su != 0) 2090 uq->uq_inherited_pri = new_inherited_pri; 2091 pri = PRI_MAX; 2092 TAILQ_FOREACH(pi, &uq->uq_pi_contested, pi_link) { 2093 uq2 = TAILQ_FIRST(&pi->pi_blocked); 2094 if (uq2 != NULL) { 2095 if (pri > UPRI(uq2->uq_thread)) 2096 pri = UPRI(uq2->uq_thread); 2097 } 2098 } 2099 if (pri > uq->uq_inherited_pri) 2100 pri = uq->uq_inherited_pri; 2101 thread_lock(td); 2102 sched_lend_user_prio(td, pri); 2103 thread_unlock(td); 2104 mtx_unlock_spin(&umtx_lock); 2105 } 2106 umtx_key_release(&key); 2107 return (error); 2108 } 2109 2110 static int 2111 do_set_ceiling(struct thread *td, struct umutex *m, uint32_t ceiling, 2112 uint32_t *old_ceiling) 2113 { 2114 struct umtx_q *uq; 2115 uint32_t save_ceiling; 2116 uint32_t owner, id; 2117 uint32_t flags; 2118 int error; 2119 2120 flags = fuword32(&m->m_flags); 2121 if ((flags & UMUTEX_PRIO_PROTECT) == 0) 2122 return (EINVAL); 2123 if (ceiling > RTP_PRIO_MAX) 2124 return (EINVAL); 2125 id = td->td_tid; 2126 uq = td->td_umtxq; 2127 if ((error = umtx_key_get(m, TYPE_PP_UMUTEX, GET_SHARE(flags), 2128 &uq->uq_key)) != 0) 2129 return (error); 2130 for (;;) { 2131 umtxq_lock(&uq->uq_key); 2132 umtxq_busy(&uq->uq_key); 2133 umtxq_unlock(&uq->uq_key); 2134 2135 save_ceiling = fuword32(&m->m_ceilings[0]); 2136 2137 owner = casuword32(&m->m_owner, 2138 UMUTEX_CONTESTED, id | UMUTEX_CONTESTED); 2139 2140 if (owner == UMUTEX_CONTESTED) { 2141 suword32(&m->m_ceilings[0], ceiling); 2142 suword32(__DEVOLATILE(uint32_t *, &m->m_owner), 2143 UMUTEX_CONTESTED); 2144 error = 0; 2145 break; 2146 } 2147 2148 /* The address was invalid. */ 2149 if (owner == -1) { 2150 error = EFAULT; 2151 break; 2152 } 2153 2154 if ((owner & ~UMUTEX_CONTESTED) == id) { 2155 suword32(&m->m_ceilings[0], ceiling); 2156 error = 0; 2157 break; 2158 } 2159 2160 /* 2161 * If we caught a signal, we have retried and now 2162 * exit immediately. 2163 */ 2164 if (error != 0) 2165 break; 2166 2167 /* 2168 * We set the contested bit, sleep. Otherwise the lock changed 2169 * and we need to retry or we lost a race to the thread 2170 * unlocking the umtx. 2171 */ 2172 umtxq_lock(&uq->uq_key); 2173 umtxq_insert(uq); 2174 umtxq_unbusy(&uq->uq_key); 2175 error = umtxq_sleep(uq, "umtxpp", 0); 2176 umtxq_remove(uq); 2177 umtxq_unlock(&uq->uq_key); 2178 } 2179 umtxq_lock(&uq->uq_key); 2180 if (error == 0) 2181 umtxq_signal(&uq->uq_key, INT_MAX); 2182 umtxq_unbusy(&uq->uq_key); 2183 umtxq_unlock(&uq->uq_key); 2184 umtx_key_release(&uq->uq_key); 2185 if (error == 0 && old_ceiling != NULL) 2186 suword32(old_ceiling, save_ceiling); 2187 return (error); 2188 } 2189 2190 static int 2191 _do_lock_umutex(struct thread *td, struct umutex *m, int flags, int timo, 2192 int mode) 2193 { 2194 switch(flags & (UMUTEX_PRIO_INHERIT | UMUTEX_PRIO_PROTECT)) { 2195 case 0: 2196 return (_do_lock_normal(td, m, flags, timo, mode)); 2197 case UMUTEX_PRIO_INHERIT: 2198 return (_do_lock_pi(td, m, flags, timo, mode)); 2199 case UMUTEX_PRIO_PROTECT: 2200 return (_do_lock_pp(td, m, flags, timo, mode)); 2201 } 2202 return (EINVAL); 2203 } 2204 2205 /* 2206 * Lock a userland POSIX mutex. 2207 */ 2208 static int 2209 do_lock_umutex(struct thread *td, struct umutex *m, 2210 struct timespec *timeout, int mode) 2211 { 2212 struct timespec ts, ts2, ts3; 2213 struct timeval tv; 2214 uint32_t flags; 2215 int error; 2216 2217 flags = fuword32(&m->m_flags); 2218 if (flags == -1) 2219 return (EFAULT); 2220 2221 if (timeout == NULL) { 2222 error = _do_lock_umutex(td, m, flags, 0, mode); 2223 /* Mutex locking is restarted if it is interrupted. */ 2224 if (error == EINTR && mode != _UMUTEX_WAIT) 2225 error = ERESTART; 2226 } else { 2227 getnanouptime(&ts); 2228 timespecadd(&ts, timeout); 2229 TIMESPEC_TO_TIMEVAL(&tv, timeout); 2230 for (;;) { 2231 error = _do_lock_umutex(td, m, flags, tvtohz(&tv), mode); 2232 if (error != ETIMEDOUT) 2233 break; 2234 getnanouptime(&ts2); 2235 if (timespeccmp(&ts2, &ts, >=)) { 2236 error = ETIMEDOUT; 2237 break; 2238 } 2239 ts3 = ts; 2240 timespecsub(&ts3, &ts2); 2241 TIMESPEC_TO_TIMEVAL(&tv, &ts3); 2242 } 2243 /* Timed-locking is not restarted. */ 2244 if (error == ERESTART) 2245 error = EINTR; 2246 } 2247 return (error); 2248 } 2249 2250 /* 2251 * Unlock a userland POSIX mutex. 2252 */ 2253 static int 2254 do_unlock_umutex(struct thread *td, struct umutex *m) 2255 { 2256 uint32_t flags; 2257 2258 flags = fuword32(&m->m_flags); 2259 if (flags == -1) 2260 return (EFAULT); 2261 2262 switch(flags & (UMUTEX_PRIO_INHERIT | UMUTEX_PRIO_PROTECT)) { 2263 case 0: 2264 return (do_unlock_normal(td, m, flags)); 2265 case UMUTEX_PRIO_INHERIT: 2266 return (do_unlock_pi(td, m, flags)); 2267 case UMUTEX_PRIO_PROTECT: 2268 return (do_unlock_pp(td, m, flags)); 2269 } 2270 2271 return (EINVAL); 2272 } 2273 2274 static int 2275 do_cv_wait(struct thread *td, struct ucond *cv, struct umutex *m, 2276 struct timespec *timeout, u_long wflags) 2277 { 2278 struct umtx_q *uq; 2279 struct timeval tv; 2280 struct timespec cts, ets, tts; 2281 uint32_t flags; 2282 uint32_t clockid; 2283 int error; 2284 2285 uq = td->td_umtxq; 2286 flags = fuword32(&cv->c_flags); 2287 error = umtx_key_get(cv, TYPE_CV, GET_SHARE(flags), &uq->uq_key); 2288 if (error != 0) 2289 return (error); 2290 2291 if ((wflags & CVWAIT_CLOCKID) != 0) { 2292 clockid = fuword32(&cv->c_clockid); 2293 if (clockid < CLOCK_REALTIME || 2294 clockid >= CLOCK_THREAD_CPUTIME_ID) { 2295 /* hmm, only HW clock id will work. */ 2296 return (EINVAL); 2297 } 2298 } else { 2299 clockid = CLOCK_REALTIME; 2300 } 2301 2302 umtxq_lock(&uq->uq_key); 2303 umtxq_busy(&uq->uq_key); 2304 umtxq_insert(uq); 2305 umtxq_unlock(&uq->uq_key); 2306 2307 /* 2308 * Set c_has_waiters to 1 before releasing user mutex, also 2309 * don't modify cache line when unnecessary. 2310 */ 2311 if (fuword32(__DEVOLATILE(uint32_t *, &cv->c_has_waiters)) == 0) 2312 suword32(__DEVOLATILE(uint32_t *, &cv->c_has_waiters), 1); 2313 2314 umtxq_lock(&uq->uq_key); 2315 umtxq_unbusy(&uq->uq_key); 2316 umtxq_unlock(&uq->uq_key); 2317 2318 error = do_unlock_umutex(td, m); 2319 2320 umtxq_lock(&uq->uq_key); 2321 if (error == 0) { 2322 if (timeout == NULL) { 2323 error = umtxq_sleep(uq, "ucond", 0); 2324 } else { 2325 if ((wflags & CVWAIT_ABSTIME) == 0) { 2326 kern_clock_gettime(td, clockid, &ets); 2327 timespecadd(&ets, timeout); 2328 tts = *timeout; 2329 } else { /* absolute time */ 2330 ets = *timeout; 2331 tts = *timeout; 2332 kern_clock_gettime(td, clockid, &cts); 2333 timespecsub(&tts, &cts); 2334 } 2335 TIMESPEC_TO_TIMEVAL(&tv, &tts); 2336 for (;;) { 2337 error = umtxq_sleep(uq, "ucond", tvtohz(&tv)); 2338 if (error != ETIMEDOUT) 2339 break; 2340 kern_clock_gettime(td, clockid, &cts); 2341 if (timespeccmp(&cts, &ets, >=)) { 2342 error = ETIMEDOUT; 2343 break; 2344 } 2345 tts = ets; 2346 timespecsub(&tts, &cts); 2347 TIMESPEC_TO_TIMEVAL(&tv, &tts); 2348 } 2349 } 2350 } 2351 2352 if ((uq->uq_flags & UQF_UMTXQ) == 0) 2353 error = 0; 2354 else { 2355 /* 2356 * This must be timeout,interrupted by signal or 2357 * surprious wakeup, clear c_has_waiter flag when 2358 * necessary. 2359 */ 2360 umtxq_busy(&uq->uq_key); 2361 if ((uq->uq_flags & UQF_UMTXQ) != 0) { 2362 int oldlen = uq->uq_cur_queue->length; 2363 umtxq_remove(uq); 2364 if (oldlen == 1) { 2365 umtxq_unlock(&uq->uq_key); 2366 suword32( 2367 __DEVOLATILE(uint32_t *, 2368 &cv->c_has_waiters), 0); 2369 umtxq_lock(&uq->uq_key); 2370 } 2371 } 2372 umtxq_unbusy(&uq->uq_key); 2373 if (error == ERESTART) 2374 error = EINTR; 2375 } 2376 2377 umtxq_unlock(&uq->uq_key); 2378 umtx_key_release(&uq->uq_key); 2379 return (error); 2380 } 2381 2382 /* 2383 * Signal a userland condition variable. 2384 */ 2385 static int 2386 do_cv_signal(struct thread *td, struct ucond *cv) 2387 { 2388 struct umtx_key key; 2389 int error, cnt, nwake; 2390 uint32_t flags; 2391 2392 flags = fuword32(&cv->c_flags); 2393 if ((error = umtx_key_get(cv, TYPE_CV, GET_SHARE(flags), &key)) != 0) 2394 return (error); 2395 umtxq_lock(&key); 2396 umtxq_busy(&key); 2397 cnt = umtxq_count(&key); 2398 nwake = umtxq_signal(&key, 1); 2399 if (cnt <= nwake) { 2400 umtxq_unlock(&key); 2401 error = suword32( 2402 __DEVOLATILE(uint32_t *, &cv->c_has_waiters), 0); 2403 umtxq_lock(&key); 2404 } 2405 umtxq_unbusy(&key); 2406 umtxq_unlock(&key); 2407 umtx_key_release(&key); 2408 return (error); 2409 } 2410 2411 static int 2412 do_cv_broadcast(struct thread *td, struct ucond *cv) 2413 { 2414 struct umtx_key key; 2415 int error; 2416 uint32_t flags; 2417 2418 flags = fuword32(&cv->c_flags); 2419 if ((error = umtx_key_get(cv, TYPE_CV, GET_SHARE(flags), &key)) != 0) 2420 return (error); 2421 2422 umtxq_lock(&key); 2423 umtxq_busy(&key); 2424 umtxq_signal(&key, INT_MAX); 2425 umtxq_unlock(&key); 2426 2427 error = suword32(__DEVOLATILE(uint32_t *, &cv->c_has_waiters), 0); 2428 2429 umtxq_lock(&key); 2430 umtxq_unbusy(&key); 2431 umtxq_unlock(&key); 2432 2433 umtx_key_release(&key); 2434 return (error); 2435 } 2436 2437 static int 2438 do_rw_rdlock(struct thread *td, struct urwlock *rwlock, long fflag, int timo) 2439 { 2440 struct umtx_q *uq; 2441 uint32_t flags, wrflags; 2442 int32_t state, oldstate; 2443 int32_t blocked_readers; 2444 int error; 2445 2446 uq = td->td_umtxq; 2447 flags = fuword32(&rwlock->rw_flags); 2448 error = umtx_key_get(rwlock, TYPE_RWLOCK, GET_SHARE(flags), &uq->uq_key); 2449 if (error != 0) 2450 return (error); 2451 2452 wrflags = URWLOCK_WRITE_OWNER; 2453 if (!(fflag & URWLOCK_PREFER_READER) && !(flags & URWLOCK_PREFER_READER)) 2454 wrflags |= URWLOCK_WRITE_WAITERS; 2455 2456 for (;;) { 2457 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state)); 2458 /* try to lock it */ 2459 while (!(state & wrflags)) { 2460 if (__predict_false(URWLOCK_READER_COUNT(state) == URWLOCK_MAX_READERS)) { 2461 umtx_key_release(&uq->uq_key); 2462 return (EAGAIN); 2463 } 2464 oldstate = casuword32(&rwlock->rw_state, state, state + 1); 2465 if (oldstate == state) { 2466 umtx_key_release(&uq->uq_key); 2467 return (0); 2468 } 2469 state = oldstate; 2470 } 2471 2472 if (error) 2473 break; 2474 2475 /* grab monitor lock */ 2476 umtxq_lock(&uq->uq_key); 2477 umtxq_busy(&uq->uq_key); 2478 umtxq_unlock(&uq->uq_key); 2479 2480 /* 2481 * re-read the state, in case it changed between the try-lock above 2482 * and the check below 2483 */ 2484 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state)); 2485 2486 /* set read contention bit */ 2487 while ((state & wrflags) && !(state & URWLOCK_READ_WAITERS)) { 2488 oldstate = casuword32(&rwlock->rw_state, state, state | URWLOCK_READ_WAITERS); 2489 if (oldstate == state) 2490 goto sleep; 2491 state = oldstate; 2492 } 2493 2494 /* state is changed while setting flags, restart */ 2495 if (!(state & wrflags)) { 2496 umtxq_lock(&uq->uq_key); 2497 umtxq_unbusy(&uq->uq_key); 2498 umtxq_unlock(&uq->uq_key); 2499 continue; 2500 } 2501 2502 sleep: 2503 /* contention bit is set, before sleeping, increase read waiter count */ 2504 blocked_readers = fuword32(&rwlock->rw_blocked_readers); 2505 suword32(&rwlock->rw_blocked_readers, blocked_readers+1); 2506 2507 while (state & wrflags) { 2508 umtxq_lock(&uq->uq_key); 2509 umtxq_insert(uq); 2510 umtxq_unbusy(&uq->uq_key); 2511 2512 error = umtxq_sleep(uq, "urdlck", timo); 2513 2514 umtxq_busy(&uq->uq_key); 2515 umtxq_remove(uq); 2516 umtxq_unlock(&uq->uq_key); 2517 if (error) 2518 break; 2519 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state)); 2520 } 2521 2522 /* decrease read waiter count, and may clear read contention bit */ 2523 blocked_readers = fuword32(&rwlock->rw_blocked_readers); 2524 suword32(&rwlock->rw_blocked_readers, blocked_readers-1); 2525 if (blocked_readers == 1) { 2526 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state)); 2527 for (;;) { 2528 oldstate = casuword32(&rwlock->rw_state, state, 2529 state & ~URWLOCK_READ_WAITERS); 2530 if (oldstate == state) 2531 break; 2532 state = oldstate; 2533 } 2534 } 2535 2536 umtxq_lock(&uq->uq_key); 2537 umtxq_unbusy(&uq->uq_key); 2538 umtxq_unlock(&uq->uq_key); 2539 } 2540 umtx_key_release(&uq->uq_key); 2541 return (error); 2542 } 2543 2544 static int 2545 do_rw_rdlock2(struct thread *td, void *obj, long val, struct timespec *timeout) 2546 { 2547 struct timespec ts, ts2, ts3; 2548 struct timeval tv; 2549 int error; 2550 2551 getnanouptime(&ts); 2552 timespecadd(&ts, timeout); 2553 TIMESPEC_TO_TIMEVAL(&tv, timeout); 2554 for (;;) { 2555 error = do_rw_rdlock(td, obj, val, tvtohz(&tv)); 2556 if (error != ETIMEDOUT) 2557 break; 2558 getnanouptime(&ts2); 2559 if (timespeccmp(&ts2, &ts, >=)) { 2560 error = ETIMEDOUT; 2561 break; 2562 } 2563 ts3 = ts; 2564 timespecsub(&ts3, &ts2); 2565 TIMESPEC_TO_TIMEVAL(&tv, &ts3); 2566 } 2567 if (error == ERESTART) 2568 error = EINTR; 2569 return (error); 2570 } 2571 2572 static int 2573 do_rw_wrlock(struct thread *td, struct urwlock *rwlock, int timo) 2574 { 2575 struct umtx_q *uq; 2576 uint32_t flags; 2577 int32_t state, oldstate; 2578 int32_t blocked_writers; 2579 int32_t blocked_readers; 2580 int error; 2581 2582 uq = td->td_umtxq; 2583 flags = fuword32(&rwlock->rw_flags); 2584 error = umtx_key_get(rwlock, TYPE_RWLOCK, GET_SHARE(flags), &uq->uq_key); 2585 if (error != 0) 2586 return (error); 2587 2588 blocked_readers = 0; 2589 for (;;) { 2590 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state)); 2591 while (!(state & URWLOCK_WRITE_OWNER) && URWLOCK_READER_COUNT(state) == 0) { 2592 oldstate = casuword32(&rwlock->rw_state, state, state | URWLOCK_WRITE_OWNER); 2593 if (oldstate == state) { 2594 umtx_key_release(&uq->uq_key); 2595 return (0); 2596 } 2597 state = oldstate; 2598 } 2599 2600 if (error) { 2601 if (!(state & (URWLOCK_WRITE_OWNER|URWLOCK_WRITE_WAITERS)) && 2602 blocked_readers != 0) { 2603 umtxq_lock(&uq->uq_key); 2604 umtxq_busy(&uq->uq_key); 2605 umtxq_signal_queue(&uq->uq_key, INT_MAX, UMTX_SHARED_QUEUE); 2606 umtxq_unbusy(&uq->uq_key); 2607 umtxq_unlock(&uq->uq_key); 2608 } 2609 2610 break; 2611 } 2612 2613 /* grab monitor lock */ 2614 umtxq_lock(&uq->uq_key); 2615 umtxq_busy(&uq->uq_key); 2616 umtxq_unlock(&uq->uq_key); 2617 2618 /* 2619 * re-read the state, in case it changed between the try-lock above 2620 * and the check below 2621 */ 2622 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state)); 2623 2624 while (((state & URWLOCK_WRITE_OWNER) || URWLOCK_READER_COUNT(state) != 0) && 2625 (state & URWLOCK_WRITE_WAITERS) == 0) { 2626 oldstate = casuword32(&rwlock->rw_state, state, state | URWLOCK_WRITE_WAITERS); 2627 if (oldstate == state) 2628 goto sleep; 2629 state = oldstate; 2630 } 2631 2632 if (!(state & URWLOCK_WRITE_OWNER) && URWLOCK_READER_COUNT(state) == 0) { 2633 umtxq_lock(&uq->uq_key); 2634 umtxq_unbusy(&uq->uq_key); 2635 umtxq_unlock(&uq->uq_key); 2636 continue; 2637 } 2638 sleep: 2639 blocked_writers = fuword32(&rwlock->rw_blocked_writers); 2640 suword32(&rwlock->rw_blocked_writers, blocked_writers+1); 2641 2642 while ((state & URWLOCK_WRITE_OWNER) || URWLOCK_READER_COUNT(state) != 0) { 2643 umtxq_lock(&uq->uq_key); 2644 umtxq_insert_queue(uq, UMTX_EXCLUSIVE_QUEUE); 2645 umtxq_unbusy(&uq->uq_key); 2646 2647 error = umtxq_sleep(uq, "uwrlck", timo); 2648 2649 umtxq_busy(&uq->uq_key); 2650 umtxq_remove_queue(uq, UMTX_EXCLUSIVE_QUEUE); 2651 umtxq_unlock(&uq->uq_key); 2652 if (error) 2653 break; 2654 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state)); 2655 } 2656 2657 blocked_writers = fuword32(&rwlock->rw_blocked_writers); 2658 suword32(&rwlock->rw_blocked_writers, blocked_writers-1); 2659 if (blocked_writers == 1) { 2660 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state)); 2661 for (;;) { 2662 oldstate = casuword32(&rwlock->rw_state, state, 2663 state & ~URWLOCK_WRITE_WAITERS); 2664 if (oldstate == state) 2665 break; 2666 state = oldstate; 2667 } 2668 blocked_readers = fuword32(&rwlock->rw_blocked_readers); 2669 } else 2670 blocked_readers = 0; 2671 2672 umtxq_lock(&uq->uq_key); 2673 umtxq_unbusy(&uq->uq_key); 2674 umtxq_unlock(&uq->uq_key); 2675 } 2676 2677 umtx_key_release(&uq->uq_key); 2678 return (error); 2679 } 2680 2681 static int 2682 do_rw_wrlock2(struct thread *td, void *obj, struct timespec *timeout) 2683 { 2684 struct timespec ts, ts2, ts3; 2685 struct timeval tv; 2686 int error; 2687 2688 getnanouptime(&ts); 2689 timespecadd(&ts, timeout); 2690 TIMESPEC_TO_TIMEVAL(&tv, timeout); 2691 for (;;) { 2692 error = do_rw_wrlock(td, obj, tvtohz(&tv)); 2693 if (error != ETIMEDOUT) 2694 break; 2695 getnanouptime(&ts2); 2696 if (timespeccmp(&ts2, &ts, >=)) { 2697 error = ETIMEDOUT; 2698 break; 2699 } 2700 ts3 = ts; 2701 timespecsub(&ts3, &ts2); 2702 TIMESPEC_TO_TIMEVAL(&tv, &ts3); 2703 } 2704 if (error == ERESTART) 2705 error = EINTR; 2706 return (error); 2707 } 2708 2709 static int 2710 do_rw_unlock(struct thread *td, struct urwlock *rwlock) 2711 { 2712 struct umtx_q *uq; 2713 uint32_t flags; 2714 int32_t state, oldstate; 2715 int error, q, count; 2716 2717 uq = td->td_umtxq; 2718 flags = fuword32(&rwlock->rw_flags); 2719 error = umtx_key_get(rwlock, TYPE_RWLOCK, GET_SHARE(flags), &uq->uq_key); 2720 if (error != 0) 2721 return (error); 2722 2723 state = fuword32(__DEVOLATILE(int32_t *, &rwlock->rw_state)); 2724 if (state & URWLOCK_WRITE_OWNER) { 2725 for (;;) { 2726 oldstate = casuword32(&rwlock->rw_state, state, 2727 state & ~URWLOCK_WRITE_OWNER); 2728 if (oldstate != state) { 2729 state = oldstate; 2730 if (!(oldstate & URWLOCK_WRITE_OWNER)) { 2731 error = EPERM; 2732 goto out; 2733 } 2734 } else 2735 break; 2736 } 2737 } else if (URWLOCK_READER_COUNT(state) != 0) { 2738 for (;;) { 2739 oldstate = casuword32(&rwlock->rw_state, state, 2740 state - 1); 2741 if (oldstate != state) { 2742 state = oldstate; 2743 if (URWLOCK_READER_COUNT(oldstate) == 0) { 2744 error = EPERM; 2745 goto out; 2746 } 2747 } 2748 else 2749 break; 2750 } 2751 } else { 2752 error = EPERM; 2753 goto out; 2754 } 2755 2756 count = 0; 2757 2758 if (!(flags & URWLOCK_PREFER_READER)) { 2759 if (state & URWLOCK_WRITE_WAITERS) { 2760 count = 1; 2761 q = UMTX_EXCLUSIVE_QUEUE; 2762 } else if (state & URWLOCK_READ_WAITERS) { 2763 count = INT_MAX; 2764 q = UMTX_SHARED_QUEUE; 2765 } 2766 } else { 2767 if (state & URWLOCK_READ_WAITERS) { 2768 count = INT_MAX; 2769 q = UMTX_SHARED_QUEUE; 2770 } else if (state & URWLOCK_WRITE_WAITERS) { 2771 count = 1; 2772 q = UMTX_EXCLUSIVE_QUEUE; 2773 } 2774 } 2775 2776 if (count) { 2777 umtxq_lock(&uq->uq_key); 2778 umtxq_busy(&uq->uq_key); 2779 umtxq_signal_queue(&uq->uq_key, count, q); 2780 umtxq_unbusy(&uq->uq_key); 2781 umtxq_unlock(&uq->uq_key); 2782 } 2783 out: 2784 umtx_key_release(&uq->uq_key); 2785 return (error); 2786 } 2787 2788 static int 2789 do_sem_wait(struct thread *td, struct _usem *sem, struct timespec *timeout) 2790 { 2791 struct umtx_q *uq; 2792 struct timeval tv; 2793 struct timespec cts, ets, tts; 2794 uint32_t flags, count; 2795 int error; 2796 2797 uq = td->td_umtxq; 2798 flags = fuword32(&sem->_flags); 2799 error = umtx_key_get(sem, TYPE_SEM, GET_SHARE(flags), &uq->uq_key); 2800 if (error != 0) 2801 return (error); 2802 umtxq_lock(&uq->uq_key); 2803 umtxq_busy(&uq->uq_key); 2804 umtxq_insert(uq); 2805 umtxq_unlock(&uq->uq_key); 2806 2807 if (fuword32(__DEVOLATILE(uint32_t *, &sem->_has_waiters)) == 0) 2808 casuword32(__DEVOLATILE(uint32_t *, &sem->_has_waiters), 0, 1); 2809 2810 count = fuword32(__DEVOLATILE(uint32_t *, &sem->_count)); 2811 if (count != 0) { 2812 umtxq_lock(&uq->uq_key); 2813 umtxq_unbusy(&uq->uq_key); 2814 umtxq_remove(uq); 2815 umtxq_unlock(&uq->uq_key); 2816 umtx_key_release(&uq->uq_key); 2817 return (0); 2818 } 2819 2820 umtxq_lock(&uq->uq_key); 2821 umtxq_unbusy(&uq->uq_key); 2822 umtxq_unlock(&uq->uq_key); 2823 2824 umtxq_lock(&uq->uq_key); 2825 if (timeout == NULL) { 2826 error = umtxq_sleep(uq, "usem", 0); 2827 } else { 2828 getnanouptime(&ets); 2829 timespecadd(&ets, timeout); 2830 TIMESPEC_TO_TIMEVAL(&tv, timeout); 2831 for (;;) { 2832 error = umtxq_sleep(uq, "usem", tvtohz(&tv)); 2833 if (error != ETIMEDOUT) 2834 break; 2835 getnanouptime(&cts); 2836 if (timespeccmp(&cts, &ets, >=)) { 2837 error = ETIMEDOUT; 2838 break; 2839 } 2840 tts = ets; 2841 timespecsub(&tts, &cts); 2842 TIMESPEC_TO_TIMEVAL(&tv, &tts); 2843 } 2844 } 2845 2846 if ((uq->uq_flags & UQF_UMTXQ) == 0) 2847 error = 0; 2848 else { 2849 umtxq_remove(uq); 2850 if (error == ERESTART) 2851 error = EINTR; 2852 } 2853 umtxq_unlock(&uq->uq_key); 2854 umtx_key_release(&uq->uq_key); 2855 return (error); 2856 } 2857 2858 /* 2859 * Signal a userland condition variable. 2860 */ 2861 static int 2862 do_sem_wake(struct thread *td, struct _usem *sem) 2863 { 2864 struct umtx_key key; 2865 int error, cnt, nwake; 2866 uint32_t flags; 2867 2868 flags = fuword32(&sem->_flags); 2869 if ((error = umtx_key_get(sem, TYPE_SEM, GET_SHARE(flags), &key)) != 0) 2870 return (error); 2871 umtxq_lock(&key); 2872 umtxq_busy(&key); 2873 cnt = umtxq_count(&key); 2874 nwake = umtxq_signal(&key, 1); 2875 if (cnt <= nwake) { 2876 umtxq_unlock(&key); 2877 error = suword32( 2878 __DEVOLATILE(uint32_t *, &sem->_has_waiters), 0); 2879 umtxq_lock(&key); 2880 } 2881 umtxq_unbusy(&key); 2882 umtxq_unlock(&key); 2883 umtx_key_release(&key); 2884 return (error); 2885 } 2886 2887 int 2888 sys__umtx_lock(struct thread *td, struct _umtx_lock_args *uap) 2889 /* struct umtx *umtx */ 2890 { 2891 return _do_lock_umtx(td, uap->umtx, td->td_tid, 0); 2892 } 2893 2894 int 2895 sys__umtx_unlock(struct thread *td, struct _umtx_unlock_args *uap) 2896 /* struct umtx *umtx */ 2897 { 2898 return do_unlock_umtx(td, uap->umtx, td->td_tid); 2899 } 2900 2901 inline int 2902 umtx_copyin_timeout(const void *addr, struct timespec *tsp) 2903 { 2904 int error; 2905 2906 error = copyin(addr, tsp, sizeof(struct timespec)); 2907 if (error == 0) { 2908 if (tsp->tv_sec < 0 || 2909 tsp->tv_nsec >= 1000000000 || 2910 tsp->tv_nsec < 0) 2911 error = EINVAL; 2912 } 2913 return (error); 2914 } 2915 2916 static int 2917 __umtx_op_lock_umtx(struct thread *td, struct _umtx_op_args *uap) 2918 { 2919 struct timespec *ts, timeout; 2920 int error; 2921 2922 /* Allow a null timespec (wait forever). */ 2923 if (uap->uaddr2 == NULL) 2924 ts = NULL; 2925 else { 2926 error = umtx_copyin_timeout(uap->uaddr2, &timeout); 2927 if (error != 0) 2928 return (error); 2929 ts = &timeout; 2930 } 2931 return (do_lock_umtx(td, uap->obj, uap->val, ts)); 2932 } 2933 2934 static int 2935 __umtx_op_unlock_umtx(struct thread *td, struct _umtx_op_args *uap) 2936 { 2937 return (do_unlock_umtx(td, uap->obj, uap->val)); 2938 } 2939 2940 static int 2941 __umtx_op_wait(struct thread *td, struct _umtx_op_args *uap) 2942 { 2943 struct timespec *ts, timeout; 2944 int error; 2945 2946 if (uap->uaddr2 == NULL) 2947 ts = NULL; 2948 else { 2949 error = umtx_copyin_timeout(uap->uaddr2, &timeout); 2950 if (error != 0) 2951 return (error); 2952 ts = &timeout; 2953 } 2954 return do_wait(td, uap->obj, uap->val, ts, 0, 0); 2955 } 2956 2957 static int 2958 __umtx_op_wait_uint(struct thread *td, struct _umtx_op_args *uap) 2959 { 2960 struct timespec *ts, timeout; 2961 int error; 2962 2963 if (uap->uaddr2 == NULL) 2964 ts = NULL; 2965 else { 2966 error = umtx_copyin_timeout(uap->uaddr2, &timeout); 2967 if (error != 0) 2968 return (error); 2969 ts = &timeout; 2970 } 2971 return do_wait(td, uap->obj, uap->val, ts, 1, 0); 2972 } 2973 2974 static int 2975 __umtx_op_wait_uint_private(struct thread *td, struct _umtx_op_args *uap) 2976 { 2977 struct timespec *ts, timeout; 2978 int error; 2979 2980 if (uap->uaddr2 == NULL) 2981 ts = NULL; 2982 else { 2983 error = umtx_copyin_timeout(uap->uaddr2, &timeout); 2984 if (error != 0) 2985 return (error); 2986 ts = &timeout; 2987 } 2988 return do_wait(td, uap->obj, uap->val, ts, 1, 1); 2989 } 2990 2991 static int 2992 __umtx_op_wake(struct thread *td, struct _umtx_op_args *uap) 2993 { 2994 return (kern_umtx_wake(td, uap->obj, uap->val, 0)); 2995 } 2996 2997 #define BATCH_SIZE 128 2998 static int 2999 __umtx_op_nwake_private(struct thread *td, struct _umtx_op_args *uap) 3000 { 3001 int count = uap->val; 3002 void *uaddrs[BATCH_SIZE]; 3003 char **upp = (char **)uap->obj; 3004 int tocopy; 3005 int error = 0; 3006 int i, pos = 0; 3007 3008 while (count > 0) { 3009 tocopy = count; 3010 if (tocopy > BATCH_SIZE) 3011 tocopy = BATCH_SIZE; 3012 error = copyin(upp+pos, uaddrs, tocopy * sizeof(char *)); 3013 if (error != 0) 3014 break; 3015 for (i = 0; i < tocopy; ++i) 3016 kern_umtx_wake(td, uaddrs[i], INT_MAX, 1); 3017 count -= tocopy; 3018 pos += tocopy; 3019 } 3020 return (error); 3021 } 3022 3023 static int 3024 __umtx_op_wake_private(struct thread *td, struct _umtx_op_args *uap) 3025 { 3026 return (kern_umtx_wake(td, uap->obj, uap->val, 1)); 3027 } 3028 3029 static int 3030 __umtx_op_lock_umutex(struct thread *td, struct _umtx_op_args *uap) 3031 { 3032 struct timespec *ts, timeout; 3033 int error; 3034 3035 /* Allow a null timespec (wait forever). */ 3036 if (uap->uaddr2 == NULL) 3037 ts = NULL; 3038 else { 3039 error = umtx_copyin_timeout(uap->uaddr2, &timeout); 3040 if (error != 0) 3041 return (error); 3042 ts = &timeout; 3043 } 3044 return do_lock_umutex(td, uap->obj, ts, 0); 3045 } 3046 3047 static int 3048 __umtx_op_trylock_umutex(struct thread *td, struct _umtx_op_args *uap) 3049 { 3050 return do_lock_umutex(td, uap->obj, NULL, _UMUTEX_TRY); 3051 } 3052 3053 static int 3054 __umtx_op_wait_umutex(struct thread *td, struct _umtx_op_args *uap) 3055 { 3056 struct timespec *ts, timeout; 3057 int error; 3058 3059 /* Allow a null timespec (wait forever). */ 3060 if (uap->uaddr2 == NULL) 3061 ts = NULL; 3062 else { 3063 error = umtx_copyin_timeout(uap->uaddr2, &timeout); 3064 if (error != 0) 3065 return (error); 3066 ts = &timeout; 3067 } 3068 return do_lock_umutex(td, uap->obj, ts, _UMUTEX_WAIT); 3069 } 3070 3071 static int 3072 __umtx_op_wake_umutex(struct thread *td, struct _umtx_op_args *uap) 3073 { 3074 return do_wake_umutex(td, uap->obj); 3075 } 3076 3077 static int 3078 __umtx_op_unlock_umutex(struct thread *td, struct _umtx_op_args *uap) 3079 { 3080 return do_unlock_umutex(td, uap->obj); 3081 } 3082 3083 static int 3084 __umtx_op_set_ceiling(struct thread *td, struct _umtx_op_args *uap) 3085 { 3086 return do_set_ceiling(td, uap->obj, uap->val, uap->uaddr1); 3087 } 3088 3089 static int 3090 __umtx_op_cv_wait(struct thread *td, struct _umtx_op_args *uap) 3091 { 3092 struct timespec *ts, timeout; 3093 int error; 3094 3095 /* Allow a null timespec (wait forever). */ 3096 if (uap->uaddr2 == NULL) 3097 ts = NULL; 3098 else { 3099 error = umtx_copyin_timeout(uap->uaddr2, &timeout); 3100 if (error != 0) 3101 return (error); 3102 ts = &timeout; 3103 } 3104 return (do_cv_wait(td, uap->obj, uap->uaddr1, ts, uap->val)); 3105 } 3106 3107 static int 3108 __umtx_op_cv_signal(struct thread *td, struct _umtx_op_args *uap) 3109 { 3110 return do_cv_signal(td, uap->obj); 3111 } 3112 3113 static int 3114 __umtx_op_cv_broadcast(struct thread *td, struct _umtx_op_args *uap) 3115 { 3116 return do_cv_broadcast(td, uap->obj); 3117 } 3118 3119 static int 3120 __umtx_op_rw_rdlock(struct thread *td, struct _umtx_op_args *uap) 3121 { 3122 struct timespec timeout; 3123 int error; 3124 3125 /* Allow a null timespec (wait forever). */ 3126 if (uap->uaddr2 == NULL) { 3127 error = do_rw_rdlock(td, uap->obj, uap->val, 0); 3128 } else { 3129 error = umtx_copyin_timeout(uap->uaddr2, &timeout); 3130 if (error != 0) 3131 return (error); 3132 error = do_rw_rdlock2(td, uap->obj, uap->val, &timeout); 3133 } 3134 return (error); 3135 } 3136 3137 static int 3138 __umtx_op_rw_wrlock(struct thread *td, struct _umtx_op_args *uap) 3139 { 3140 struct timespec timeout; 3141 int error; 3142 3143 /* Allow a null timespec (wait forever). */ 3144 if (uap->uaddr2 == NULL) { 3145 error = do_rw_wrlock(td, uap->obj, 0); 3146 } else { 3147 error = umtx_copyin_timeout(uap->uaddr2, &timeout); 3148 if (error != 0) 3149 return (error); 3150 3151 error = do_rw_wrlock2(td, uap->obj, &timeout); 3152 } 3153 return (error); 3154 } 3155 3156 static int 3157 __umtx_op_rw_unlock(struct thread *td, struct _umtx_op_args *uap) 3158 { 3159 return do_rw_unlock(td, uap->obj); 3160 } 3161 3162 static int 3163 __umtx_op_sem_wait(struct thread *td, struct _umtx_op_args *uap) 3164 { 3165 struct timespec *ts, timeout; 3166 int error; 3167 3168 /* Allow a null timespec (wait forever). */ 3169 if (uap->uaddr2 == NULL) 3170 ts = NULL; 3171 else { 3172 error = umtx_copyin_timeout(uap->uaddr2, &timeout); 3173 if (error != 0) 3174 return (error); 3175 ts = &timeout; 3176 } 3177 return (do_sem_wait(td, uap->obj, ts)); 3178 } 3179 3180 static int 3181 __umtx_op_sem_wake(struct thread *td, struct _umtx_op_args *uap) 3182 { 3183 return do_sem_wake(td, uap->obj); 3184 } 3185 3186 typedef int (*_umtx_op_func)(struct thread *td, struct _umtx_op_args *uap); 3187 3188 static _umtx_op_func op_table[] = { 3189 __umtx_op_lock_umtx, /* UMTX_OP_LOCK */ 3190 __umtx_op_unlock_umtx, /* UMTX_OP_UNLOCK */ 3191 __umtx_op_wait, /* UMTX_OP_WAIT */ 3192 __umtx_op_wake, /* UMTX_OP_WAKE */ 3193 __umtx_op_trylock_umutex, /* UMTX_OP_MUTEX_TRYLOCK */ 3194 __umtx_op_lock_umutex, /* UMTX_OP_MUTEX_LOCK */ 3195 __umtx_op_unlock_umutex, /* UMTX_OP_MUTEX_UNLOCK */ 3196 __umtx_op_set_ceiling, /* UMTX_OP_SET_CEILING */ 3197 __umtx_op_cv_wait, /* UMTX_OP_CV_WAIT*/ 3198 __umtx_op_cv_signal, /* UMTX_OP_CV_SIGNAL */ 3199 __umtx_op_cv_broadcast, /* UMTX_OP_CV_BROADCAST */ 3200 __umtx_op_wait_uint, /* UMTX_OP_WAIT_UINT */ 3201 __umtx_op_rw_rdlock, /* UMTX_OP_RW_RDLOCK */ 3202 __umtx_op_rw_wrlock, /* UMTX_OP_RW_WRLOCK */ 3203 __umtx_op_rw_unlock, /* UMTX_OP_RW_UNLOCK */ 3204 __umtx_op_wait_uint_private, /* UMTX_OP_WAIT_UINT_PRIVATE */ 3205 __umtx_op_wake_private, /* UMTX_OP_WAKE_PRIVATE */ 3206 __umtx_op_wait_umutex, /* UMTX_OP_UMUTEX_WAIT */ 3207 __umtx_op_wake_umutex, /* UMTX_OP_UMUTEX_WAKE */ 3208 __umtx_op_sem_wait, /* UMTX_OP_SEM_WAIT */ 3209 __umtx_op_sem_wake, /* UMTX_OP_SEM_WAKE */ 3210 __umtx_op_nwake_private /* UMTX_OP_NWAKE_PRIVATE */ 3211 }; 3212 3213 int 3214 sys__umtx_op(struct thread *td, struct _umtx_op_args *uap) 3215 { 3216 if ((unsigned)uap->op < UMTX_OP_MAX) 3217 return (*op_table[uap->op])(td, uap); 3218 return (EINVAL); 3219 } 3220 3221 #ifdef COMPAT_FREEBSD32 3222 int 3223 freebsd32_umtx_lock(struct thread *td, struct freebsd32_umtx_lock_args *uap) 3224 /* struct umtx *umtx */ 3225 { 3226 return (do_lock_umtx32(td, (uint32_t *)uap->umtx, td->td_tid, NULL)); 3227 } 3228 3229 int 3230 freebsd32_umtx_unlock(struct thread *td, struct freebsd32_umtx_unlock_args *uap) 3231 /* struct umtx *umtx */ 3232 { 3233 return (do_unlock_umtx32(td, (uint32_t *)uap->umtx, td->td_tid)); 3234 } 3235 3236 struct timespec32 { 3237 uint32_t tv_sec; 3238 uint32_t tv_nsec; 3239 }; 3240 3241 static inline int 3242 umtx_copyin_timeout32(void *addr, struct timespec *tsp) 3243 { 3244 struct timespec32 ts32; 3245 int error; 3246 3247 error = copyin(addr, &ts32, sizeof(struct timespec32)); 3248 if (error == 0) { 3249 if (ts32.tv_sec < 0 || 3250 ts32.tv_nsec >= 1000000000 || 3251 ts32.tv_nsec < 0) 3252 error = EINVAL; 3253 else { 3254 tsp->tv_sec = ts32.tv_sec; 3255 tsp->tv_nsec = ts32.tv_nsec; 3256 } 3257 } 3258 return (error); 3259 } 3260 3261 static int 3262 __umtx_op_lock_umtx_compat32(struct thread *td, struct _umtx_op_args *uap) 3263 { 3264 struct timespec *ts, timeout; 3265 int error; 3266 3267 /* Allow a null timespec (wait forever). */ 3268 if (uap->uaddr2 == NULL) 3269 ts = NULL; 3270 else { 3271 error = umtx_copyin_timeout32(uap->uaddr2, &timeout); 3272 if (error != 0) 3273 return (error); 3274 ts = &timeout; 3275 } 3276 return (do_lock_umtx32(td, uap->obj, uap->val, ts)); 3277 } 3278 3279 static int 3280 __umtx_op_unlock_umtx_compat32(struct thread *td, struct _umtx_op_args *uap) 3281 { 3282 return (do_unlock_umtx32(td, uap->obj, (uint32_t)uap->val)); 3283 } 3284 3285 static int 3286 __umtx_op_wait_compat32(struct thread *td, struct _umtx_op_args *uap) 3287 { 3288 struct timespec *ts, timeout; 3289 int error; 3290 3291 if (uap->uaddr2 == NULL) 3292 ts = NULL; 3293 else { 3294 error = umtx_copyin_timeout32(uap->uaddr2, &timeout); 3295 if (error != 0) 3296 return (error); 3297 ts = &timeout; 3298 } 3299 return do_wait(td, uap->obj, uap->val, ts, 1, 0); 3300 } 3301 3302 static int 3303 __umtx_op_lock_umutex_compat32(struct thread *td, struct _umtx_op_args *uap) 3304 { 3305 struct timespec *ts, timeout; 3306 int error; 3307 3308 /* Allow a null timespec (wait forever). */ 3309 if (uap->uaddr2 == NULL) 3310 ts = NULL; 3311 else { 3312 error = umtx_copyin_timeout32(uap->uaddr2, &timeout); 3313 if (error != 0) 3314 return (error); 3315 ts = &timeout; 3316 } 3317 return do_lock_umutex(td, uap->obj, ts, 0); 3318 } 3319 3320 static int 3321 __umtx_op_wait_umutex_compat32(struct thread *td, struct _umtx_op_args *uap) 3322 { 3323 struct timespec *ts, timeout; 3324 int error; 3325 3326 /* Allow a null timespec (wait forever). */ 3327 if (uap->uaddr2 == NULL) 3328 ts = NULL; 3329 else { 3330 error = umtx_copyin_timeout32(uap->uaddr2, &timeout); 3331 if (error != 0) 3332 return (error); 3333 ts = &timeout; 3334 } 3335 return do_lock_umutex(td, uap->obj, ts, _UMUTEX_WAIT); 3336 } 3337 3338 static int 3339 __umtx_op_cv_wait_compat32(struct thread *td, struct _umtx_op_args *uap) 3340 { 3341 struct timespec *ts, timeout; 3342 int error; 3343 3344 /* Allow a null timespec (wait forever). */ 3345 if (uap->uaddr2 == NULL) 3346 ts = NULL; 3347 else { 3348 error = umtx_copyin_timeout32(uap->uaddr2, &timeout); 3349 if (error != 0) 3350 return (error); 3351 ts = &timeout; 3352 } 3353 return (do_cv_wait(td, uap->obj, uap->uaddr1, ts, uap->val)); 3354 } 3355 3356 static int 3357 __umtx_op_rw_rdlock_compat32(struct thread *td, struct _umtx_op_args *uap) 3358 { 3359 struct timespec timeout; 3360 int error; 3361 3362 /* Allow a null timespec (wait forever). */ 3363 if (uap->uaddr2 == NULL) { 3364 error = do_rw_rdlock(td, uap->obj, uap->val, 0); 3365 } else { 3366 error = umtx_copyin_timeout32(uap->uaddr2, &timeout); 3367 if (error != 0) 3368 return (error); 3369 error = do_rw_rdlock2(td, uap->obj, uap->val, &timeout); 3370 } 3371 return (error); 3372 } 3373 3374 static int 3375 __umtx_op_rw_wrlock_compat32(struct thread *td, struct _umtx_op_args *uap) 3376 { 3377 struct timespec timeout; 3378 int error; 3379 3380 /* Allow a null timespec (wait forever). */ 3381 if (uap->uaddr2 == NULL) { 3382 error = do_rw_wrlock(td, uap->obj, 0); 3383 } else { 3384 error = umtx_copyin_timeout32(uap->uaddr2, &timeout); 3385 if (error != 0) 3386 return (error); 3387 3388 error = do_rw_wrlock2(td, uap->obj, &timeout); 3389 } 3390 return (error); 3391 } 3392 3393 static int 3394 __umtx_op_wait_uint_private_compat32(struct thread *td, struct _umtx_op_args *uap) 3395 { 3396 struct timespec *ts, timeout; 3397 int error; 3398 3399 if (uap->uaddr2 == NULL) 3400 ts = NULL; 3401 else { 3402 error = umtx_copyin_timeout32(uap->uaddr2, &timeout); 3403 if (error != 0) 3404 return (error); 3405 ts = &timeout; 3406 } 3407 return do_wait(td, uap->obj, uap->val, ts, 1, 1); 3408 } 3409 3410 static int 3411 __umtx_op_sem_wait_compat32(struct thread *td, struct _umtx_op_args *uap) 3412 { 3413 struct timespec *ts, timeout; 3414 int error; 3415 3416 /* Allow a null timespec (wait forever). */ 3417 if (uap->uaddr2 == NULL) 3418 ts = NULL; 3419 else { 3420 error = umtx_copyin_timeout32(uap->uaddr2, &timeout); 3421 if (error != 0) 3422 return (error); 3423 ts = &timeout; 3424 } 3425 return (do_sem_wait(td, uap->obj, ts)); 3426 } 3427 3428 static int 3429 __umtx_op_nwake_private32(struct thread *td, struct _umtx_op_args *uap) 3430 { 3431 int count = uap->val; 3432 uint32_t uaddrs[BATCH_SIZE]; 3433 uint32_t **upp = (uint32_t **)uap->obj; 3434 int tocopy; 3435 int error = 0; 3436 int i, pos = 0; 3437 3438 while (count > 0) { 3439 tocopy = count; 3440 if (tocopy > BATCH_SIZE) 3441 tocopy = BATCH_SIZE; 3442 error = copyin(upp+pos, uaddrs, tocopy * sizeof(uint32_t)); 3443 if (error != 0) 3444 break; 3445 for (i = 0; i < tocopy; ++i) 3446 kern_umtx_wake(td, (void *)(intptr_t)uaddrs[i], 3447 INT_MAX, 1); 3448 count -= tocopy; 3449 pos += tocopy; 3450 } 3451 return (error); 3452 } 3453 3454 static _umtx_op_func op_table_compat32[] = { 3455 __umtx_op_lock_umtx_compat32, /* UMTX_OP_LOCK */ 3456 __umtx_op_unlock_umtx_compat32, /* UMTX_OP_UNLOCK */ 3457 __umtx_op_wait_compat32, /* UMTX_OP_WAIT */ 3458 __umtx_op_wake, /* UMTX_OP_WAKE */ 3459 __umtx_op_trylock_umutex, /* UMTX_OP_MUTEX_LOCK */ 3460 __umtx_op_lock_umutex_compat32, /* UMTX_OP_MUTEX_TRYLOCK */ 3461 __umtx_op_unlock_umutex, /* UMTX_OP_MUTEX_UNLOCK */ 3462 __umtx_op_set_ceiling, /* UMTX_OP_SET_CEILING */ 3463 __umtx_op_cv_wait_compat32, /* UMTX_OP_CV_WAIT*/ 3464 __umtx_op_cv_signal, /* UMTX_OP_CV_SIGNAL */ 3465 __umtx_op_cv_broadcast, /* UMTX_OP_CV_BROADCAST */ 3466 __umtx_op_wait_compat32, /* UMTX_OP_WAIT_UINT */ 3467 __umtx_op_rw_rdlock_compat32, /* UMTX_OP_RW_RDLOCK */ 3468 __umtx_op_rw_wrlock_compat32, /* UMTX_OP_RW_WRLOCK */ 3469 __umtx_op_rw_unlock, /* UMTX_OP_RW_UNLOCK */ 3470 __umtx_op_wait_uint_private_compat32, /* UMTX_OP_WAIT_UINT_PRIVATE */ 3471 __umtx_op_wake_private, /* UMTX_OP_WAKE_PRIVATE */ 3472 __umtx_op_wait_umutex_compat32, /* UMTX_OP_UMUTEX_WAIT */ 3473 __umtx_op_wake_umutex, /* UMTX_OP_UMUTEX_WAKE */ 3474 __umtx_op_sem_wait_compat32, /* UMTX_OP_SEM_WAIT */ 3475 __umtx_op_sem_wake, /* UMTX_OP_SEM_WAKE */ 3476 __umtx_op_nwake_private32 /* UMTX_OP_NWAKE_PRIVATE */ 3477 }; 3478 3479 int 3480 freebsd32_umtx_op(struct thread *td, struct freebsd32_umtx_op_args *uap) 3481 { 3482 if ((unsigned)uap->op < UMTX_OP_MAX) 3483 return (*op_table_compat32[uap->op])(td, 3484 (struct _umtx_op_args *)uap); 3485 return (EINVAL); 3486 } 3487 #endif 3488 3489 void 3490 umtx_thread_init(struct thread *td) 3491 { 3492 td->td_umtxq = umtxq_alloc(); 3493 td->td_umtxq->uq_thread = td; 3494 } 3495 3496 void 3497 umtx_thread_fini(struct thread *td) 3498 { 3499 umtxq_free(td->td_umtxq); 3500 } 3501 3502 /* 3503 * It will be called when new thread is created, e.g fork(). 3504 */ 3505 void 3506 umtx_thread_alloc(struct thread *td) 3507 { 3508 struct umtx_q *uq; 3509 3510 uq = td->td_umtxq; 3511 uq->uq_inherited_pri = PRI_MAX; 3512 3513 KASSERT(uq->uq_flags == 0, ("uq_flags != 0")); 3514 KASSERT(uq->uq_thread == td, ("uq_thread != td")); 3515 KASSERT(uq->uq_pi_blocked == NULL, ("uq_pi_blocked != NULL")); 3516 KASSERT(TAILQ_EMPTY(&uq->uq_pi_contested), ("uq_pi_contested is not empty")); 3517 } 3518 3519 /* 3520 * exec() hook. 3521 */ 3522 static void 3523 umtx_exec_hook(void *arg __unused, struct proc *p __unused, 3524 struct image_params *imgp __unused) 3525 { 3526 umtx_thread_cleanup(curthread); 3527 } 3528 3529 /* 3530 * thread_exit() hook. 3531 */ 3532 void 3533 umtx_thread_exit(struct thread *td) 3534 { 3535 umtx_thread_cleanup(td); 3536 } 3537 3538 /* 3539 * clean up umtx data. 3540 */ 3541 static void 3542 umtx_thread_cleanup(struct thread *td) 3543 { 3544 struct umtx_q *uq; 3545 struct umtx_pi *pi; 3546 3547 if ((uq = td->td_umtxq) == NULL) 3548 return; 3549 3550 mtx_lock_spin(&umtx_lock); 3551 uq->uq_inherited_pri = PRI_MAX; 3552 while ((pi = TAILQ_FIRST(&uq->uq_pi_contested)) != NULL) { 3553 pi->pi_owner = NULL; 3554 TAILQ_REMOVE(&uq->uq_pi_contested, pi, pi_link); 3555 } 3556 mtx_unlock_spin(&umtx_lock); 3557 thread_lock(td); 3558 sched_lend_user_prio(td, PRI_MAX); 3559 thread_unlock(td); 3560 } 3561