From owner-svn-src-all@freebsd.org Wed Mar 21 21:15:44 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 98598F67E15; Wed, 21 Mar 2018 21:15:44 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id C75B768AA9; Wed, 21 Mar 2018 21:15:43 +0000 (UTC) (envelope-from markj@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 A4F452FDEA; Wed, 21 Mar 2018 21:15:43 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w2LLFh0d094488; Wed, 21 Mar 2018 21:15:43 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w2LLFhDl094487; Wed, 21 Mar 2018 21:15:43 GMT (envelope-from markj@FreeBSD.org) Message-Id: <201803212115.w2LLFhDl094487@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Wed, 21 Mar 2018 21:15:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r331325 - head/sys/kern X-SVN-Group: head X-SVN-Commit-Author: markj X-SVN-Commit-Paths: head/sys/kern X-SVN-Commit-Revision: 331325 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.25 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: Wed, 21 Mar 2018 21:15:45 -0000 Author: markj Date: Wed Mar 21 21:15:43 2018 New Revision: 331325 URL: https://svnweb.freebsd.org/changeset/base/331325 Log: Elide the object lock in the common case in vfs_vmio_unwire(). The object lock was only needed when attempting to free B_DIRECT buffer pages, and for testing for invalid pages (and freeing them if so). Handle the latter by instead moving invalid pages near the head of the inactive queue, where they will be reclaimed quickly. Reviewed by: alc, kib, jeff MFC after: 3 weeks Differential Revision: https://reviews.freebsd.org/D14778 Modified: head/sys/kern/vfs_bio.c Modified: head/sys/kern/vfs_bio.c ============================================================================== --- head/sys/kern/vfs_bio.c Wed Mar 21 21:13:26 2018 (r331324) +++ head/sys/kern/vfs_bio.c Wed Mar 21 21:15:43 2018 (r331325) @@ -2901,7 +2901,8 @@ vfs_vmio_iodone(struct buf *bp) } /* - * Unwire a page held by a buf and place it on the appropriate vm queue. + * Unwire a page held by a buf and either free it or update the page queues to + * reflect its recent use. */ static void vfs_vmio_unwire(struct buf *bp, vm_page_t m) @@ -2910,24 +2911,26 @@ vfs_vmio_unwire(struct buf *bp, vm_page_t m) vm_page_lock(m); if (vm_page_unwire_noq(m)) { - /* - * Determine if the page should be freed before adding - * it to the inactive queue. - */ - if (m->valid == 0) { - freed = !vm_page_busied(m); - if (freed) - vm_page_free(m); - } else if ((bp->b_flags & B_DIRECT) != 0) + if ((bp->b_flags & B_DIRECT) != 0) freed = vm_page_try_to_free(m); else freed = false; if (!freed) { /* - * If the page is unlikely to be reused, let the - * VM know. Otherwise, maintain LRU. + * Use a racy check of the valid bits to determine + * whether we can accelerate reclamation of the page. + * The valid bits will be stable unless the page is + * being mapped or is referenced by multiple buffers, + * and in those cases we expect races to be rare. At + * worst we will either accelerate reclamation of a + * valid page and violate LRU, or unnecessarily defer + * reclamation of an invalid page. + * + * The B_NOREUSE flag marks data that is not expected to + * be reused, so accelerate reclamation in that case + * too. Otherwise, maintain LRU. */ - if ((bp->b_flags & B_NOREUSE) != 0) + if (m->valid == 0 || (bp->b_flags & B_NOREUSE) != 0) vm_page_deactivate_noreuse(m); else if (m->queue == PQ_ACTIVE) vm_page_reference(m); @@ -3014,7 +3017,11 @@ vfs_vmio_truncate(struct buf *bp, int desiredpages) (desiredpages << PAGE_SHIFT), bp->b_npages - desiredpages); } else BUF_CHECK_UNMAPPED(bp); - obj = bp->b_bufobj->bo_object; + + /* + * The object lock is needed only if we will attempt to free pages. + */ + obj = (bp->b_flags & B_DIRECT) != 0 ? bp->b_bufobj->bo_object : NULL; if (obj != NULL) VM_OBJECT_WLOCK(obj); for (i = desiredpages; i < bp->b_npages; i++) {