Date: Mon, 23 Jun 2014 13:14:27 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r267789 - stable/9/sys/kern Message-ID: <201406231314.s5NDERcT027388@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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."));
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201406231314.s5NDERcT027388>