Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/external/bsd/drm2/linux drm/linux_ww_mutex: Fix wait loops.
details: https://anonhg.NetBSD.org/src/rev/dd982c95a069
branches: trunk
changeset: 378329:dd982c95a069
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sat Jul 29 22:43:56 2023 +0000
description:
drm/linux_ww_mutex: Fix wait loops.
If cv_wait_sig returns because a signal is delivered, we may
nonetheless have been granted the lock. It is harmless for us to
ignore this fact in three of the four paths, but in
ww_mutex_state_wait_sig, we may now have ownership of the lock and
MUST NOT return failure because the caller MUST release the lock
before destroying the ww_acquire_ctx.
While here, restructure the other three loops for clarity, so they
match the structure of the fourth and so they have a little less
impenetrable negation.
PR kern/57537
XXX pullup-8
XXX pullup-9
XXX pullup-10
diffstat:
sys/external/bsd/drm2/linux/linux_ww_mutex.c | 60 ++++++++++++++++++++-------
1 files changed, 44 insertions(+), 16 deletions(-)
diffs (123 lines):
diff -r e078f6e49046 -r dd982c95a069 sys/external/bsd/drm2/linux/linux_ww_mutex.c
--- a/sys/external/bsd/drm2/linux/linux_ww_mutex.c Sat Jul 29 17:54:54 2023 +0000
+++ b/sys/external/bsd/drm2/linux/linux_ww_mutex.c Sat Jul 29 22:43:56 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_ww_mutex.c,v 1.14 2022/03/18 23:33:41 riastradh Exp $ */
+/* $NetBSD: linux_ww_mutex.c,v 1.15 2023/07/29 22:43:56 riastradh Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_ww_mutex.c,v 1.14 2022/03/18 23:33:41 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_ww_mutex.c,v 1.15 2023/07/29 22:43:56 riastradh Exp $");
#include <sys/types.h>
#include <sys/atomic.h>
@@ -286,8 +286,14 @@ ww_mutex_state_wait(struct ww_mutex *mut
KASSERT(mutex_owned(&mutex->wwm_lock));
KASSERT(mutex->wwm_state == state);
- do cv_wait(&mutex->wwm_cv, &mutex->wwm_lock);
- while (mutex->wwm_state == state);
+
+ for (;;) {
+ cv_wait(&mutex->wwm_cv, &mutex->wwm_lock);
+ if (mutex->wwm_state != state)
+ break;
+ }
+
+ KASSERT(mutex->wwm_state != state);
}
/*
@@ -310,18 +316,26 @@ ww_mutex_state_wait_sig(struct ww_mutex
KASSERT(mutex_owned(&mutex->wwm_lock));
KASSERT(mutex->wwm_state == state);
- do {
+
+ for (;;) {
/* XXX errno NetBSD->Linux */
ret = -cv_wait_sig(&mutex->wwm_cv, &mutex->wwm_lock);
+ if (mutex->wwm_state != state) {
+ ret = 0;
+ break;
+ }
if (ret) {
KASSERTMSG((ret == -EINTR || ret == -ERESTART),
"ret=%d", ret);
ret = -EINTR;
break;
}
- } while (mutex->wwm_state == state);
+ }
KASSERTMSG((ret == 0 || ret == -EINTR), "ret=%d", ret);
+ KASSERTMSG(ret != 0 || mutex->wwm_state != state,
+ "ret=%d mutex=%p mutex->wwm_state=%d state=%d",
+ ret, mutex, mutex->wwm_state, state);
return ret;
}
@@ -363,12 +377,18 @@ ww_mutex_lock_wait(struct ww_mutex *mute
"ticket number reused: %"PRId64" (%p) %"PRId64" (%p)",
ctx->wwx_ticket, ctx, collision->wwx_ticket, collision);
- do cv_wait(&mutex->wwm_cv, &mutex->wwm_lock);
- while (!(((mutex->wwm_state == WW_CTX) ||
- (mutex->wwm_state == WW_WANTOWN)) &&
- (mutex->wwm_u.ctx == ctx)));
+ for (;;) {
+ cv_wait(&mutex->wwm_cv, &mutex->wwm_lock);
+ if ((mutex->wwm_state == WW_CTX ||
+ mutex->wwm_state == WW_WANTOWN) &&
+ mutex->wwm_u.ctx == ctx)
+ break;
+ }
rb_tree_remove_node(&mutex->wwm_waiters, ctx);
+
+ KASSERT(mutex->wwm_state == WW_CTX || mutex->wwm_state == WW_WANTOWN);
+ KASSERT(mutex->wwm_u.ctx == ctx);
}
/*
@@ -411,21 +431,29 @@ ww_mutex_lock_wait_sig(struct ww_mutex *
"ticket number reused: %"PRId64" (%p) %"PRId64" (%p)",
ctx->wwx_ticket, ctx, collision->wwx_ticket, collision);
- do {
+ for (;;) {
/* XXX errno NetBSD->Linux */
ret = -cv_wait_sig(&mutex->wwm_cv, &mutex->wwm_lock);
+ if ((mutex->wwm_state == WW_CTX ||
+ mutex->wwm_state == WW_WANTOWN) &&
+ mutex->wwm_u.ctx == ctx) {
+ ret = 0;
+ break;
+ }
if (ret) {
KASSERTMSG((ret == -EINTR || ret == -ERESTART),
"ret=%d", ret);
ret = -EINTR;
- goto out;
+ break;
}
- } while (!(((mutex->wwm_state == WW_CTX) ||
- (mutex->wwm_state == WW_WANTOWN)) &&
- (mutex->wwm_u.ctx == ctx)));
+ }
+
+ rb_tree_remove_node(&mutex->wwm_waiters, ctx);
-out: rb_tree_remove_node(&mutex->wwm_waiters, ctx);
KASSERTMSG((ret == 0 || ret == -EINTR), "ret=%d", ret);
+ KASSERT(ret != 0 ||
+ mutex->wwm_state == WW_CTX || mutex->wwm_state == WW_WANTOWN);
+ KASSERT(ret != 0 || mutex->wwm_u.ctx == ctx);
return ret;
}
Home |
Main Index |
Thread Index |
Old Index