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);
 }
 
 /*
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to