Date: Wed, 21 Mar 2018 21:15:43 +0000 (UTC) From: Mark Johnston <markj@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r331325 - head/sys/kern Message-ID: <201803212115.w2LLFhDl094487@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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++) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201803212115.w2LLFhDl094487>