When code from r254064 in pmap_ts_referenced() drops pv lock and

blocks on a pmap lock, pmap_release() might proceed in parallel and
destroy the pmap mutex, since unlocked pv lock allows to remove pv
entry owned by the pmap.

For now, gate the pmap_release() on write-locked pvh_global_lock.
Since pmap_ts_release() does not unlock the global lock,
pmap_release() would not destroy pmap mutex until the
pmap_ts_referenced() finished.  We cannot enter pmap_ts_referenced()
and encounter a pv entry for the destroyed pmap if pmap_release()
passed the global lock gate, since pmap_remove_pages() would finish
earlier.

Reported by:	jeff, pho
Reviewed by:	alc
Tested by:	pho
Sponsored by:	The FreeBSD Foundation
This commit is contained in:
kib 2013-08-18 21:36:22 +00:00
parent 7bc0ae6019
commit 17c7e12452

View File

@ -1959,6 +1959,9 @@ pmap_release(pmap_t pmap)
KASSERT(vm_radix_is_empty(&pmap->pm_root),
("pmap_release: pmap has reserved page table page(s)"));
rw_wlock(&pvh_global_lock);
rw_wunlock(&pvh_global_lock);
m = PHYS_TO_VM_PAGE(pmap->pm_pml4[PML4PML4I] & PG_FRAME);
for (i = 0; i < NKPML4E; i++) /* KVA */