diff options
author | alc <alc@FreeBSD.org> | 2003-08-23 06:52:32 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2003-08-23 06:52:32 +0000 |
commit | 06fbefe190e0ae8a0c89a80fbd6c80183f7e06e1 (patch) | |
tree | 44682ab860f018edce772bcd663f7d2b161b895e | |
parent | edbda376e130a72c3d04ba2863f7f2772ac1175e (diff) | |
download | FreeBSD-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.
-rw-r--r-- | sys/vm/vm_fault.c | 18 |
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 |