diff options
author | alc <alc@FreeBSD.org> | 2012-07-06 06:42:25 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2012-07-06 06:42:25 +0000 |
commit | 6c7a2e716bd587719d2eb31cced13af496bed18e (patch) | |
tree | f1f9a49ee0ba3d465627230404fb647c6583b073 | |
parent | b8a35c814a4b1f5c1d8d3a88682a86b8c372506d (diff) | |
download | FreeBSD-src-6c7a2e716bd587719d2eb31cced13af496bed18e.zip FreeBSD-src-6c7a2e716bd587719d2eb31cced13af496bed18e.tar.gz |
Make pmap_enter()'s management of PV entries consistent with the other pmap
functions that manage PV entries. Specifically, remove the PV entry from
the containing PV list only after the corresponding PTE is destroyed.
Update the pmap's wired mapping count in pmap_enter() before the PV list
lock is acquired.
-rw-r--r-- | sys/amd64/amd64/pmap.c | 35 |
1 files changed, 15 insertions, 20 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index d36d87f..9e1ae3d 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -3517,8 +3517,6 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m, goto validate; } - pv = NULL; - /* * Mapping has changed, invalidate old range and fall through to * handle validating new mapping. @@ -3526,11 +3524,8 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m, if (opa) { if (origpte & PG_W) pmap->pm_stats.wired_count--; - if (origpte & PG_MANAGED) { + if ((origpte & PG_MANAGED) != 0) om = PHYS_TO_VM_PAGE(opa); - CHANGE_PV_LIST_LOCK_TO_VM_PAGE(&lock, om); - pv = pmap_pvh_remove(&om->md, pmap, va); - } if (mpte != NULL) { mpte->wire_count--; KASSERT(mpte->wire_count > 0, @@ -3541,22 +3536,20 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m, pmap_resident_count_inc(pmap, 1); /* + * Increment the counters. + */ + if (wired) + pmap->pm_stats.wired_count++; + + /* * Enter on the PV list if part of our managed memory. */ if ((newpte & PG_MANAGED) != 0) { - if (pv == NULL) - pv = get_pv_entry(pmap, &lock); - CHANGE_PV_LIST_LOCK_TO_VM_PAGE(&lock, m); + pv = get_pv_entry(pmap, &lock); pv->pv_va = va; + CHANGE_PV_LIST_LOCK_TO_PHYS(&lock, pa); TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list); - } else if (pv != NULL) - free_pv_entry(pmap, pv); - - /* - * Increment counters - */ - if (wired) - pmap->pm_stats.wired_count++; + } validate: @@ -3586,9 +3579,11 @@ validate: if ((newpte & PG_RW) == 0) invlva = TRUE; } - if ((om->aflags & PGA_WRITEABLE) != 0) { - CHANGE_PV_LIST_LOCK_TO_VM_PAGE(&lock, om); - if (TAILQ_EMPTY(&om->md.pv_list) && + if (opa != pa && (origpte & PG_MANAGED) != 0) { + CHANGE_PV_LIST_LOCK_TO_PHYS(&lock, opa); + pmap_pvh_free(&om->md, pmap, va); + if ((om->aflags & PGA_WRITEABLE) != 0 && + TAILQ_EMPTY(&om->md.pv_list) && ((om->flags & PG_FICTITIOUS) != 0 || TAILQ_EMPTY(&pa_to_pvh(opa)->pv_list))) vm_page_aflag_clear(om, PGA_WRITEABLE); |