svn commit: r255940 - in head/sys: kern sys

Konstantin Belousov kib at FreeBSD.org
Sun Sep 29 18:02:24 UTC 2013


Author: kib
Date: Sun Sep 29 18:02:23 2013
New Revision: 255940
URL: http://svnweb.freebsd.org/changeset/base/255940

Log:
  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)

Modified:
  head/sys/kern/kern_lock.c
  head/sys/sys/lockmgr.h

Modified: head/sys/kern/kern_lock.c
==============================================================================
--- head/sys/kern/kern_lock.c	Sun Sep 29 15:19:34 2013	(r255939)
+++ head/sys/kern/kern_lock.c	Sun Sep 29 18:02:23 2013	(r255940)
@@ -497,6 +497,7 @@ __lockmgr_args(struct lock *lk, u_int fl
 			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 fl
 		}
 		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 fl
 		}
 
 		/*
+		 * 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.
 		 */

Modified: head/sys/sys/lockmgr.h
==============================================================================
--- head/sys/sys/lockmgr.h	Sun Sep 29 15:19:34 2013	(r255939)
+++ head/sys/sys/lockmgr.h	Sun Sep 29 18:02:23 2013	(r255940)
@@ -169,6 +169,7 @@ _lockmgr_args_rw(struct lock *lk, u_int 
 #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)
 


More information about the svn-src-all mailing list