summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_fault.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-10-04 21:35:48 +0000
committeralc <alc@FreeBSD.org>2003-10-04 21:35:48 +0000
commit3272fbe303ea9a30ce8ce0504703786a6dd83e8b (patch)
tree8b0b026cfc8d3b3ef3aa0296e7ce9dc71298f3de /sys/vm/vm_fault.c
parent96e57c74e6b01016ed04d9977ddd48cf53c5d165 (diff)
downloadFreeBSD-src-3272fbe303ea9a30ce8ce0504703786a6dd83e8b.zip
FreeBSD-src-3272fbe303ea9a30ce8ce0504703786a6dd83e8b.tar.gz
Synchronize access to a vm page's valid field using the containing
vm object's lock.
Diffstat (limited to 'sys/vm/vm_fault.c')
-rw-r--r--sys/vm/vm_fault.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 76fe277..5a47307 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -889,8 +889,6 @@ readrest:
*/
KASSERT(fs.m->flags & PG_BUSY,
("vm_fault: page %p not busy!", fs.m));
- unlock_things(&fs);
-
/*
* Sanity check: page must be completely valid or it is not fit to
* map into user space. vm_pager_get_pages() ensures this.
@@ -899,6 +897,8 @@ readrest:
vm_page_zero_invalid(fs.m, TRUE);
printf("Warning: page %p partially invalid on fault\n", fs.m);
}
+ unlock_things(&fs);
+
pmap_enter(fs.map->pmap, vaddr, fs.m, prot, wired);
if (((fault_flags & VM_FAULT_WIRE_MASK) == 0) && (wired == 0)) {
vm_fault_prefault(fs.map->pmap, vaddr, fs.entry);
@@ -994,12 +994,13 @@ vm_fault_prefault(pmap_t pmap, vm_offset_t addra, vm_map_entry_t entry)
VM_OBJECT_UNLOCK(lobject);
lobject = backing_object;
}
- VM_OBJECT_UNLOCK(lobject);
/*
* give-up when a page is not in memory
*/
- if (m == NULL)
+ if (m == NULL) {
+ VM_OBJECT_UNLOCK(lobject);
break;
+ }
vm_page_lock_queues();
if (((m->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
(m->busy == 0) &&
@@ -1010,11 +1011,14 @@ vm_fault_prefault(pmap_t pmap, vm_offset_t addra, vm_map_entry_t entry)
}
vm_page_busy(m);
vm_page_unlock_queues();
+ VM_OBJECT_UNLOCK(lobject);
mpte = pmap_enter_quick(pmap, addr, m, mpte);
+ VM_OBJECT_LOCK(lobject);
vm_page_lock_queues();
vm_page_wakeup(m);
}
vm_page_unlock_queues();
+ VM_OBJECT_UNLOCK(lobject);
}
}
OpenPOWER on IntegriCloud