Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 9 Jan 2014 03:32:04 +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-10@freebsd.org
Subject:   svn commit: r260467 - stable/10/sys/amd64/amd64
Message-ID:  <201401090332.s093W4VV017207@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Thu Jan  9 03:32:03 2014
New Revision: 260467
URL: http://svnweb.freebsd.org/changeset/base/260467

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/10/sys/amd64/amd64/pmap.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/amd64/amd64/pmap.c
==============================================================================
--- stable/10/sys/amd64/amd64/pmap.c	Thu Jan  9 03:25:54 2014	(r260466)
+++ stable/10/sys/amd64/amd64/pmap.c	Thu Jan  9 03:32:03 2014	(r260467)
@@ -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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201401090332.s093W4VV017207>