diff options
author | jeff <jeff@FreeBSD.org> | 2005-03-15 14:14:09 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2005-03-15 14:14:09 +0000 |
commit | d1b34cc38c81af8e8e47ba71ace1e8b1c28275f0 (patch) | |
tree | 92f8cebb06e53408a6176d5776ef7112866b4393 | |
parent | 67bf6d96ea190a4bd20d6b02b7fb6857c4cc7998 (diff) | |
download | FreeBSD-src-d1b34cc38c81af8e8e47ba71ace1e8b1c28275f0.zip FreeBSD-src-d1b34cc38c81af8e8e47ba71ace1e8b1c28275f0.tar.gz |
- In vm_page_insert() hold the backing vnode when the first page
is inserted.
- In vm_page_remove() drop the backing vnode when the last page
is removed.
- Don't check the vnode to see if it must be reclaimed on every
call to vm_page_free_toq() as we only check it now when it is
actually required. This saves us two lock operations per call.
Sponsored by: Isilon Systems, Inc.
-rw-r--r-- | sys/vm/vm_page.c | 29 |
1 files changed, 10 insertions, 19 deletions
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index d9a8467..2e3211f 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -575,6 +575,11 @@ vm_page_insert(vm_page_t m, vm_object_t object, vm_pindex_t pindex) * show that the object has one more resident page. */ object->resident_page_count++; + /* + * Hold the vnode until the last page is released. + */ + if (object->resident_page_count == 1 && object->type == OBJT_VNODE) + vhold((struct vnode *)object->handle); /* * Since we are inserting a new and possibly dirty page, @@ -630,6 +635,11 @@ vm_page_remove(vm_page_t m) */ object->resident_page_count--; object->generation++; + /* + * The vnode may now be recycled. + */ + if (object->resident_page_count == 0 && object->type == OBJT_VNODE) + vdrop((struct vnode *)object->handle); m->object = NULL; } @@ -995,7 +1005,6 @@ void vm_page_free_toq(vm_page_t m) { struct vpgqueues *pq; - vm_object_t object = m->object; mtx_assert(&vm_page_queue_mtx, MA_OWNED); cnt.v_tfree++; @@ -1040,24 +1049,6 @@ vm_page_free_toq(vm_page_t m) } /* - * If we've exhausted the object's resident pages we want to free - * it up. - */ - if (object && - (object->type == OBJT_VNODE) && - ((object->flags & OBJ_DEAD) == 0) - ) { - struct vnode *vp = (struct vnode *)object->handle; - - if (vp) { - VI_LOCK(vp); - if (VSHOULDFREE(vp)) - vfree(vp); - VI_UNLOCK(vp); - } - } - - /* * Clear the UNMANAGED flag when freeing an unmanaged page. */ if (m->flags & PG_UNMANAGED) { |