Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 13 Jul 2018 22:40:14 +0000 (UTC)
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r336267 - head/sys/kern
Message-ID:  <201807132240.w6DMeEA7073097@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mjg
Date: Fri Jul 13 22:40:14 2018
New Revision: 336267
URL: https://svnweb.freebsd.org/changeset/base/336267

Log:
  lockmgr: tidy up slock/sunlock similar to other locks

Modified:
  head/sys/kern/kern_lock.c

Modified: head/sys/kern/kern_lock.c
==============================================================================
--- head/sys/kern/kern_lock.c	Fri Jul 13 21:30:18 2018	(r336266)
+++ head/sys/kern/kern_lock.c	Fri Jul 13 22:40:14 2018	(r336267)
@@ -112,11 +112,21 @@ CTASSERT(LK_UNLOCKED == (LK_UNLOCKED &
 	}								\
 } while (0)
 
-#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)))
+static bool __always_inline
+LK_CAN_SHARE(uintptr_t x, int flags, bool fp)
+{
+
+	if ((x & (LK_SHARE | LK_EXCLUSIVE_WAITERS | LK_EXCLUSIVE_SPINNERS)) ==
+	    LK_SHARE)
+		return (true);
+	if (fp || (!(x & LK_SHARE)))
+		return (false);
+	if ((curthread->td_lk_slocks != 0 && !(flags & LK_NODDLKTREAT)) ||
+	    (curthread->td_pflags & TDP_DEADLKTREAT))
+		return (true);
+	return (false);
+}
+
 #define	LK_TRYOP(x)							\
 	((x) & LK_NOWAIT)
 
@@ -169,7 +179,7 @@ struct lockmgr_wait {
 };
 
 static bool __always_inline lockmgr_slock_try(struct lock *lk, uintptr_t *xp,
-    int flags);
+    int flags, bool fp);
 static bool __always_inline lockmgr_sunlock_try(struct lock *lk, uintptr_t *xp);
 
 static void
@@ -498,7 +508,7 @@ lockdestroy(struct lock *lk)
 }
 
 static bool __always_inline
-lockmgr_slock_try(struct lock *lk, uintptr_t *xp, int flags)
+lockmgr_slock_try(struct lock *lk, uintptr_t *xp, int flags, bool fp)
 {
 
 	/*
@@ -509,7 +519,7 @@ lockmgr_slock_try(struct lock *lk, uintptr_t *xp, int 
 	 * loop back and retry.
 	 */
 	*xp = lk->lk_lock;
-	while (LK_CAN_SHARE(*xp, flags)) {
+	while (LK_CAN_SHARE(*xp, flags, fp)) {
 		if (atomic_fcmpset_acq_ptr(&lk->lk_lock, xp,
 		    *xp + LK_ONE_SHARER)) {
 			return (true);
@@ -523,29 +533,12 @@ lockmgr_sunlock_try(struct lock *lk, uintptr_t *xp)
 {
 
 	for (;;) {
-		/*
-		 * If there is more than one shared lock held, just drop one
-		 * and return.
-		 */
-		if (LK_SHARERS(*xp) > 1) {
+		if (LK_SHARERS(*xp) > 1 || !(*xp & LK_ALL_WAITERS)) {
 			if (atomic_fcmpset_rel_ptr(&lk->lk_lock, xp,
 			    *xp - LK_ONE_SHARER))
 				return (true);
 			continue;
 		}
-
-		/*
-		 * If there are not waiters on the exclusive queue, drop the
-		 * lock quickly.
-		 */
-		if ((*xp & LK_ALL_WAITERS) == 0) {
-			MPASS((*xp & ~LK_EXCLUSIVE_SPINNERS) ==
-			    LK_SHARERS_LOCK(1));
-			if (atomic_fcmpset_rel_ptr(&lk->lk_lock, xp,
-			    LK_UNLOCKED))
-				return (true);
-			continue;
-		}
 		break;
 	}
 	return (false);
@@ -574,7 +567,7 @@ lockmgr_slock_hard(struct lock *lk, u_int flags, struc
 		WITNESS_CHECKORDER(&lk->lock_object, LOP_NEWORDER,
 		    file, line, flags & LK_INTERLOCK ? ilk : NULL);
 	for (;;) {
-		if (lockmgr_slock_try(lk, &x, flags))
+		if (lockmgr_slock_try(lk, &x, flags, false))
 			break;
 #ifdef HWPMC_HOOKS
 		PMC_SOFT_CALL( , , lock, failed);
@@ -617,7 +610,7 @@ retry_sleepq:
 		 * if the lock can be acquired in shared mode, try
 		 * again.
 		 */
-		if (LK_CAN_SHARE(x, flags)) {
+		if (LK_CAN_SHARE(x, flags, false)) {
 			sleepq_release(&lk->lock_object);
 			continue;
 		}
@@ -932,7 +925,7 @@ lockmgr_lock_fast_path(struct lock *lk, u_int flags, s
 			    file, line, flags & LK_INTERLOCK ? ilk : NULL);
 		if (__predict_false(lk->lock_object.lo_flags & LK_NOSHARE))
 			break;
-		if (lockmgr_slock_try(lk, &x, flags)) {
+		if (lockmgr_slock_try(lk, &x, flags, true)) {
 			lockmgr_note_shared_acquire(lk, 0, 0,
 			    file, line, flags);
 			locked = true;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807132240.w6DMeEA7073097>