Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 May 2019 15:44:53 +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-12@freebsd.org
Subject:   svn commit: r347346 - stable/12/sys/vm
Message-ID:  <201905081544.x48Firc8013377@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Wed May  8 15:44:53 2019
New Revision: 347346
URL: https://svnweb.freebsd.org/changeset/base/347346

Log:
  MFC r346990:
  Fix another race between vm_map_protect() and vm_map_wire().

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

Modified: stable/12/sys/vm/vm_map.c
==============================================================================
--- stable/12/sys/vm/vm_map.c	Wed May  8 15:43:22 2019	(r347345)
+++ stable/12/sys/vm/vm_map.c	Wed May  8 15:44:53 2019	(r347346)
@@ -2347,7 +2347,7 @@ int
 vm_map_protect(vm_map_t map, vm_offset_t start, vm_offset_t end,
 	       vm_prot_t new_prot, boolean_t set_max)
 {
-	vm_map_entry_t current, entry;
+	vm_map_entry_t current, entry, in_tran;
 	vm_object_t obj;
 	struct ucred *cred;
 	vm_prot_t old_prot;
@@ -2355,6 +2355,8 @@ vm_map_protect(vm_map_t map, vm_offset_t start, vm_off
 	if (start == end)
 		return (KERN_SUCCESS);
 
+again:
+	in_tran = NULL;
 	vm_map_lock(map);
 
 	/*
@@ -2387,6 +2389,22 @@ vm_map_protect(vm_map_t map, vm_offset_t start, vm_off
 			vm_map_unlock(map);
 			return (KERN_PROTECTION_FAILURE);
 		}
+		if ((entry->eflags & MAP_ENTRY_IN_TRANSITION) != 0)
+			in_tran = entry;
+	}
+
+	/*
+	 * Postpone the operation until all in transition map entries
+	 * are stabilized.  In-transition entry might already have its
+	 * pages wired and wired_count incremented, but
+	 * MAP_ENTRY_USER_WIRED flag not yet set, and visible to other
+	 * threads because the map lock is dropped.  In this case we
+	 * would miss our call to vm_fault_copy_entry().
+	 */
+	if (in_tran != NULL) {
+		in_tran->eflags |= MAP_ENTRY_NEEDS_WAKEUP;
+		vm_map_unlock_and_wait(map, 0);
+		goto again;
 	}
 
 	/*



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