From owner-svn-src-head@freebsd.org Sat Jul 15 01:49:56 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 34D10DB2280; Sat, 15 Jul 2017 01:49:56 +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 0E75982AB8; Sat, 15 Jul 2017 01:49:55 +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 v6F1ntFm094116; Sat, 15 Jul 2017 01:49:55 GMT (envelope-from alc@FreeBSD.org) Received: (from alc@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v6F1ntjD094115; Sat, 15 Jul 2017 01:49:55 GMT (envelope-from alc@FreeBSD.org) Message-Id: <201707150149.v6F1ntjD094115@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: alc set sender to alc@FreeBSD.org using -f From: Alan Cox Date: Sat, 15 Jul 2017 01:49:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r321003 - head/sys/amd64/amd64 X-SVN-Group: head X-SVN-Commit-Author: alc X-SVN-Commit-Paths: head/sys/amd64/amd64 X-SVN-Commit-Revision: 321003 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: Sat, 15 Jul 2017 01:49:56 -0000 Author: alc Date: Sat Jul 15 01:49:54 2017 New Revision: 321003 URL: https://svnweb.freebsd.org/changeset/base/321003 Log: Extract the innermost loop of pmap_remove() out into its own function, pmap_remove_ptes(). (This new function will also be used by an upcoming change to pmap_enter() that adds support for psind == 1 mappings.) Submitted by: Yufeng Zhou (an earlier version) Reviewed by: kib, markj MFC after: 1 week Modified: head/sys/amd64/amd64/pmap.c Modified: head/sys/amd64/amd64/pmap.c ============================================================================== --- head/sys/amd64/amd64/pmap.c Sat Jul 15 00:45:22 2017 (r321002) +++ head/sys/amd64/amd64/pmap.c Sat Jul 15 01:49:54 2017 (r321003) @@ -629,6 +629,9 @@ static int pmap_remove_pte(pmap_t pmap, pt_entry_t *pt static vm_page_t pmap_remove_pt_page(pmap_t pmap, vm_offset_t va); static void pmap_remove_page(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, struct spglist *free); +static bool pmap_remove_ptes(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, + pd_entry_t *pde, struct spglist *free, + struct rwlock **lockp); static boolean_t pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va, vm_page_t m, struct rwlock **lockp); static void pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, @@ -3736,6 +3739,44 @@ pmap_remove_page(pmap_t pmap, vm_offset_t va, pd_entry } /* + * Removes the specified range of addresses from the page table page. + */ +static bool +pmap_remove_ptes(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, + pd_entry_t *pde, struct spglist *free, struct rwlock **lockp) +{ + pt_entry_t PG_G, *pte; + vm_offset_t va; + bool anyvalid; + + PMAP_LOCK_ASSERT(pmap, MA_OWNED); + PG_G = pmap_global_bit(pmap); + anyvalid = false; + va = eva; + for (pte = pmap_pde_to_pte(pde, sva); sva != eva; pte++, + sva += PAGE_SIZE) { + if (*pte == 0) { + if (va != eva) { + pmap_invalidate_range(pmap, va, sva); + va = eva; + } + continue; + } + if ((*pte & PG_G) == 0) + anyvalid = true; + else if (va == eva) + va = sva; + if (pmap_remove_pte(pmap, pte, sva, *pde, free, lockp)) { + sva += PAGE_SIZE; + break; + } + } + if (va != eva) + pmap_invalidate_range(pmap, va, sva); + return (anyvalid); +} + +/* * Remove the given range of addresses from the specified map. * * It is assumed that the start and end are properly @@ -3745,11 +3786,11 @@ void pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) { struct rwlock *lock; - vm_offset_t va, va_next; + vm_offset_t va_next; pml4_entry_t *pml4e; pdp_entry_t *pdpe; pd_entry_t ptpaddr, *pde; - pt_entry_t *pte, PG_G, PG_V; + pt_entry_t PG_G, PG_V; struct spglist free; int anyvalid; @@ -3852,28 +3893,8 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t if (va_next > eva) va_next = eva; - va = va_next; - for (pte = pmap_pde_to_pte(pde, sva); sva != va_next; pte++, - sva += PAGE_SIZE) { - if (*pte == 0) { - if (va != va_next) { - pmap_invalidate_range(pmap, va, sva); - va = va_next; - } - continue; - } - if ((*pte & PG_G) == 0) - anyvalid = 1; - else if (va == va_next) - va = sva; - if (pmap_remove_pte(pmap, pte, sva, ptpaddr, &free, - &lock)) { - sva += PAGE_SIZE; - break; - } - } - if (va != va_next) - pmap_invalidate_range(pmap, va, sva); + if (pmap_remove_ptes(pmap, sva, va_next, pde, &free, &lock)) + anyvalid = 1; } if (lock != NULL) rw_wunlock(lock);