summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_fault.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-08-23 06:52:32 +0000
committeralc <alc@FreeBSD.org>2003-08-23 06:52:32 +0000
commit06fbefe190e0ae8a0c89a80fbd6c80183f7e06e1 (patch)
tree44682ab860f018edce772bcd663f7d2b161b895e /sys/vm/vm_fault.c
parentedbda376e130a72c3d04ba2863f7f2772ac1175e (diff)
downloadFreeBSD-src-06fbefe190e0ae8a0c89a80fbd6c80183f7e06e1.zip
FreeBSD-src-06fbefe190e0ae8a0c89a80fbd6c80183f7e06e1.tar.gz
To implement the sequential access optimization, vm_fault() may need to
reacquire the "first" object's lock while a backing object's lock is held. Since this is a lock-order reversal, vm_fault() uses trylock to acquire the first object's lock, skipping the sequential access optimization in the unlikely event that the trylock fails.
Diffstat (limited to 'sys/vm/vm_fault.c')
-rw-r--r--sys/vm/vm_fault.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index ad739bf..2f87cb7 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -446,13 +446,14 @@ readrest:
if (ahead > VM_FAULT_READ_AHEAD)
ahead = VM_FAULT_READ_AHEAD;
}
-
- if ((fs.first_object->type != OBJT_DEVICE) &&
- (behavior == MAP_ENTRY_BEHAV_SEQUENTIAL ||
- (behavior != MAP_ENTRY_BEHAV_RANDOM &&
- fs.pindex >= fs.entry->lastr &&
- fs.pindex < fs.entry->lastr + VM_FAULT_READ))
- ) {
+ is_first_object_locked = FALSE;
+ if ((behavior == MAP_ENTRY_BEHAV_SEQUENTIAL ||
+ (behavior != MAP_ENTRY_BEHAV_RANDOM &&
+ fs.pindex >= fs.entry->lastr &&
+ fs.pindex < fs.entry->lastr + VM_FAULT_READ)) &&
+ (fs.first_object == fs.object ||
+ (is_first_object_locked = VM_OBJECT_TRYLOCK(fs.first_object))) &&
+ fs.first_object->type != OBJT_DEVICE) {
vm_pindex_t firstpindex, tmppindex;
if (fs.first_pindex < 2 * VM_FAULT_READ)
@@ -492,7 +493,8 @@ readrest:
ahead += behind;
behind = 0;
}
-
+ if (is_first_object_locked)
+ VM_OBJECT_UNLOCK(fs.first_object);
/*
* now we find out if any other pages should be paged
* in at this time this routine checks to see if the
OpenPOWER on IntegriCloud