Index: sys/vm/vm_map.c =================================================================== --- sys/vm/vm_map.c +++ sys/vm/vm_map.c @@ -2351,10 +2351,13 @@ vm_object_t obj; struct ucred *cred; vm_prot_t old_prot; + bool in_transition; if (start == end) return (KERN_SUCCESS); +again: + in_transition = false; vm_map_lock(map); /* @@ -2387,6 +2390,24 @@ vm_map_unlock(map); return (KERN_PROTECTION_FAILURE); } + if ((entry->eflags & MAP_ENTRY_IN_TRANSITION) == 0 && + !in_transition) { + in_transition = true; + entry->eflags |= MAP_ENTRY_NEEDS_WAKEUP; + } + } + + /* + * 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_transition) { + vm_map_unlock_and_wait(map, 0); + goto again; } /*