git: b2e37d027f10 - stable/15 - libthr: Fix some bugs in trylock

From: ShengYi Hung <aokblast_at_FreeBSD.org>
Date: Sun, 01 Nov 2026 22:08:40 UTC
The branch stable/15 has been updated by aokblast:

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

commit b2e37d027f10910bb2e7577df906dadd66739153
Author:     ShengYi Hung <aokblast@FreeBSD.org>
AuthorDate: 2026-10-07 02:30:48 +0000
Commit:     ShengYi Hung <aokblast@FreeBSD.org>
CommitDate: 2026-11-01 22:08:00 +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
    
    (cherry picked from commit de2c0f157a9cce0b763da9ae97ada870fa4d1824)
---
 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));
 }