| 578 | } |
| 579 | |
| 580 | static __noinline int |
| 581 | lockmgr_slock_hard(struct lock *lk, u_int flags, struct lock_object *ilk, |
| 582 | const char *file, int line, struct lockmgr_wait *lwa) |
| 583 | { |
| 584 | uintptr_t tid, x; |
| 585 | int error = 0; |
| 586 | const char *iwmesg; |
| 587 | int ipri, itimo; |
| 588 | |
| 589 | #ifdef KDTRACE_HOOKS |
| 590 | uint64_t sleep_time = 0; |
| 591 | #endif |
| 592 | #ifdef LOCK_PROFILING |
| 593 | uint64_t waittime = 0; |
| 594 | int contested = 0; |
| 595 | #endif |
| 596 | struct lock_delay_arg lda; |
| 597 | |
| 598 | if (KERNEL_PANICKED()) |
| 599 | goto out; |
| 600 | |
| 601 | tid = (uintptr_t)curthread; |
| 602 | |
| 603 | if (LK_CAN_WITNESS(flags)) |
| 604 | WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER, |
| 605 | file, line, flags & LK_INTERLOCK ? ilk : NULL); |
| 606 | x = lockmgr_read_value(lk); |
| 607 | lock_delay_arg_init(&lda, &lockmgr_delay); |
| 608 | if (!lk_adaptive) |
| 609 | flags &= ~LK_ADAPTIVE; |
| 610 | /* |
| 611 | * The lock may already be locked exclusive by curthread, |
| 612 | * avoid deadlock. |
| 613 | */ |
| 614 | if (LK_HOLDER(x) == tid) { |
| 615 | LOCK_LOG2(lk, |
| 616 | "%s: %p already held in exclusive mode", |
| 617 | __func__, lk); |
| 618 | error = EDEADLK; |
| 619 | goto out; |
| 620 | } |
| 621 | |
| 622 | for (;;) { |
| 623 | if (lockmgr_slock_try(lk, &x, flags, false)) |
| 624 | break; |
| 625 | |
| 626 | if ((flags & (LK_ADAPTIVE | LK_INTERLOCK)) == LK_ADAPTIVE) { |
| 627 | if (lockmgr_slock_adaptive(&lda, lk, &x, flags)) |
| 628 | continue; |
| 629 | } |
| 630 | |
| 631 | #ifdef HWPMC_HOOKS |
| 632 | PMC_SOFT_CALL( , , lock, failed); |
| 633 | #endif |
| 634 | lock_profile_obtain_lock_failed(&lk->lock_object, |
| 635 | &contested, &waittime); |
| 636 | |
| 637 | /* |
no test coverage detected