summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_map.c42
-rw-r--r--sys/vm/vm_map.h5
-rw-r--r--sys/vm/vm_mmap.c16
-rw-r--r--sys/vm/vm_page.c9
4 files changed, 59 insertions, 13 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 35552a6..1a51af8 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -671,6 +671,41 @@ vm_map_wakeup(vm_map_t map)
wakeup(&map->root);
}
+void
+vm_map_busy(vm_map_t map)
+{
+
+ VM_MAP_ASSERT_LOCKED(map);
+ map->busy++;
+}
+
+void
+vm_map_unbusy(vm_map_t map)
+{
+
+ VM_MAP_ASSERT_LOCKED(map);
+ KASSERT(map->busy, ("vm_map_unbusy: not busy"));
+ if (--map->busy == 0 && (map->flags & MAP_BUSY_WAKEUP)) {
+ vm_map_modflags(map, 0, MAP_BUSY_WAKEUP);
+ wakeup(&map->busy);
+ }
+}
+
+void
+vm_map_wait_busy(vm_map_t map)
+{
+
+ VM_MAP_ASSERT_LOCKED(map);
+ while (map->busy) {
+ vm_map_modflags(map, MAP_BUSY_WAKEUP, 0);
+ if (map->system_map)
+ msleep(&map->busy, &map->system_mtx, 0, "mbusy", 0);
+ else
+ sx_sleep(&map->busy, &map->lock, 0, "mbusy", 0);
+ }
+ map->timestamp++;
+}
+
long
vmspace_resident_count(struct vmspace *vmspace)
{
@@ -718,6 +753,7 @@ _vm_map_init(vm_map_t map, pmap_t pmap, vm_offset_t min, vm_offset_t max)
map->flags = 0;
map->root = NULL;
map->timestamp = 0;
+ map->busy = 0;
}
void
@@ -2382,12 +2418,14 @@ vm_map_wire(vm_map_t map, vm_offset_t start, vm_offset_t end,
entry->object.vm_object->type == OBJT_SG);
/*
* Release the map lock, relying on the in-transition
- * mark.
+ * mark. Mark the map busy for fork.
*/
+ vm_map_busy(map);
vm_map_unlock(map);
rv = vm_fault_wire(map, saved_start, saved_end,
fictitious);
vm_map_lock(map);
+ vm_map_unbusy(map);
if (last_timestamp + 1 != map->timestamp) {
/*
* Look again for the entry because the map was
@@ -2995,6 +3033,8 @@ vmspace_fork(struct vmspace *vm1, vm_ooffset_t *fork_charge)
int locked;
vm_map_lock(old_map);
+ if (old_map->busy)
+ vm_map_wait_busy(old_map);
vm2 = vmspace_alloc(old_map->min_offset, old_map->max_offset);
if (vm2 == NULL)
goto unlock_and_return;
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
index f7fc5f5..fecbffe 100644
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -187,12 +187,14 @@ struct vm_map {
pmap_t pmap; /* (c) Physical map */
#define min_offset header.start /* (c) */
#define max_offset header.end /* (c) */
+ int busy;
};
/*
* vm_flags_t values
*/
#define MAP_WIREFUTURE 0x01 /* wire all future pages */
+#define MAP_BUSY_WAKEUP 0x02
#ifdef _KERNEL
static __inline vm_offset_t
@@ -275,6 +277,9 @@ int _vm_map_lock_upgrade(vm_map_t map, const char *file, int line);
void _vm_map_lock_downgrade(vm_map_t map, const char *file, int line);
int vm_map_locked(vm_map_t map);
void vm_map_wakeup(vm_map_t map);
+void vm_map_busy(vm_map_t map);
+void vm_map_unbusy(vm_map_t map);
+void vm_map_wait_busy(vm_map_t map);
#define vm_map_lock(map) _vm_map_lock(map, LOCK_FILE, LOCK_LINE)
#define vm_map_unlock(map) _vm_map_unlock(map, LOCK_FILE, LOCK_LINE)
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index f2dba2c..a73e03a 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -276,14 +276,14 @@ mmap(td, uap)
if (addr + size < addr)
return (EINVAL);
} else {
- /*
- * XXX for non-fixed mappings where no hint is provided or
- * the hint would fall in the potential heap space,
- * place it after the end of the largest possible heap.
- *
- * There should really be a pmap call to determine a reasonable
- * location.
- */
+ /*
+ * XXX for non-fixed mappings where no hint is provided or
+ * the hint would fall in the potential heap space,
+ * place it after the end of the largest possible heap.
+ *
+ * There should really be a pmap call to determine a reasonable
+ * location.
+ */
PROC_LOCK(td->td_proc);
if (addr == 0 ||
(addr >= round_page((vm_offset_t)vms->vm_taddr) &&
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 863b842..1208ea0 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -430,11 +430,12 @@ vm_page_startup(vm_offset_t vaddr)
*/
new_end = vm_reserv_startup(&vaddr, new_end, high_water);
#endif
-#ifdef __amd64__
+#if defined(__amd64__) || defined(__mips__)
/*
- * pmap_map on amd64 comes out of the direct-map, not kvm like i386,
- * so the pages must be tracked for a crashdump to include this data.
- * This includes the vm_page_array and the early UMA bootstrap pages.
+ * pmap_map on amd64 and mips can come out of the direct-map, not kvm
+ * like i386, so the pages must be tracked for a crashdump to include
+ * this data. This includes the vm_page_array and the early UMA
+ * bootstrap pages.
*/
for (pa = new_end; pa < phys_avail[biggestone + 1]; pa += PAGE_SIZE)
dump_add_page(pa);
OpenPOWER on IntegriCloud