Author: mav
Date: Mon Jun 23 13:14:26 2014
New Revision: 267789
URL: http://svnweb.freebsd.org/changeset/base/267789

Log:
  MFC r267232, r267239:
  Use atomics to modify numvnodes variable.
  
  This allows to mostly avoid lock usage in getnewvnode_[drop_]reserve(),
  that reduces number of global vnode_free_list_mtx mutex acquisitions
  from 4 to 2 per NFS request on ZFS, improving SMP scalability.

Modified:
  stable/9/sys/kern/vfs_subr.c
Directory Properties:
  stable/9/   (props changed)
  stable/9/sys/   (props changed)

Modified: stable/9/sys/kern/vfs_subr.c
==============================================================================
--- stable/9/sys/kern/vfs_subr.c        Mon Jun 23 13:11:47 2014        
(r267788)
+++ stable/9/sys/kern/vfs_subr.c        Mon Jun 23 13:14:26 2014        
(r267789)
@@ -975,12 +975,19 @@ getnewvnode_reserve(u_int count)
        struct thread *td;
 
        td = curthread;
+       /* First try to be quick and racy. */
+       if (atomic_fetchadd_long(&numvnodes, count) + count <= desiredvnodes) {
+               td->td_vp_reserv += count;
+               return;
+       } else
+               atomic_subtract_long(&numvnodes, count);
+
        mtx_lock(&vnode_free_list_mtx);
        while (count > 0) {
                if (getnewvnode_wait(0) == 0) {
                        count--;
                        td->td_vp_reserv++;
-                       numvnodes++;
+                       atomic_add_long(&numvnodes, 1);
                }
        }
        mtx_unlock(&vnode_free_list_mtx);
@@ -992,10 +999,7 @@ getnewvnode_drop_reserve(void)
        struct thread *td;
 
        td = curthread;
-       mtx_lock(&vnode_free_list_mtx);
-       KASSERT(numvnodes >= td->td_vp_reserv, ("reserve too large"));
-       numvnodes -= td->td_vp_reserv;
-       mtx_unlock(&vnode_free_list_mtx);
+       atomic_subtract_long(&numvnodes, td->td_vp_reserv);
        td->td_vp_reserv = 0;
 }
 
@@ -1032,7 +1036,7 @@ getnewvnode(const char *tag, struct moun
                return (error);
        }
 #endif
-       numvnodes++;
+       atomic_add_long(&numvnodes, 1);
        mtx_unlock(&vnode_free_list_mtx);
 alloc:
        vp = (struct vnode *) uma_zalloc(vnode_zone, M_WAITOK|M_ZERO);
@@ -2508,9 +2512,7 @@ vdropl(struct vnode *vp)
         * The vnode has been marked for destruction, so free it.
         */
        CTR2(KTR_VFS, "%s: destroying the vnode %p", __func__, vp);
-       mtx_lock(&vnode_free_list_mtx);
-       numvnodes--;
-       mtx_unlock(&vnode_free_list_mtx);
+       atomic_subtract_long(&numvnodes, 1);
        bo = &vp->v_bufobj;
        VNASSERT((vp->v_iflag & VI_FREE) == 0, vp,
            ("cleaned vnode still on the free list."));
_______________________________________________
svn-src-stable-9@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "svn-src-stable-9-unsubscr...@freebsd.org"

Reply via email to