Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 May 2012 15:25:35 +0000 (UTC)
From:      Alan Cox <alc@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r235912 - head/sys/i386/i386
Message-ID:  <201205241525.q4OFPZes045568@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: alc
Date: Thu May 24 15:25:35 2012
New Revision: 235912
URL: http://svn.freebsd.org/changeset/base/235912

Log:
  MF amd64 r233097, r233122
  
  With the changes over the past year to how accesses to the page's dirty
  field are synchronized, there is no need for pmap_protect() to acquire
  the page queues lock unless it is going to access the pv lists or
  PMAP1/PADDR1.
  
  Style fix to pmap_protect().

Modified:
  head/sys/i386/i386/pmap.c

Modified: head/sys/i386/i386/pmap.c
==============================================================================
--- head/sys/i386/i386/pmap.c	Thu May 24 14:07:44 2012	(r235911)
+++ head/sys/i386/i386/pmap.c	Thu May 24 15:25:35 2012	(r235912)
@@ -3050,7 +3050,7 @@ pmap_protect(pmap_t pmap, vm_offset_t sv
 	vm_offset_t pdnxt;
 	pd_entry_t ptpaddr;
 	pt_entry_t *pte;
-	int anychanged;
+	boolean_t anychanged, pv_lists_locked;
 
 	if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
 		pmap_remove(pmap, sva, eva);
@@ -3066,10 +3066,16 @@ pmap_protect(pmap_t pmap, vm_offset_t sv
 		return;
 #endif
 
-	anychanged = 0;
+	if (pmap_is_current(pmap))
+		pv_lists_locked = FALSE;
+	else {
+		pv_lists_locked = TRUE;
+resume:
+		vm_page_lock_queues();
+		sched_pin();
+	}
+	anychanged = FALSE;
 
-	vm_page_lock_queues();
-	sched_pin();
 	PMAP_LOCK(pmap);
 	for (; sva < eva; sva = pdnxt) {
 		pt_entry_t obits, pbits;
@@ -3104,12 +3110,27 @@ pmap_protect(pmap_t pmap, vm_offset_t sv
 				 */
 				if (pmap_protect_pde(pmap,
 				    &pmap->pm_pdir[pdirindex], sva, prot))
-					anychanged = 1;
-				continue;
-			} else if (!pmap_demote_pde(pmap,
-			    &pmap->pm_pdir[pdirindex], sva)) {
-				/* The large page mapping was destroyed. */
+					anychanged = TRUE;
 				continue;
+			} else {
+				if (!pv_lists_locked) {
+					pv_lists_locked = TRUE;
+					if (!mtx_trylock(&vm_page_queue_mtx)) {
+						if (anychanged)
+							pmap_invalidate_all(
+							    pmap);
+						PMAP_UNLOCK(pmap);
+						goto resume;
+					}
+				}
+				if (!pmap_demote_pde(pmap,
+				    &pmap->pm_pdir[pdirindex], sva)) {
+					/*
+					 * The large page mapping was
+					 * destroyed.
+					 */
+					continue;
+				}
 			}
 		}
 
@@ -3155,14 +3176,16 @@ retry:
 				if (obits & PG_G)
 					pmap_invalidate_page(pmap, sva);
 				else
-					anychanged = 1;
+					anychanged = TRUE;
 			}
 		}
 	}
-	sched_unpin();
 	if (anychanged)
 		pmap_invalidate_all(pmap);
-	vm_page_unlock_queues();
+	if (pv_lists_locked) {
+		sched_unpin();
+		vm_page_unlock_queues();
+	}
 	PMAP_UNLOCK(pmap);
 }
 



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