diff options
author | dillon <dillon@FreeBSD.org> | 2001-10-26 00:08:05 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 2001-10-26 00:08:05 +0000 |
commit | f883ef447af57985b21cde8cd13232ca845190a4 (patch) | |
tree | d2fcc74cff2c1c1ff478c189a5bc5cafc79d4509 /sys/vm | |
parent | 9e3e7670a88869e7b562b5608cd584c56c3a6517 (diff) | |
download | FreeBSD-src-f883ef447af57985b21cde8cd13232ca845190a4.zip FreeBSD-src-f883ef447af57985b21cde8cd13232ca845190a4.tar.gz |
Implement kern.maxvnodes. adjusting kern.maxvnodes now actually has a
real effect.
Optimize vfs_msync(). Avoid having to continually drop and re-obtain
mutexes when scanning the vnode list. Improves looping case by 500%.
Optimize ffs_sync(). Avoid having to continually drop and re-obtain
mutexes when scanning the vnode list. This makes a couple of assumptions,
which I believe are ok, in regards to vnode stability when the mount list
mutex is held. Improves looping case by 500%.
(more optimization work is needed on top of these fixes)
MFC after: 1 week
Diffstat (limited to 'sys/vm')
-rw-r--r-- | sys/vm/vm_fault.c | 3 | ||||
-rw-r--r-- | sys/vm/vm_object.c | 41 | ||||
-rw-r--r-- | sys/vm/vm_object.h | 1 | ||||
-rw-r--r-- | sys/vm/vm_page.c | 2 |
4 files changed, 42 insertions, 5 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 3507353..8814ae5 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -806,8 +806,7 @@ readrest: if (prot & VM_PROT_WRITE) { vm_page_flag_set(fs.m, PG_WRITEABLE); - vm_object_set_flag(fs.m->object, - OBJ_WRITEABLE|OBJ_MIGHTBEDIRTY); + vm_object_set_writeable_dirty(fs.m->object); /* * If the fault is a write, we know that this page is being diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 1d5a989..b7613eb 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -321,8 +321,11 @@ vm_object_reference(vm_object_t object) if (object == NULL) return; +#if 0 + /* object can be re-referenced during final cleaning */ KASSERT(!(object->flags & OBJ_DEAD), ("vm_object_reference: attempting to reference dead obj")); +#endif object->ref_count++; if (object->type == OBJT_VNODE) { @@ -454,8 +457,13 @@ doterm: temp->generation++; object->backing_object = NULL; } - vm_object_terminate(object); - /* unlocks and deallocates object */ + /* + * Don't double-terminate, we could be in a termination + * recursion due to the terminate having to sync data + * to disk. + */ + if ((object->flags & OBJ_DEAD) == 0) + vm_object_terminate(object); object = temp; } } @@ -627,7 +635,17 @@ vm_object_page_clean(vm_object_t object, vm_pindex_t start, vm_pindex_t end, int } if (clearobjflags && (tstart == 0) && (tend == object->size)) { + struct vnode *vp; + vm_object_clear_flag(object, OBJ_WRITEABLE|OBJ_MIGHTBEDIRTY); + if (object->type == OBJT_VNODE && + (vp = (struct vnode *)object->handle) != NULL) { + if (vp->v_flag & VOBJDIRTY) { + mtx_lock(&vp->v_interlock); + vp->v_flag &= ~VOBJDIRTY; + mtx_unlock(&vp->v_interlock); + } + } } rescan: @@ -1357,6 +1375,8 @@ vm_object_collapse(vm_object_t object) * and no object references within it, all that is * necessary is to dispose of it. */ + KASSERT(backing_object->ref_count == 1, ("backing_object %p was somehow re-referenced during collapse!", backing_object)); + KASSERT(TAILQ_FIRST(&backing_object->memq) == NULL, ("backing_object %p somehow has left over pages during collapse!", backing_object)); TAILQ_REMOVE( &vm_object_list, @@ -1684,6 +1704,23 @@ vm_object_in_map(vm_object_t object) return 0; } +void +vm_object_set_writeable_dirty(vm_object_t object) +{ + struct vnode *vp; + + vm_object_set_flag(object, OBJ_WRITEABLE|OBJ_MIGHTBEDIRTY); + if (object->type == OBJT_VNODE && + (vp = (struct vnode *)object->handle) != NULL) { + if ((vp->v_flag & VOBJDIRTY) == 0) { + mtx_lock(&vp->v_interlock); + vp->v_flag |= VOBJDIRTY; + mtx_unlock(&vp->v_interlock); + } + } +} + + DB_SHOW_COMMAND(vmochk, vm_object_check) { vm_object_t object; diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h index c126cb6..1256e85 100644 --- a/sys/vm/vm_object.h +++ b/sys/vm/vm_object.h @@ -184,6 +184,7 @@ void vm_object_collapse (vm_object_t); void vm_object_deallocate (vm_object_t); void vm_object_terminate (vm_object_t); void vm_object_vndeallocate (vm_object_t); +void vm_object_set_writeable_dirty (vm_object_t); void vm_object_init (void); void vm_object_page_clean (vm_object_t, vm_pindex_t, vm_pindex_t, boolean_t); void vm_object_page_remove (vm_object_t, vm_pindex_t, vm_pindex_t, boolean_t); diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 61d821f..0eb06fc 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -609,7 +609,7 @@ vm_page_insert(vm_page_t m, vm_object_t object, vm_pindex_t pindex) * update the object's OBJ_WRITEABLE and OBJ_MIGHTBEDIRTY flags. */ if (m->flags & PG_WRITEABLE) - vm_object_set_flag(object, OBJ_WRITEABLE|OBJ_MIGHTBEDIRTY); + vm_object_set_writeable_dirty(object); } /* |