summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2005-03-15 14:14:09 +0000
committerjeff <jeff@FreeBSD.org>2005-03-15 14:14:09 +0000
commitd1b34cc38c81af8e8e47ba71ace1e8b1c28275f0 (patch)
tree92f8cebb06e53408a6176d5776ef7112866b4393
parent67bf6d96ea190a4bd20d6b02b7fb6857c4cc7998 (diff)
downloadFreeBSD-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.c29
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) {
OpenPOWER on IntegriCloud