Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 5 Jan 2020 01:00:11 +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: r356364 - head/sys/kern
Message-ID:  <202001050100.00510B4i031470@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mjg
Date: Sun Jan  5 01:00:11 2020
New Revision: 356364
URL: https://svnweb.freebsd.org/changeset/base/356364

Log:
  vfs: factor out avoidable branches in _vn_lock

Modified:
  head/sys/kern/vfs_vnops.c

Modified: head/sys/kern/vfs_vnops.c
==============================================================================
--- head/sys/kern/vfs_vnops.c	Sun Jan  5 00:59:47 2020	(r356363)
+++ head/sys/kern/vfs_vnops.c	Sun Jan  5 01:00:11 2020	(r356364)
@@ -1564,28 +1564,53 @@ vn_poll(struct file *fp, int events, struct ucred *act
  * Acquire the requested lock and then check for validity.  LK_RETRY
  * permits vn_lock to return doomed vnodes.
  */
-int
-_vn_lock(struct vnode *vp, int flags, char *file, int line)
+static int __noinline
+_vn_lock_fallback(struct vnode *vp, int flags, char *file, int line, int error)
 {
-	int error;
 
-	VNASSERT((flags & LK_TYPE_MASK) != 0, vp,
-	    ("vn_lock: no locktype"));
-	VNASSERT(vp->v_holdcnt != 0, vp, ("vn_lock: zero hold count"));
-retry:
-	error = VOP_LOCK1(vp, flags, file, line);
-	flags &= ~LK_INTERLOCK;	/* Interlock is always dropped. */
 	KASSERT((flags & LK_RETRY) == 0 || error == 0,
 	    ("vn_lock: error %d incompatible with flags %#x", error, flags));
 
+	if (error == 0)
+		VNASSERT(VN_IS_DOOMED(vp), vp, ("vnode not doomed"));
+
 	if ((flags & LK_RETRY) == 0) {
-		if (error == 0 && VN_IS_DOOMED(vp)) {
+		if (error == 0) {
 			VOP_UNLOCK(vp);
 			error = ENOENT;
 		}
-	} else if (error != 0)
-		goto retry;
-	return (error);
+		return (error);
+	}
+
+	/*
+	 * LK_RETRY case.
+	 *
+	 * Nothing to do if we got the lock.
+	 */
+	if (error == 0)
+		return (0);
+
+	/*
+	 * Interlock was dropped by the call in _vn_lock.
+	 */
+	flags &= ~LK_INTERLOCK;
+	do {
+		error = VOP_LOCK1(vp, flags, file, line);
+	} while (error != 0);
+	return (0);
+}
+
+int
+_vn_lock(struct vnode *vp, int flags, char *file, int line)
+{
+	int error;
+
+	VNASSERT((flags & LK_TYPE_MASK) != 0, vp, ("vn_lock: no locktype"));
+	VNASSERT(vp->v_holdcnt != 0, vp, ("vn_lock: zero hold count"));
+	error = VOP_LOCK1(vp, flags, file, line);
+	if (__predict_false(error != 0 || VN_IS_DOOMED(vp)))
+		return (_vn_lock_fallback(vp, flags, file, line, error));
+	return (0);
 }
 
 /*



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