diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -2612,15 +2612,11 @@ umtxq_unbusy_unlocked(&uq->uq_key); continue; } - error = 0; } } else if (owner == UMUTEX_RB_NOTRECOV) { error = ENOTRECOVERABLE; } - if (try != 0) - error = EBUSY; - /* * If we caught a signal, we have retried and now * exit immediately. @@ -2628,6 +2624,19 @@ if (error != 0) break; + /* + * We may have gotten a spurious failure. + */ + if (owner == UMUTEX_CONTESTED) { + umtxq_unbusy_unlocked(&uq->uq_key); + continue; + } + + if (try != 0) { + error = EBUSY; + break; + } + umtxq_lock(&uq->uq_key); umtxq_insert(uq); umtxq_unbusy(&uq->uq_key); @@ -2834,6 +2843,14 @@ if (error != 0) break; + /* + * We may have gotten a spurious failure. + */ + if (owner == UMUTEX_CONTESTED) { + umtxq_unbusy_unlocked(&uq->uq_key); + continue; + } + /* * We set the contested bit, sleep. Otherwise the lock changed * and we need to retry or we lost a race to the thread