mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 08:43:19 -04:00
lockmgr: denote recursion with a bit in lock value
This reduces excessive reads from the lock. Tested by: pho
This commit is contained in:
parent
f6b091fbbd
commit
4aff9f5d99
2 changed files with 12 additions and 7 deletions
|
|
@ -736,6 +736,7 @@ lockmgr_xlock_hard(struct lock *lk, u_int flags, struct lock_object *ilk,
|
|||
panic("%s: recursing on non recursive lockmgr %p "
|
||||
"@ %s:%d\n", __func__, lk, file, line);
|
||||
}
|
||||
atomic_set_ptr(&lk->lk_lock, LK_WRITER_RECURSED);
|
||||
lk->lk_recurse++;
|
||||
LOCK_LOG2(lk, "%s: %p recursing", __func__, lk);
|
||||
LOCK_LOG_LOCK("XLOCK", &lk->lock_object, 0,
|
||||
|
|
@ -1039,9 +1040,11 @@ lockmgr_xunlock_hard(struct lock *lk, uintptr_t x, u_int flags, struct lock_obje
|
|||
* The lock is held in exclusive mode.
|
||||
* If the lock is recursed also, then unrecurse it.
|
||||
*/
|
||||
if (lockmgr_xlocked_v(x) && lockmgr_recursed(lk)) {
|
||||
if (lockmgr_recursed_v(x)) {
|
||||
LOCK_LOG2(lk, "%s: %p unrecursing", __func__, lk);
|
||||
lk->lk_recurse--;
|
||||
if (lk->lk_recurse == 0)
|
||||
atomic_clear_ptr(&lk->lk_lock, LK_WRITER_RECURSED);
|
||||
goto out;
|
||||
}
|
||||
if (tid != LK_KERNPROC)
|
||||
|
|
@ -1187,9 +1190,8 @@ lockmgr_unlock(struct lock *lk)
|
|||
} else {
|
||||
tid = (uintptr_t)curthread;
|
||||
lockmgr_note_exclusive_release(lk, file, line);
|
||||
if (!lockmgr_recursed(lk) &&
|
||||
atomic_cmpset_rel_ptr(&lk->lk_lock, tid, LK_UNLOCKED)) {
|
||||
LOCKSTAT_PROFILE_RELEASE_RWLOCK(lockmgr__release, lk, LOCKSTAT_WRITER);
|
||||
if (x == tid && atomic_cmpset_rel_ptr(&lk->lk_lock, tid, LK_UNLOCKED)) {
|
||||
LOCKSTAT_PROFILE_RELEASE_RWLOCK(lockmgr__release, lk,LOCKSTAT_WRITER);
|
||||
} else {
|
||||
return (lockmgr_xunlock_hard(lk, x, LK_RELEASE, NULL, file, line));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,13 +42,14 @@
|
|||
#define LK_SHARED_WAITERS 0x02
|
||||
#define LK_EXCLUSIVE_WAITERS 0x04
|
||||
#define LK_EXCLUSIVE_SPINNERS 0x08
|
||||
#define LK_WRITER_RECURSED 0x10
|
||||
#define LK_ALL_WAITERS \
|
||||
(LK_SHARED_WAITERS | LK_EXCLUSIVE_WAITERS)
|
||||
#define LK_FLAGMASK \
|
||||
(LK_SHARE | LK_ALL_WAITERS | LK_EXCLUSIVE_SPINNERS)
|
||||
(LK_SHARE | LK_ALL_WAITERS | LK_EXCLUSIVE_SPINNERS | LK_WRITER_RECURSED)
|
||||
|
||||
#define LK_HOLDER(x) ((x) & ~LK_FLAGMASK)
|
||||
#define LK_SHARERS_SHIFT 4
|
||||
#define LK_SHARERS_SHIFT 5
|
||||
#define LK_SHARERS(x) (LK_HOLDER(x) >> LK_SHARERS_SHIFT)
|
||||
#define LK_SHARERS_LOCK(x) ((x) << LK_SHARERS_SHIFT | LK_SHARE)
|
||||
#define LK_ONE_SHARER (1 << LK_SHARERS_SHIFT)
|
||||
|
|
@ -131,8 +132,10 @@ _lockmgr_args_rw(struct lock *lk, u_int flags, struct rwlock *ilk,
|
|||
LOCK_FILE, LOCK_LINE)
|
||||
#define lockmgr_disown(lk) \
|
||||
_lockmgr_disown((lk), LOCK_FILE, LOCK_LINE)
|
||||
#define lockmgr_recursed_v(v) \
|
||||
(v & LK_WRITER_RECURSED)
|
||||
#define lockmgr_recursed(lk) \
|
||||
((lk)->lk_recurse != 0)
|
||||
lockmgr_recursed_v((lk)->lk_lock)
|
||||
#define lockmgr_rw(lk, flags, ilk) \
|
||||
_lockmgr_args_rw((lk), (flags), (ilk), LK_WMESG_DEFAULT, \
|
||||
LK_PRIO_DEFAULT, LK_TIMO_DEFAULT, LOCK_FILE, LOCK_LINE)
|
||||
|
|
|
|||
Loading…
Reference in a new issue