diff options
author | kib <kib@FreeBSD.org> | 2014-11-16 23:02:32 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2014-11-16 23:02:32 +0000 |
commit | e01547e9e70b57b8238e62634e4bd6c88ed32cc0 (patch) | |
tree | dc5cde361b78c3c877b05e1653ac200915de5866 /sys/kern/kern_lock.c | |
parent | 7fb42ed981537c54e039f09af4b1cc969a4219ba (diff) | |
download | FreeBSD-src-e01547e9e70b57b8238e62634e4bd6c88ed32cc0.zip FreeBSD-src-e01547e9e70b57b8238e62634e4bd6c88ed32cc0.tar.gz |
MFC r273966:
Fix two issues with lockmgr(9) LK_CAN_SHARE() test, related
to the exclusive locker starvation.
MFC r273986:
Fix the build with ADAPTIVE_LOCKMGRS kernel option.
Diffstat (limited to 'sys/kern/kern_lock.c')
-rw-r--r-- | sys/kern/kern_lock.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index 8fa3fba..f221569 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -116,10 +116,11 @@ CTASSERT(LK_UNLOCKED == (LK_UNLOCKED & } \ } while (0) -#define LK_CAN_SHARE(x) \ - (((x) & LK_SHARE) && (((x) & LK_EXCLUSIVE_WAITERS) == 0 || \ - ((x) & LK_EXCLUSIVE_SPINNERS) == 0 || \ - curthread->td_lk_slocks || (curthread->td_pflags & TDP_DEADLKTREAT))) +#define LK_CAN_SHARE(x, flags) \ + (((x) & LK_SHARE) && \ + (((x) & (LK_EXCLUSIVE_WAITERS | LK_EXCLUSIVE_SPINNERS)) == 0 || \ + (curthread->td_lk_slocks != 0 && !(flags & LK_NODDLKTREAT)) || \ + (curthread->td_pflags & TDP_DEADLKTREAT))) #define LK_TRYOP(x) \ ((x) & LK_NOWAIT) @@ -531,7 +532,7 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, * waiters, if we fail to acquire the shared lock * loop back and retry. */ - if (LK_CAN_SHARE(x)) { + if (LK_CAN_SHARE(x, flags)) { if (atomic_cmpset_acq_ptr(&lk->lk_lock, x, x + LK_ONE_SHARER)) break; @@ -615,7 +616,7 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, __func__, lk, spintries, i); x = lk->lk_lock; if ((x & LK_SHARE) == 0 || - LK_CAN_SHARE(x) != 0) + LK_CAN_SHARE(x, flags) != 0) break; cpu_spinwait(); } @@ -636,7 +637,7 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, * if the lock can be acquired in shared mode, try * again. */ - if (LK_CAN_SHARE(x)) { + if (LK_CAN_SHARE(x, flags)) { sleepq_release(&lk->lock_object); continue; } |