Module Name: src Committed By: riastradh Date: Sun Dec 19 11:21:45 UTC 2021
Modified Files: src/sys/external/bsd/drm2/include/linux: rwsem.h src/sys/external/bsd/drm2/linux: linux_rwsem.c Log Message: linux: Teach rw semaphores about lockdebug. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/external/bsd/drm2/include/linux/rwsem.h cvs rdiff -u -r1.2 -r1.3 src/sys/external/bsd/drm2/linux/linux_rwsem.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/include/linux/rwsem.h diff -u src/sys/external/bsd/drm2/include/linux/rwsem.h:1.3 src/sys/external/bsd/drm2/include/linux/rwsem.h:1.4 --- src/sys/external/bsd/drm2/include/linux/rwsem.h:1.3 Sun Dec 19 11:21:30 2021 +++ src/sys/external/bsd/drm2/include/linux/rwsem.h Sun Dec 19 11:21:45 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: rwsem.h,v 1.3 2021/12/19 11:21:30 riastradh Exp $ */ +/* $NetBSD: rwsem.h,v 1.4 2021/12/19 11:21:45 riastradh Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -60,6 +60,7 @@ struct rw_semaphore { struct lwp *rws_writer; unsigned rws_readers; bool rws_writewanted; + bool rws_debug; }; void init_rwsem(struct rw_semaphore *); Index: src/sys/external/bsd/drm2/linux/linux_rwsem.c diff -u src/sys/external/bsd/drm2/linux/linux_rwsem.c:1.2 src/sys/external/bsd/drm2/linux/linux_rwsem.c:1.3 --- src/sys/external/bsd/drm2/linux/linux_rwsem.c:1.2 Sun Dec 19 11:21:38 2021 +++ src/sys/external/bsd/drm2/linux/linux_rwsem.c Sun Dec 19 11:21:45 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: linux_rwsem.c,v 1.2 2021/12/19 11:21:38 riastradh Exp $ */ +/* $NetBSD: linux_rwsem.c,v 1.3 2021/12/19 11:21:45 riastradh Exp $ */ /*- * Copyright (c) 2021 The NetBSD Foundation, Inc. @@ -27,12 +27,13 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux_rwsem.c,v 1.2 2021/12/19 11:21:38 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_rwsem.c,v 1.3 2021/12/19 11:21:45 riastradh Exp $"); #include <sys/types.h> #include <sys/condvar.h> #include <sys/lwp.h> +#include <sys/lockdebug.h> #include <sys/rwlock.h> #include <machine/limits.h> @@ -41,6 +42,40 @@ __KERNEL_RCSID(0, "$NetBSD: linux_rwsem. #include <linux/rwsem.h> +#define RWSEM_WANTLOCK(RWSEM) \ + LOCKDEBUG_WANTLOCK((RWSEM)->rws_debug, (RWSEM), \ + (uintptr_t)__builtin_return_address(0), 0) +#define RWSEM_LOCKED_EX(RWSEM) \ + LOCKDEBUG_LOCKED((RWSEM)->rws_debug, (RWSEM), NULL, \ + (uintptr_t)__builtin_return_address(0), 0) +#define RWSEM_LOCKED_SH(RWSEM) \ + LOCKDEBUG_LOCKED((RWSEM)->rws_debug, (RWSEM), NULL, \ + (uintptr_t)__builtin_return_address(0), 1) +#define RWSEM_UNLOCKED_EX(RWSEM) \ + LOCKDEBUG_UNLOCKED((RWSEM)->rws_debug, (RWSEM), \ + (uintptr_t)__builtin_return_address(0), 0) +#define RWSEM_UNLOCKED_SH(RWSEM) \ + LOCKDEBUG_UNLOCKED((RWSEM)->rws_debug, (RWSEM), \ + (uintptr_t)__builtin_return_address(0), 1) + +#ifdef LOCKDEBUG +static void +rwsem_dump(const volatile void *cookie, lockop_printer_t pr) +{ + const volatile struct rw_semaphore *rwsem = cookie; + + pr("%-13s: %p", "writer", rwsem->rws_writer); + pr("%-13s: %u", "readers", rwsem->rws_readers); + pr("%-13s: %s", "writewanted", rwsem->rws_writewanted ? "yes" : "no"); +} + +static lockops_t rwsem_lockops = { + .lo_name = "Linux read/write semaphore", + .lo_type = LOCKOPS_SLEEP, + .lo_dump = rwsem_dump, +}; +#endif + void init_rwsem(struct rw_semaphore *rwsem) { @@ -49,6 +84,11 @@ init_rwsem(struct rw_semaphore *rwsem) cv_init(&rwsem->rws_cv, "lnxrwsem"); rwsem->rws_writer = NULL; rwsem->rws_readers = 0; + +#ifdef LOCKDEBUG + rwsem->rws_debug = LOCKDEBUG_ALLOC(rwsem, &rwsem_lockops, + (uintptr_t)__builtin_return_address(0)); +#endif } void @@ -57,6 +97,11 @@ destroy_rwsem(struct rw_semaphore *rwsem KASSERT(rwsem->rws_readers == 0); KASSERT(rwsem->rws_writer == NULL); + +#ifdef LOCKDEBUG + LOCKDEBUG_FREE(rwsem->rws_debug, rwsem); +#endif + cv_destroy(&rwsem->rws_cv); mutex_destroy(&rwsem->rws_lock); } @@ -65,12 +110,16 @@ void down_read(struct rw_semaphore *rwsem) { + RWSEM_WANTLOCK(rwsem); + mutex_enter(&rwsem->rws_lock); while (rwsem->rws_writer || rwsem->rws_writewanted) cv_wait(&rwsem->rws_cv, &rwsem->rws_lock); KASSERT(rwsem->rws_readers < UINT_MAX); rwsem->rws_readers++; mutex_exit(&rwsem->rws_lock); + + RWSEM_LOCKED_SH(rwsem); } bool @@ -94,6 +143,9 @@ down_read_trylock(struct rw_semaphore *r } mutex_exit(&rwsem->rws_lock); + if (ret) + RWSEM_LOCKED_SH(rwsem); + return ret; } @@ -101,6 +153,8 @@ void up_read(struct rw_semaphore *rwsem) { + RWSEM_UNLOCKED_SH(rwsem); + mutex_enter(&rwsem->rws_lock); KASSERT(rwsem->rws_readers); KASSERT(rwsem->rws_writer == NULL); @@ -113,6 +167,8 @@ void down_write(struct rw_semaphore *rwsem) { + RWSEM_WANTLOCK(rwsem); + mutex_enter(&rwsem->rws_lock); /* If another writer is waiting, get in the queue. */ @@ -138,12 +194,16 @@ down_write(struct rw_semaphore *rwsem) rwsem->rws_writer = curlwp; mutex_exit(&rwsem->rws_lock); + + RWSEM_LOCKED_EX(rwsem); } void up_write(struct rw_semaphore *rwsem) { + RWSEM_UNLOCKED_EX(rwsem); + mutex_enter(&rwsem->rws_lock); KASSERT(rwsem->rws_writer == curlwp); KASSERT(rwsem->rws_readers == 0); @@ -156,6 +216,8 @@ void downgrade_write(struct rw_semaphore *rwsem) { + RWSEM_UNLOCKED_EX(rwsem); + mutex_enter(&rwsem->rws_lock); KASSERT(rwsem->rws_writer == curlwp); KASSERT(rwsem->rws_readers == 0); @@ -163,4 +225,6 @@ downgrade_write(struct rw_semaphore *rws rwsem->rws_readers = 1; cv_broadcast(&rwsem->rws_cv); mutex_exit(&rwsem->rws_lock); + + RWSEM_LOCKED_SH(rwsem); }