Date: Thu, 9 Jan 2014 03:33:12 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r260468 - stable/9/sys/amd64/amd64 Message-ID: <201401090333.s093XCXr017407@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Thu Jan 9 03:33:12 2014 New Revision: 260468 URL: http://svnweb.freebsd.org/changeset/base/260468 Log: 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. Modified: stable/9/sys/amd64/amd64/pmap.c Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/amd64/amd64/pmap.c ============================================================================== --- stable/9/sys/amd64/amd64/pmap.c Thu Jan 9 03:32:03 2014 (r260467) +++ stable/9/sys/amd64/amd64/pmap.c Thu Jan 9 03:33:12 2014 (r260468) @@ -4386,12 +4386,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) @@ -4408,10 +4416,25 @@ pmap_remove_pages(pmap_t pmap) uint64_t inuse, bitmask; int allfree, field, freed, idx; - 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; rw_rlock(&pvh_global_lock); PMAP_LOCK(pmap);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201401090333.s093XCXr017407>