aboutsummaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2017-02-05 13:37:23 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2017-02-05 13:37:23 +0000
commit993ddec44dd4459d14cbd963264aa380ed0074a6 (patch)
treea65fa44006a59bacbbdb4d6c461114be0b2057f2 /sys/kern
parent96ee43103d39f4c2ed4fdad0a66c86ea47b91126 (diff)
downloadsrc-993ddec44dd4459d14cbd963264aa380ed0074a6.tar.gz
src-993ddec44dd4459d14cbd963264aa380ed0074a6.zip
rwlock: move lockstat handling out of inline primitives
See r313275 for details. One difference here is that recursion handling was removed from the fallback routine. As it is it was never supposed to see a recursed lock in the first place. Future changes will move it out of inline variants, but right now there is no easy to way to test if the lock is recursed without reading additional words.
Notes
Notes: svn path=/head/; revision=313282
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_rwlock.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c
index 435caa2fa17d..c024de5cc8cb 100644
--- a/sys/kern/kern_rwlock.c
+++ b/sys/kern/kern_rwlock.c
@@ -283,6 +283,7 @@ void
_rw_wlock_cookie(volatile uintptr_t *c, const char *file, int line)
{
struct rwlock *rw;
+ uintptr_t tid, v;
if (SCHEDULER_STOPPED())
return;
@@ -296,7 +297,14 @@ _rw_wlock_cookie(volatile uintptr_t *c, const char *file, int line)
("rw_wlock() of destroyed rwlock @ %s:%d", file, line));
WITNESS_CHECKORDER(&rw->lock_object, LOP_NEWORDER | LOP_EXCLUSIVE, file,
line, NULL);
- __rw_wlock(rw, curthread, file, line);
+ tid = (uintptr_t)curthread;
+ v = RW_UNLOCKED;
+ if (!_rw_write_lock_fetch(rw, &v, tid))
+ _rw_wlock_hard(rw, v, tid, file, line);
+ else
+ LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(rw__acquire, rw,
+ 0, 0, file, line, LOCKSTAT_WRITER);
+
LOCK_LOG_LOCK("WLOCK", &rw->lock_object, 0, rw->rw_recurse, file, line);
WITNESS_LOCK(&rw->lock_object, LOP_EXCLUSIVE, file, line);
TD_LOCKS_INC(curthread);
@@ -355,7 +363,11 @@ _rw_wunlock_cookie(volatile uintptr_t *c, const char *file, int line)
WITNESS_UNLOCK(&rw->lock_object, LOP_EXCLUSIVE, file, line);
LOCK_LOG_LOCK("WUNLOCK", &rw->lock_object, 0, rw->rw_recurse, file,
line);
- __rw_wunlock(rw, curthread, file, line);
+ if (rw->rw_recurse)
+ rw->rw_recurse--;
+ else
+ _rw_wunlock_hard(rw, (uintptr_t)curthread, file, line);
+
TD_LOCKS_DEC(curthread);
}
@@ -998,13 +1010,12 @@ __rw_wunlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
return;
rw = rwlock2rw(c);
+ MPASS(!rw_recursed(rw));
- if (rw_wlocked(rw) && rw_recursed(rw)) {
- rw->rw_recurse--;
- if (LOCK_LOG_TEST(&rw->lock_object, 0))
- CTR2(KTR_LOCK, "%s: %p unrecursing", __func__, rw);
+ LOCKSTAT_PROFILE_RELEASE_RWLOCK(rw__release, rw,
+ LOCKSTAT_WRITER);
+ if (_rw_write_unlock(rw, tid))
return;
- }
KASSERT(rw->rw_lock & (RW_LOCK_READ_WAITERS | RW_LOCK_WRITE_WAITERS),
("%s: neither of the waiter flags are set", __func__));