From owner-svn-src-head@FreeBSD.ORG Sun Jun 8 15:38:40 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id D17C834F; Sun, 8 Jun 2014 15:38:40 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A512C2FD6; Sun, 8 Jun 2014 15:38:40 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s58Fceik039085; Sun, 8 Jun 2014 15:38:40 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s58FceEv039084; Sun, 8 Jun 2014 15:38:40 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201406081538.s58FceEv039084@svn.freebsd.org> From: Alexander Motin Date: Sun, 8 Jun 2014 15:38:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r267232 - head/sys/kern X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 08 Jun 2014 15:38:40 -0000 Author: mav Date: Sun Jun 8 15:38:40 2014 New Revision: 267232 URL: http://svnweb.freebsd.org/changeset/base/267232 Log: 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. Reviewed by: kib MFC after: 2 weeks Sponsored by: iXsystems, Inc. Modified: head/sys/kern/vfs_subr.c Modified: head/sys/kern/vfs_subr.c ============================================================================== --- head/sys/kern/vfs_subr.c Sun Jun 8 14:02:25 2014 (r267231) +++ head/sys/kern/vfs_subr.c Sun Jun 8 15:38:40 2014 (r267232) @@ -995,14 +995,25 @@ void getnewvnode_reserve(u_int count) { struct thread *td; + long num; td = curthread; + /* First try to be quick and racy. */ + if (numvnodes + count <= desiredvnodes) { + num = atomic_fetchadd_long(&numvnodes, count); + if (num + 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); @@ -1014,10 +1025,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; } @@ -1054,7 +1062,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); @@ -2385,9 +2393,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."));