Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 2 Jul 2012 05:57:44 +0000 (UTC)
From:      Alan Cox <alc@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: r237952 - stable/9/sys/i386/i386
Message-ID:  <201207020557.q625viCY047706@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: alc
Date: Mon Jul  2 05:57:44 2012
New Revision: 237952
URL: http://svn.freebsd.org/changeset/base/237952

Log:
  MFC r235912
    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.

Modified:
  stable/9/sys/i386/i386/pmap.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/i386/i386/pmap.c
==============================================================================
--- stable/9/sys/i386/i386/pmap.c	Mon Jul  2 05:57:01 2012	(r237951)
+++ stable/9/sys/i386/i386/pmap.c	Mon Jul  2 05:57:44 2012	(r237952)
@@ -3125,7 +3125,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);
@@ -3141,10 +3141,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;
@@ -3179,12 +3185,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;
+				}
 			}
 		}
 
@@ -3230,14 +3251,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?201207020557.q625viCY047706>