summaryrefslogtreecommitdiffstats
path: root/sys/sys/mutex.h
diff options
context:
space:
mode:
authormjg <mjg@FreeBSD.org>2017-03-16 06:45:36 +0000
committermjg <mjg@FreeBSD.org>2017-03-16 06:45:36 +0000
commitf690d08c057e8a0ec75f68e6a3b2e1d3d68ec977 (patch)
tree79547747719192ef3f44b1bc780f86e4dc0eefc9 /sys/sys/mutex.h
parent75c730bce9acd14b7ecb04b7be87b14661c92be3 (diff)
downloadFreeBSD-src-f690d08c057e8a0ec75f68e6a3b2e1d3d68ec977.zip
FreeBSD-src-f690d08c057e8a0ec75f68e6a3b2e1d3d68ec977.tar.gz
MFC r313275,r313280,r313282,r313335:
mtx: move lockstat handling out of inline primitives Lockstat requires checking if it is enabled and if so, calling a 6 argument function. Further, determining whether to call it on unlock requires pre-reading the lock value. This is problematic in at least 3 ways: - more branches in the hot path than necessary - additional cacheline ping pong under contention - bigger code Instead, check first if lockstat handling is necessary and if so, just fall back to regular locking routines. For this purpose a new macro is introduced (LOCKSTAT_PROFILE_ENABLED). LOCK_PROFILING uninlines all primitives. Fold in the current inline lock variant into the _mtx_lock_flags to retain the support. With this change the inline variants are not used when LOCK_PROFILING is defined and thus can ignore its existence. This results in: text data bss dec hex filename 22259667 1303208 4994976 28557851 1b3c21b kernel.orig 21797315 1303208 4994976 28095499 1acb40b kernel.patched i.e. about 3% reduction in text size. A remaining action is to remove spurious arguments for internal kernel consumers. == sx: move lockstat handling out of inline primitives See r313275 for details. == 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. == locks: fix recursion support after recent changes When a relevant lockstat probe is enabled the fallback primitive is called with a constant signifying a free lock. This works fine for typical cases but breaks with recursion, since it checks if the passed value is that of the executing thread. Read the value if necessary.
Diffstat (limited to 'sys/sys/mutex.h')
-rw-r--r--sys/sys/mutex.h21
1 files changed, 8 insertions, 13 deletions
diff --git a/sys/sys/mutex.h b/sys/sys/mutex.h
index 841bd76..42f26fd 100644
--- a/sys/sys/mutex.h
+++ b/sys/sys/mutex.h
@@ -171,10 +171,8 @@ void thread_lock_flags_(struct thread *, int, const char *, int);
#define _mtx_obtain_lock(mp, tid) \
atomic_cmpset_acq_ptr(&(mp)->mtx_lock, MTX_UNOWNED, (tid))
-#define _mtx_obtain_lock_fetch(mp, vp, tid) ({ \
- *vp = MTX_UNOWNED; \
- atomic_fcmpset_acq_ptr(&(mp)->mtx_lock, vp, (tid)); \
-})
+#define _mtx_obtain_lock_fetch(mp, vp, tid) \
+ atomic_fcmpset_acq_ptr(&(mp)->mtx_lock, vp, (tid))
/* Try to release mtx_lock if it is unrecursed and uncontested. */
#define _mtx_release_lock(mp, tid) \
@@ -193,13 +191,11 @@ void thread_lock_flags_(struct thread *, int, const char *, int);
/* Lock a normal mutex. */
#define __mtx_lock(mp, tid, opts, file, line) do { \
uintptr_t _tid = (uintptr_t)(tid); \
- uintptr_t _v; \
+ uintptr_t _v = MTX_UNOWNED; \
\
- if (!_mtx_obtain_lock_fetch((mp), &_v, _tid)) \
+ if (__predict_false(LOCKSTAT_PROFILE_ENABLED(adaptive__acquire) ||\
+ !_mtx_obtain_lock_fetch((mp), &_v, _tid))) \
_mtx_lock_sleep((mp), _v, _tid, (opts), (file), (line));\
- else \
- LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(adaptive__acquire, \
- mp, 0, 0, file, line); \
} while (0)
/*
@@ -211,7 +207,7 @@ void thread_lock_flags_(struct thread *, int, const char *, int);
#ifdef SMP
#define __mtx_lock_spin(mp, tid, opts, file, line) do { \
uintptr_t _tid = (uintptr_t)(tid); \
- uintptr_t _v; \
+ uintptr_t _v = MTX_UNOWNED; \
\
spinlock_enter(); \
if (!_mtx_obtain_lock_fetch((mp), &_v, _tid)) \
@@ -267,9 +263,8 @@ void thread_lock_flags_(struct thread *, int, const char *, int);
#define __mtx_unlock(mp, tid, opts, file, line) do { \
uintptr_t _tid = (uintptr_t)(tid); \
\
- if ((mp)->mtx_recurse == 0) \
- LOCKSTAT_PROFILE_RELEASE_LOCK(adaptive__release, mp); \
- if (!_mtx_release_lock((mp), _tid)) \
+ if (__predict_false(LOCKSTAT_PROFILE_ENABLED(adaptive__release) ||\
+ !_mtx_release_lock((mp), _tid))) \
_mtx_unlock_sleep((mp), (opts), (file), (line)); \
} while (0)
OpenPOWER on IntegriCloud