From owner-svn-src-all@freebsd.org Thu Jan 16 21:45:21 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id A133C1F730C; Thu, 16 Jan 2020 21:45:21 +0000 (UTC) (envelope-from mjg@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47zHmd3lm6z4fKX; Thu, 16 Jan 2020 21:45:21 +0000 (UTC) (envelope-from mjg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 7BDA82633E; Thu, 16 Jan 2020 21:45:21 +0000 (UTC) (envelope-from mjg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 00GLjLwI057375; Thu, 16 Jan 2020 21:45:21 GMT (envelope-from mjg@FreeBSD.org) Received: (from mjg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 00GLjLtN057374; Thu, 16 Jan 2020 21:45:21 GMT (envelope-from mjg@FreeBSD.org) Message-Id: <202001162145.00GLjLtN057374@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mjg set sender to mjg@FreeBSD.org using -f From: Mateusz Guzik Date: Thu, 16 Jan 2020 21:45:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r356812 - head/sys/kern X-SVN-Group: head X-SVN-Commit-Author: mjg X-SVN-Commit-Paths: head/sys/kern X-SVN-Commit-Revision: 356812 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Jan 2020 21:45:21 -0000 Author: mjg Date: Thu Jan 16 21:45:21 2020 New Revision: 356812 URL: https://svnweb.freebsd.org/changeset/base/356812 Log: vfs: increment numvnodes without the vnode list lock unless under pressure The vnode list lock is only needed to reclaim free vnodes or kick the vnlru thread (or to block and not miss a wake up (but note the sleep has a timeout so this would not be a correctness issue)). Try to get away without the lock by just doing an atomic increment. The lock is contended e.g., during poudriere -j 104 where about half of all acquires come from vnode allocation code. Note the entire scheme needs a rewrite, the above just reduces it's SMP impact. Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D23140 Modified: head/sys/kern/vfs_subr.c Modified: head/sys/kern/vfs_subr.c ============================================================================== --- head/sys/kern/vfs_subr.c Thu Jan 16 21:43:13 2020 (r356811) +++ head/sys/kern/vfs_subr.c Thu Jan 16 21:45:21 2020 (r356812) @@ -1497,21 +1497,22 @@ vtryrecycle(struct vnode *vp) * The routine can try to free a vnode or stall for up to 1 second waiting for * vnlru to clear things up, but ultimately always performs a M_WAITOK allocation. */ -static struct vnode * -vn_alloc(struct mount *mp) +static u_long vn_alloc_cyclecount; + +static struct vnode * __noinline +vn_alloc_hard(struct mount *mp) { u_long rnumvnodes, rfreevnodes; - static u_long cyclecount; mtx_lock(&vnode_list_mtx); rnumvnodes = atomic_load_long(&numvnodes); if (rnumvnodes + 1 < desiredvnodes) { - cyclecount = 0; + vn_alloc_cyclecount = 0; goto alloc; } rfreevnodes = atomic_load_long(&freevnodes); - if (cyclecount++ >= rfreevnodes) { - cyclecount = 0; + if (vn_alloc_cyclecount++ >= rfreevnodes) { + vn_alloc_cyclecount = 0; vstir = 1; } /* @@ -1543,6 +1544,22 @@ alloc: if (vnlru_under(rnumvnodes, vlowat)) vnlru_kick(); mtx_unlock(&vnode_list_mtx); + return (uma_zalloc(vnode_zone, M_WAITOK)); +} + +static struct vnode * +vn_alloc(struct mount *mp) +{ + u_long rnumvnodes; + + if (__predict_false(vn_alloc_cyclecount != 0)) + return (vn_alloc_hard(mp)); + rnumvnodes = atomic_fetchadd_long(&numvnodes, 1) + 1; + if (__predict_false(vnlru_under(rnumvnodes, vlowat))) { + atomic_subtract_long(&numvnodes, 1); + return (vn_alloc_hard(mp)); + } + return (uma_zalloc(vnode_zone, M_WAITOK)); }