summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2009-02-08 20:30:51 +0000
committerkib <kib@FreeBSD.org>2009-02-08 20:30:51 +0000
commit9a341e28ebd8cb82b35c8eeb849a7607597d399e (patch)
tree329bfc1903e45928be5dc9c04a265341794927c5 /sys/vm
parent17606abd64d468568c5f7cb68d9e22dd675fcb15 (diff)
downloadFreeBSD-src-9a341e28ebd8cb82b35c8eeb849a7607597d399e.zip
FreeBSD-src-9a341e28ebd8cb82b35c8eeb849a7607597d399e.tar.gz
In vm_map_sync(), do not call vm_object_sync() while holding map lock.
Reference object, drop the map lock, and then call vm_object_sync(). The object sync might require vnode lock for OBJT_VNODE type objects. Reviewed by: tegge Tested by: pho
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_map.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 13b9050..281f436 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -2304,6 +2304,7 @@ vm_map_sync(
vm_size_t size;
vm_object_t object;
vm_ooffset_t offset;
+ unsigned int last_timestamp;
vm_map_lock_read(map);
VM_MAP_RANGE_CHECK(map, start, end);
@@ -2338,8 +2339,7 @@ vm_map_sync(
* Make a second pass, cleaning/uncaching pages from the indicated
* objects as we go.
*/
- for (current = entry; current != &map->header && current->start < end;
- current = current->next) {
+ for (current = entry; current != &map->header && current->start < end;) {
offset = current->offset + (start - current->start);
size = (end <= current->end ? end : current->end) - start;
if (current->eflags & MAP_ENTRY_IS_SUB_MAP) {
@@ -2359,8 +2359,16 @@ vm_map_sync(
} else {
object = current->object.vm_object;
}
+ vm_object_reference(object);
+ last_timestamp = map->timestamp;
+ vm_map_unlock_read(map);
vm_object_sync(object, offset, size, syncio, invalidate);
start += size;
+ vm_object_deallocate(object);
+ vm_map_lock_read(map);
+ if (last_timestamp == map->timestamp ||
+ !vm_map_lookup_entry(map, start, &current))
+ current = current->next;
}
vm_map_unlock_read(map);
OpenPOWER on IntegriCloud