diff options
author | alc <alc@FreeBSD.org> | 2003-10-04 21:35:48 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2003-10-04 21:35:48 +0000 |
commit | 3272fbe303ea9a30ce8ce0504703786a6dd83e8b (patch) | |
tree | 8b0b026cfc8d3b3ef3aa0296e7ce9dc71298f3de /sys/vm/vm_fault.c | |
parent | 96e57c74e6b01016ed04d9977ddd48cf53c5d165 (diff) | |
download | FreeBSD-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.c | 12 |
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); } } |