From owner-svn-src-head@freebsd.org Fri Jul 14 02:15:49 2017 Return-Path: Delivered-To: svn-src-head@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 CA405DB2F7C; Fri, 14 Jul 2017 02:15:49 +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 948ED71663; Fri, 14 Jul 2017 02:15:49 +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 v6E2FmVq005608; Fri, 14 Jul 2017 02:15:48 GMT (envelope-from alc@FreeBSD.org) Received: (from alc@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v6E2Fmwr005605; Fri, 14 Jul 2017 02:15:48 GMT (envelope-from alc@FreeBSD.org) Message-Id: <201707140215.v6E2Fmwr005605@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: alc set sender to alc@FreeBSD.org using -f From: Alan Cox Date: Fri, 14 Jul 2017 02:15:48 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r320980 - head/sys/vm X-SVN-Group: head X-SVN-Commit-Author: alc X-SVN-Commit-Paths: head/sys/vm X-SVN-Commit-Revision: 320980 X-SVN-Commit-Repository: base 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.23 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: Fri, 14 Jul 2017 02:15:49 -0000 Author: alc Date: Fri Jul 14 02:15:48 2017 New Revision: 320980 URL: https://svnweb.freebsd.org/changeset/base/320980 Log: Generalize vm_page_ps_is_valid() to support testing other predicates on the (super)page, renaming the function to vm_page_ps_test(). Reviewed by: kib, markj MFC after: 1 week Modified: head/sys/vm/vm_map.c head/sys/vm/vm_page.c head/sys/vm/vm_page.h Modified: head/sys/vm/vm_map.c ============================================================================== --- head/sys/vm/vm_map.c Fri Jul 14 01:45:43 2017 (r320979) +++ head/sys/vm/vm_map.c Fri Jul 14 02:15:48 2017 (r320980) @@ -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: head/sys/vm/vm_page.c ============================================================================== --- head/sys/vm/vm_page.c Fri Jul 14 01:45:43 2017 (r320979) +++ head/sys/vm/vm_page.c Fri Jul 14 02:15:48 2017 (r320980) @@ -3472,12 +3472,11 @@ 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) { int i, npages; @@ -3490,10 +3489,25 @@ 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); + 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: head/sys/vm/vm_page.h ============================================================================== --- head/sys/vm/vm_page.h Fri Jul 14 01:45:43 2017 (r320979) +++ head/sys/vm/vm_page.h Fri Jul 14 02:15:48 2017 (r320980) @@ -438,6 +438,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); @@ -469,7 +481,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,