summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authordg <dg@FreeBSD.org>1998-10-22 02:16:53 +0000
committerdg <dg@FreeBSD.org>1998-10-22 02:16:53 +0000
commitb8a68d9fd9fa6c7e3cbfc74355e2d40ea475df06 (patch)
tree72ae64e5931b47dff270d9fc0de92b177f0e7be8 /sys/vm
parentb173a5087cd17abbd5e834001ccfc7230d62dd51 (diff)
downloadFreeBSD-src-b8a68d9fd9fa6c7e3cbfc74355e2d40ea475df06.zip
FreeBSD-src-b8a68d9fd9fa6c7e3cbfc74355e2d40ea475df06.tar.gz
Make the VM system handle the case where a terminating object contains
legitimately wired pages. Currently we print a diagnostic when this happens, but this will be removed soon when it will be common for this to occur with zero-copy TCP/IP buffers.
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_object.c74
1 files changed, 31 insertions, 43 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index f419e2f..c60ede2 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_object.c,v 1.128 1998/09/04 08:06:57 dfr Exp $
+ * $Id: vm_object.c,v 1.129 1998/09/28 02:40:11 dg Exp $
*/
/*
@@ -91,7 +91,6 @@
#include <vm/vm_zone.h>
static void vm_object_qcollapse __P((vm_object_t object));
-static void vm_object_dispose __P((vm_object_t));
/*
* Virtual memory objects maintain the actual data
@@ -406,7 +405,6 @@ vm_object_terminate(object)
register vm_object_t object;
{
register vm_page_t p;
- int s;
/*
* Make sure no one uses us.
@@ -442,58 +440,48 @@ vm_object_terminate(object)
vp = (struct vnode *) object->handle;
vinvalbuf(vp, V_SAVE, NOCRED, NULL, 0, 0);
-
- /*
- * Let the pager know object is dead.
- */
- vm_pager_deallocate(object);
-
}
- if ((object->type != OBJT_VNODE) && (object->ref_count == 0)) {
+ if (object->ref_count != 0)
+ panic("vm_object_terminate: object with references, ref_count=%d", object->ref_count);
- /*
- * Now free the pages. For internal objects, this also removes them
- * from paging queues.
- */
- while ((p = TAILQ_FIRST(&object->memq)) != NULL) {
+ /*
+ * Now free the pages. For internal objects, this also removes them
+ * from paging queues. Don't free wired pages, just remove them
+ * from the object.
+ */
+ while ((p = TAILQ_FIRST(&object->memq)) != NULL) {
#if !defined(MAX_PERF)
- if (p->busy || (p->flags & PG_BUSY))
- printf("vm_object_terminate: freeing busy page\n");
+ if (p->busy || (p->flags & PG_BUSY))
+ printf("vm_object_terminate: freeing busy page\n");
#endif
+ if (p->wire_count == 0) {
vm_page_busy(p);
vm_page_free(p);
cnt.v_pfree++;
+ } else {
+ printf("vm_object_terminate: not freeing wired page; wire_count=%d\n", p->wire_count);
+ vm_page_remove(p);
}
- /*
- * Let the pager know object is dead.
- */
- vm_pager_deallocate(object);
-
}
+ /*
+ * Let the pager know object is dead.
+ */
+ vm_pager_deallocate(object);
- if ((object->ref_count == 0) && (object->resident_page_count == 0))
- vm_object_dispose(object);
-}
+ /*
+ * Remove the object from the global object list.
+ */
+ simple_lock(&vm_object_list_lock);
+ TAILQ_REMOVE(&vm_object_list, object, object_list);
+ simple_unlock(&vm_object_list_lock);
-/*
- * vm_object_dispose
- *
- * Dispose the object.
- */
-static void
-vm_object_dispose(object)
- vm_object_t object;
-{
- simple_lock(&vm_object_list_lock);
- TAILQ_REMOVE(&vm_object_list, object, object_list);
- vm_object_count--;
- simple_unlock(&vm_object_list_lock);
- /*
- * Free the space for the object.
- */
- zfree(obj_zone, object);
- wakeup(object);
+ wakeup(object);
+
+ /*
+ * Free the space for the object.
+ */
+ zfree(obj_zone, object);
}
/*
OpenPOWER on IntegriCloud