diff options
author | kib <kib@FreeBSD.org> | 2014-01-09 03:32:03 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2014-01-09 03:32:03 +0000 |
commit | dd0e0d7345725365b13093acb46d43a16ddd2679 (patch) | |
tree | 6c63525f22f17d9943706af339fdc4c9b7fc0eb1 /sys/amd64 | |
parent | a3d28139be193510ec41b229e1c7e1c9b9d206c2 (diff) | |
download | FreeBSD-src-dd0e0d7345725365b13093acb46d43a16ddd2679.zip FreeBSD-src-dd0e0d7345725365b13093acb46d43a16ddd2679.tar.gz |
MFC r260205:
Update the description for pmap_remove_pages() to match the modern
times. Assert that the pmap passed to pmap_remove_pages() is only
active on current CPU.
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/pmap.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 6ff1eae..54b985d 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -5124,12 +5124,20 @@ pmap_page_is_mapped(vm_page_t m) } /* - * Remove all pages from specified address space - * this aids process exit speeds. Also, this code - * is special cased for current process only, but - * can have the more generic (and slightly slower) - * mode enabled. This is much faster than pmap_remove - * in the case of running down an entire address space. + * Destroy all managed, non-wired mappings in the given user-space + * pmap. This pmap cannot be active on any processor besides the + * caller. + * + * This function cannot be applied to the kernel pmap. Moreover, it + * is not intended for general use. It is only to be used during + * process termination. Consequently, it can be implemented in ways + * that make it faster than pmap_remove(). First, it can more quickly + * destroy mappings by iterating over the pmap's collection of PV + * entries, rather than searching the page table. Second, it doesn't + * have to test and clear the page table entries atomically, because + * no processor is currently accessing the user address space. In + * particular, a page table entry's dirty bit won't change state once + * this function starts. */ void pmap_remove_pages(pmap_t pmap) @@ -5149,10 +5157,24 @@ pmap_remove_pages(pmap_t pmap) boolean_t superpage; vm_paddr_t pa; - if (pmap != PCPU_GET(curpmap)) { - printf("warning: pmap_remove_pages called with non-current pmap\n"); - return; + /* + * Assert that the given pmap is only active on the current + * CPU. Unfortunately, we cannot block another CPU from + * activating the pmap while this function is executing. + */ + KASSERT(pmap == PCPU_GET(curpmap), ("non-current pmap %p", pmap)); +#ifdef INVARIANTS + { + cpuset_t other_cpus; + + other_cpus = all_cpus; + critical_enter(); + CPU_CLR(PCPU_GET(cpuid), &other_cpus); + CPU_AND(&other_cpus, &pmap->pm_active); + critical_exit(); + KASSERT(CPU_EMPTY(&other_cpus), ("pmap active %p", pmap)); } +#endif lock = NULL; PG_M = pmap_modified_bit(pmap); |