From fd336e2ac08442bd7d7cd58b107e95fa148b62b9 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 31 Jul 2019 19:16:49 +0000 Subject: [PATCH] Fix handling of transient casueword(9) failures in do_sem_wait(). In particular, restart should be only done when the failure is transient. For this, recheck the count1 value after the operation. Note that do_sem_wait() is older usem interface. Reported and tested by: bdrewery Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/kern/kern_umtx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index bb9984579753..6c914ab6f3ea 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -3229,7 +3229,8 @@ do_sem_wait(struct thread *td, struct _usem *sem, struct _umtx_time *timeout) rv = casueword32(&sem->_has_waiters, 0, &count1, 1); if (rv == 0) rv1 = fueword32(&sem->_count, &count); - if (rv == -1 || (rv == 0 && (rv1 == -1 || count != 0)) || rv == 1) { + if (rv == -1 || (rv == 0 && (rv1 == -1 || count != 0)) || + (rv == 1 && count1 == 0)) { umtxq_lock(&uq->uq_key); umtxq_unbusy(&uq->uq_key); umtxq_remove(uq);