git: f660777865fc - main - _utmx_op: don't recurse on chain busy

From: Kyle Evans <kevans_at_FreeBSD.org>
Date: Wed, 13 Nov 2024 22:18:47 UTC
The branch main has been updated by kevans:

URL: https://cgit.FreeBSD.org/src/commit/?id=f660777865fcc28e147b51362412e0286e7df78e

commit f660777865fcc28e147b51362412e0286e7df78e
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2024-11-13 22:18:40 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2024-11-13 22:18:40 +0000

    _utmx_op: don't recurse on chain busy
    
    In handling a PP mutex, we'll busy it as soon as we enter the loop and
    unbusy it either prior to sleeping or at exit time.  In this particular
    case, if we fail to transition the mutex from OWNERDEAD -> owned because
    of casueword(9) failure and the suspend check fails, we'll start over
    and attempt to busy an already-busied chain and irrecoverably lock up
    both this thread and anything else that tries to busy the chain.
    
    Unbusy the chain prior to restarting because I couldn't decide if that
    was a better or worse idea than just keeping track of whether we dirtied
    it in do_lock_pp() and avoiding re-dirty.  This is marginally easier to
    reason about as it returns us to expected state on entry to the loop.
    
    While we're here, simplify the code a bit as `error` will be clobbered
    right after the branch anyways.
    
    Reviewed by:    kib, olce (both earlier version)
    Differential Revision:  https://reviews.freebsd.org/D47493
---
 sys/kern/kern_umtx.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index 705571930d7b..b71fa9a6de24 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -2605,11 +2605,9 @@ do_lock_pp(struct thread *td, struct umutex *m, uint32_t flags,
 			 */
 			if (error == 0) {
 				error = thread_check_susp(td, false);
-				if (error == 0) {
-					if (try != 0)
-						error = EBUSY;
-					else
-						continue;
+				if (error == 0 && try == 0) {
+					umtxq_unbusy_unlocked(&uq->uq_key);
+					continue;
 				}
 				error = 0;
 			}