git: de2c0f157a9c - main - libthr: Fix some bugs in trylock

From: ShengYi Hung <aokblast_at_FreeBSD.org>
Date: Wed, 07 Oct 2026 17:14:19 UTC
The branch main has been updated by aokblast:

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

commit de2c0f157a9cce0b763da9ae97ada870fa4d1824
Author:     ShengYi Hung <aokblast@FreeBSD.org>
AuthorDate: 2026-10-07 02:30:48 +0000
Commit:     ShengYi Hung <aokblast@FreeBSD.org>
CommitDate: 2026-10-07 17:14:04 +0000

    libthr: Fix some bugs in trylock
    
    1. When contester > 2, a release causes kernel set CONTENTION bit but
       with no owner. In this case, the userspace should be able to try the
       lock instead of fall immediately. We copy this from trylock2.
    2. A PI mutex should consult to kernel instead of decided by userspace
       itself.
    
    Reviewed by:    kib
    MFC after:      2 weeks
    Differential Revision: https://reviews.freebsd.org/D60427
---
 lib/libthr/thread/thr_umtx.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/lib/libthr/thread/thr_umtx.h b/lib/libthr/thread/thr_umtx.h
index 4e1c08ca64e8..eada8ab9297f 100644
--- a/lib/libthr/thread/thr_umtx.h
+++ b/lib/libthr/thread/thr_umtx.h
@@ -82,13 +82,19 @@ _thr_umutex_trylock(struct umutex *mtx, uint32_t id)
 
 	if (atomic_cmpset_acq_32(&mtx->m_owner, UMUTEX_UNOWNED, id))
 		return (0);
+	if ((uint32_t)mtx->m_owner == UMUTEX_CONTESTED &&
+	    __predict_true((mtx->m_flags & (UMUTEX_PRIO_PROTECT |
+	   UMUTEX_PRIO_INHERIT)) == 0) &&
+	   atomic_cmpset_acq_32(&mtx->m_owner, UMUTEX_CONTESTED,
+	   id | UMUTEX_CONTESTED))
+		return (0);
 	if (__predict_false((uint32_t)mtx->m_owner == UMUTEX_RB_OWNERDEAD) &&
 	    atomic_cmpset_acq_32(&mtx->m_owner, UMUTEX_RB_OWNERDEAD,
 	    id | UMUTEX_CONTESTED))
 		return (EOWNERDEAD);
 	if (__predict_false((uint32_t)mtx->m_owner == UMUTEX_RB_NOTRECOV))
 		return (ENOTRECOVERABLE);
-	if ((mtx->m_flags & UMUTEX_PRIO_PROTECT) == 0)
+	if ((mtx->m_flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT)) == 0)
 		return (EBUSY);
 	return (__thr_umutex_trylock(mtx));
 }