diff options
-rw-r--r-- | sys/kern/kern_lock.c | 13 | ||||
-rw-r--r-- | sys/sys/lockmgr.h | 1 |
2 files changed, 14 insertions, 0 deletions
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index 74a5b19..8ca8acd 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -497,6 +497,7 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, op = LK_EXCLUSIVE; break; case LK_UPGRADE: + case LK_TRYUPGRADE: case LK_DOWNGRADE: _lockmgr_assert(lk, KA_XLOCKED | KA_NOTRECURSED, file, line); @@ -694,6 +695,7 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, } break; case LK_UPGRADE: + case LK_TRYUPGRADE: _lockmgr_assert(lk, KA_SLOCKED, file, line); v = lk->lk_lock; x = v & LK_ALL_WAITERS; @@ -714,6 +716,17 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk, } /* + * In LK_TRYUPGRADE mode, do not drop the lock, + * returning EBUSY instead. + */ + if (op == LK_TRYUPGRADE) { + LOCK_LOG2(lk, "%s: %p failed the nowait upgrade", + __func__, lk); + error = EBUSY; + break; + } + + /* * We have been unable to succeed in upgrading, so just * give up the shared lock. */ diff --git a/sys/sys/lockmgr.h b/sys/sys/lockmgr.h index f525a06..059de81 100644 --- a/sys/sys/lockmgr.h +++ b/sys/sys/lockmgr.h @@ -169,6 +169,7 @@ _lockmgr_args_rw(struct lock *lk, u_int flags, struct rwlock *ilk, #define LK_RELEASE 0x100000 #define LK_SHARED 0x200000 #define LK_UPGRADE 0x400000 +#define LK_TRYUPGRADE 0x800000 #define LK_TOTAL_MASK (LK_INIT_MASK | LK_EATTR_MASK | LK_TYPE_MASK) |