diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2024-08-27 21:32:51 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2024-08-28 14:33:46 +0000 |
commit | 75447afca868f82f1c53c5be32dccd777813ec1a (patch) | |
tree | f659ba6c88bcf066012e342b2750017a5b6e7114 | |
parent | b1c3a4d75f4ff74218434a11cdd4e56632e13711 (diff) | |
download | src-75447afca868f82f1c53c5be32dccd777813ec1a.tar.gz src-75447afca868f82f1c53c5be32dccd777813ec1a.zip |
rangelocks: extract the cheat mode drain code
Reviewed by: markj
Tested by: lwhsu
Sponsored by: The FreeBSD Foundation
Differential revision: https://reviews.freebsd.org/D46465
-rw-r--r-- | sys/kern/kern_rangelock.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/sys/kern/kern_rangelock.c b/sys/kern/kern_rangelock.c index 38449f71a8b7..0e62b91b4ee7 100644 --- a/sys/kern/kern_rangelock.c +++ b/sys/kern/kern_rangelock.c @@ -82,6 +82,24 @@ SYSCTL_INT(_debug, OID_AUTO, rangelock_cheat, CTLFLAG_RWTUN, #define RL_RET_CHEAT_RLOCKED 0x1100 #define RL_RET_CHEAT_WLOCKED 0x2200 +static void +rangelock_cheat_drain(struct rangelock *lock) +{ + uintptr_t v; + + DROP_GIANT(); + for (;;) { + v = (uintptr_t)atomic_load_ptr(&lock->head); + if ((v & RL_CHEAT_DRAINING) == 0) + break; + sleepq_add(&lock->head, NULL, "ranged1", 0, 0); + sleepq_wait(&lock->head, PRI_USER); + sleepq_lock(&lock->head); + } + sleepq_release(&lock->head); + PICKUP_GIANT(); +} + static bool rangelock_cheat_lock(struct rangelock *lock, int locktype, bool trylock, void **cookie) @@ -99,17 +117,7 @@ drain: } sleepq_lock(&lock->head); drain1: - DROP_GIANT(); - for (;;) { - v = (uintptr_t)atomic_load_ptr(&lock->head); - if ((v & RL_CHEAT_DRAINING) == 0) - break; - sleepq_add(&lock->head, NULL, "ranged1", 0, 0); - sleepq_wait(&lock->head, PRI_USER); - sleepq_lock(&lock->head); - } - sleepq_release(&lock->head); - PICKUP_GIANT(); + rangelock_cheat_drain(lock); return (false); } |