summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2013-09-29 18:02:23 +0000
committerkib <kib@FreeBSD.org>2013-09-29 18:02:23 +0000
commit632f1d29f39402167db9069d25e9bdc974b29c88 (patch)
treee521a2a30027732330389023ab5d36a15df225fc
parentf093c579801a670d1ae7a75f29919c66b2adae40 (diff)
downloadFreeBSD-src-632f1d29f39402167db9069d25e9bdc974b29c88.zip
FreeBSD-src-632f1d29f39402167db9069d25e9bdc974b29c88.tar.gz
Add LK_TRYUPGRADE operation for lockmgr(9), which attempts to
atomically upgrade shared lock to exclusive. On failure, error is returned and lock is not dropped in the process. Tested by: pho (previous version) No objections from: attilio Sponsored by: The FreeBSD Foundation MFC after: 1 week Approved by: re (glebius)
-rw-r--r--sys/kern/kern_lock.c13
-rw-r--r--sys/sys/lockmgr.h1
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)
OpenPOWER on IntegriCloud