summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2014-01-09 03:32:03 +0000
committerkib <kib@FreeBSD.org>2014-01-09 03:32:03 +0000
commitdd0e0d7345725365b13093acb46d43a16ddd2679 (patch)
tree6c63525f22f17d9943706af339fdc4c9b7fc0eb1
parenta3d28139be193510ec41b229e1c7e1c9b9d206c2 (diff)
downloadFreeBSD-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.
-rw-r--r--sys/amd64/amd64/pmap.c40
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);
OpenPOWER on IntegriCloud