svn commit: r321003 - head/sys/amd64/amd64
Alan Cox
alc at FreeBSD.org
Sat Jul 15 01:49:56 UTC 2017
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 <yz70 at rice.edu> (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);
More information about the svn-src-all
mailing list