Module Name: src Committed By: martin Date: Tue Aug 1 17:29:15 UTC 2023
Modified Files: src/sys/external/bsd/drm2/linux [netbsd-8]: linux_ww_mutex.c Log Message: Pull up following revision(s) (requested by riastradh in ticket #1876): sys/external/bsd/drm2/linux/linux_ww_mutex.c: revision 1.15 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 To generate a diff of this commit: cvs rdiff -u -r1.2.10.5 -r1.2.10.6 \ src/sys/external/bsd/drm2/linux/linux_ww_mutex.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/external/bsd/drm2/linux/linux_ww_mutex.c diff -u src/sys/external/bsd/drm2/linux/linux_ww_mutex.c:1.2.10.5 src/sys/external/bsd/drm2/linux/linux_ww_mutex.c:1.2.10.6 --- src/sys/external/bsd/drm2/linux/linux_ww_mutex.c:1.2.10.5 Tue Aug 1 17:19:57 2023 +++ src/sys/external/bsd/drm2/linux/linux_ww_mutex.c Tue Aug 1 17:29:15 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: linux_ww_mutex.c,v 1.2.10.5 2023/08/01 17:19:57 martin Exp $ */ +/* $NetBSD: linux_ww_mutex.c,v 1.2.10.6 2023/08/01 17:29:15 martin 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.2.10.5 2023/08/01 17:19:57 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_ww_mutex.c,v 1.2.10.6 2023/08/01 17:29:15 martin Exp $"); #include <sys/types.h> #include <sys/atomic.h> @@ -271,8 +271,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); } /* @@ -295,18 +301,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; } @@ -348,12 +362,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); } /* @@ -396,21 +416,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; }