From owner-svn-src-all@freebsd.org Sat Oct 7 18:08:38 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id DDF5FE3E1B2; Sat, 7 Oct 2017 18:08:38 +0000 (UTC) (envelope-from alc@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 mx1.freebsd.org (Postfix) with ESMTPS id 8D830720A5; Sat, 7 Oct 2017 18:08:38 +0000 (UTC) (envelope-from alc@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v97I8bXJ007617; Sat, 7 Oct 2017 18:08:37 GMT (envelope-from alc@FreeBSD.org) Received: (from alc@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v97I8bDu007614; Sat, 7 Oct 2017 18:08:37 GMT (envelope-from alc@FreeBSD.org) Message-Id: <201710071808.v97I8bDu007614@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: alc set sender to alc@FreeBSD.org using -f From: Alan Cox Date: Sat, 7 Oct 2017 18:08:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r324389 - stable/11/sys/vm X-SVN-Group: stable-11 X-SVN-Commit-Author: alc X-SVN-Commit-Paths: stable/11/sys/vm X-SVN-Commit-Revision: 324389 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.23 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: Sat, 07 Oct 2017 18:08:39 -0000 Author: alc Date: Sat Oct 7 18:08:37 2017 New Revision: 324389 URL: https://svnweb.freebsd.org/changeset/base/324389 Log: MFC r320980,321377 Generalize vm_page_ps_is_valid() to support testing other predicates on the (super)page, renaming the function to vm_page_ps_test(). In vm_page_ps_test(), always check that the base pages within the specified superpage all belong to the same object. To date, that check has not been needed, but upcoming changes require it. Modified: stable/11/sys/vm/vm_map.c stable/11/sys/vm/vm_page.c stable/11/sys/vm/vm_page.h Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/vm/vm_map.c ============================================================================== --- stable/11/sys/vm/vm_map.c Sat Oct 7 17:40:31 2017 (r324388) +++ stable/11/sys/vm/vm_map.c Sat Oct 7 18:08:37 2017 (r324389) @@ -1962,7 +1962,7 @@ vm_map_pmap_enter(vm_map_t map, vm_offset_t addr, vm_p (pagesizes[p->psind] - 1)) == 0) { mask = atop(pagesizes[p->psind]) - 1; if (tmpidx + mask < psize && - vm_page_ps_is_valid(p)) { + vm_page_ps_test(p, PS_ALL_VALID, NULL)) { p += mask; threshold += mask; } Modified: stable/11/sys/vm/vm_page.c ============================================================================== --- stable/11/sys/vm/vm_page.c Sat Oct 7 17:40:31 2017 (r324388) +++ stable/11/sys/vm/vm_page.c Sat Oct 7 18:08:37 2017 (r324389) @@ -3612,16 +3612,17 @@ vm_page_is_valid(vm_page_t m, int base, int size) } /* - * vm_page_ps_is_valid: - * - * Returns TRUE if the entire (super)page is valid and FALSE otherwise. + * Returns true if all of the specified predicates are true for the entire + * (super)page and false otherwise. */ -boolean_t -vm_page_ps_is_valid(vm_page_t m) +bool +vm_page_ps_test(vm_page_t m, int flags, vm_page_t skip_m) { + vm_object_t object; int i, npages; - VM_OBJECT_ASSERT_LOCKED(m->object); + object = m->object; + VM_OBJECT_ASSERT_LOCKED(object); npages = atop(pagesizes[m->psind]); /* @@ -3630,10 +3631,28 @@ vm_page_ps_is_valid(vm_page_t m) * occupy adjacent entries in vm_page_array[]. */ for (i = 0; i < npages; i++) { - if (m[i].valid != VM_PAGE_BITS_ALL) - return (FALSE); + /* Always test object consistency, including "skip_m". */ + if (m[i].object != object) + return (false); + if (&m[i] == skip_m) + continue; + if ((flags & PS_NONE_BUSY) != 0 && vm_page_busied(&m[i])) + return (false); + if ((flags & PS_ALL_DIRTY) != 0) { + /* + * Calling vm_page_test_dirty() or pmap_is_modified() + * might stop this case from spuriously returning + * "false". However, that would require a write lock + * on the object containing "m[i]". + */ + if (m[i].dirty != VM_PAGE_BITS_ALL) + return (false); + } + if ((flags & PS_ALL_VALID) != 0 && + m[i].valid != VM_PAGE_BITS_ALL) + return (false); } - return (TRUE); + return (true); } /* Modified: stable/11/sys/vm/vm_page.h ============================================================================== --- stable/11/sys/vm/vm_page.h Sat Oct 7 17:40:31 2017 (r324388) +++ stable/11/sys/vm/vm_page.h Sat Oct 7 18:08:37 2017 (r324389) @@ -440,6 +440,18 @@ malloc2vm_flags(int malloc_flags) } #endif +/* + * Predicates supported by vm_page_ps_test(): + * + * PS_ALL_DIRTY is true only if the entire (super)page is dirty. + * However, it can be spuriously false when the (super)page has become + * dirty in the pmap but that information has not been propagated to the + * machine-independent layer. + */ +#define PS_ALL_DIRTY 0x1 +#define PS_ALL_VALID 0x2 +#define PS_NONE_BUSY 0x4 + void vm_page_busy_downgrade(vm_page_t m); void vm_page_busy_sleep(vm_page_t m, const char *msg, bool nonshared); void vm_page_flash(vm_page_t m); @@ -475,7 +487,7 @@ vm_page_t vm_page_next(vm_page_t m); int vm_page_pa_tryrelock(pmap_t, vm_paddr_t, vm_paddr_t *); struct vm_pagequeue *vm_page_pagequeue(vm_page_t m); vm_page_t vm_page_prev(vm_page_t m); -boolean_t vm_page_ps_is_valid(vm_page_t m); +bool vm_page_ps_test(vm_page_t m, int flags, vm_page_t skip_m); void vm_page_putfake(vm_page_t m); void vm_page_readahead_finish(vm_page_t m); bool vm_page_reclaim_contig(int req, u_long npages, vm_paddr_t low,