Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 May 2014 16:46:51 +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-10@freebsd.org
Subject:   svn commit: r266589 - stable/10/sys/vm
Message-ID:  <201405231646.s4NGkpHk033939@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: alc
Date: Fri May 23 16:46:50 2014
New Revision: 266589
URL: http://svnweb.freebsd.org/changeset/base/266589

Log:
  MFC r265886, r265948
    With the new-and-improved vm_fault_copy_entry() (r265843), we can always
    avoid soft page faults when adding write access to user wired entries in
    vm_map_protect().  Previously, we only avoided the soft page fault when
    the underlying pages were copy-on-write.  In other words, we avoided the
    pages faults that might sleep on page allocation, but not the trivial
    page faults to update the physical map.
  
    On a fork allow read-only wired pages to be copy-on-write shared between
    the parent and child processes.  Previously, we copied these pages even
    though they are read only.  However, the reason for copying them is
    historical and no longer exists.  In recent times, vm_map_protect() has
    developed the ability to copy pages when write access is added to wired
    copy-on-write pages.  So, in this case, copy-on-write sharing of wired
    pages is not to be feared.  It is not going to lead to copy-on-write
    faults on wired memory.

Modified:
  stable/10/sys/vm/vm_map.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/vm/vm_map.c
==============================================================================
--- stable/10/sys/vm/vm_map.c	Fri May 23 16:22:36 2014	(r266588)
+++ stable/10/sys/vm/vm_map.c	Fri May 23 16:46:50 2014	(r266589)
@@ -1978,10 +1978,17 @@ vm_map_protect(vm_map_t map, vm_offset_t
 		else
 			current->protection = new_prot;
 
-		if ((current->eflags & (MAP_ENTRY_COW | MAP_ENTRY_USER_WIRED))
-		     == (MAP_ENTRY_COW | MAP_ENTRY_USER_WIRED) &&
+		/*
+		 * For user wired map entries, the normal lazy evaluation of
+		 * write access upgrades through soft page faults is
+		 * undesirable.  Instead, immediately copy any pages that are
+		 * copy-on-write and enable write access in the physical map.
+		 */
+		if ((current->eflags & MAP_ENTRY_USER_WIRED) != 0 &&
 		    (current->protection & VM_PROT_WRITE) != 0 &&
 		    (old_prot & VM_PROT_WRITE) == 0) {
+			KASSERT(old_prot != VM_PROT_NONE,
+			    ("vm_map_protect: inaccessible wired map entry"));
 			vm_fault_copy_entry(map, map, current, current, NULL);
 		}
 
@@ -3017,8 +3024,8 @@ vm_map_copy_entry(
 	if ((dst_entry->eflags|src_entry->eflags) & MAP_ENTRY_IS_SUB_MAP)
 		return;
 
-	if (src_entry->wired_count == 0) {
-
+	if (src_entry->wired_count == 0 ||
+	    (src_entry->protection & VM_PROT_WRITE) == 0) {
 		/*
 		 * If the source entry is marked needs_copy, it is already
 		 * write-protected.
@@ -3109,9 +3116,9 @@ vm_map_copy_entry(
 		    dst_entry->end - dst_entry->start, src_entry->start);
 	} else {
 		/*
-		 * Of course, wired down pages can't be set copy-on-write.
-		 * Cause wired pages to be copied into the new map by
-		 * simulating faults (the new pages are pageable)
+		 * We don't want to make writeable wired pages copy-on-write.
+		 * Immediately copy these pages into the new map by simulating
+		 * page faults.  The new pages are pageable.
 		 */
 		vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry,
 		    fork_charge);



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