summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-01-27 01:12:35 +0000
committeralc <alc@FreeBSD.org>2003-01-27 01:12:35 +0000
commit194d4d0ebe88dd44ab7d65399df465a2dd2db945 (patch)
tree0d509ce3eebe463648d7e5d961b2399d932c670a /sys/vm
parent0558ae797113e90550f5c3a68fc95c48d1f547f9 (diff)
downloadFreeBSD-src-194d4d0ebe88dd44ab7d65399df465a2dd2db945.zip
FreeBSD-src-194d4d0ebe88dd44ab7d65399df465a2dd2db945.tar.gz
Simplify vm_object_page_remove(): The object's memq is now ordered. The
two cases that existed before for performance optimization purposes can be reduced to one.
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_object.c93
1 files changed, 31 insertions, 62 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index f00499f..5f4a04c 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -1697,7 +1697,6 @@ void
vm_object_page_remove(vm_object_t object, vm_pindex_t start, vm_pindex_t end, boolean_t clean_only)
{
vm_page_t p, next;
- vm_pindex_t size;
int all;
if (object == NULL ||
@@ -1715,69 +1714,39 @@ vm_object_page_remove(vm_object_t object, vm_pindex_t start, vm_pindex_t end, bo
vm_object_pip_add(object, 1);
again:
vm_page_lock_queues();
- size = end - start;
- if (all || size > object->resident_page_count / 4) {
- for (p = TAILQ_FIRST(&object->memq); p != NULL; p = next) {
- next = TAILQ_NEXT(p, listq);
- if (all || ((start <= p->pindex) && (p->pindex < end))) {
- if (p->wire_count != 0) {
- pmap_remove_all(p);
- if (!clean_only)
- p->valid = 0;
- continue;
- }
-
- /*
- * The busy flags are only cleared at
- * interrupt -- minimize the spl transitions
- */
- if (vm_page_sleep_if_busy(p, TRUE, "vmopar"))
- goto again;
-
- if (clean_only && p->valid) {
- vm_page_test_dirty(p);
- if (p->valid & p->dirty)
- continue;
- }
- vm_page_busy(p);
- pmap_remove_all(p);
- vm_page_free(p);
- }
+ if ((p = TAILQ_FIRST(&object->memq)) != NULL) {
+ if (p->pindex < start) {
+ p = vm_page_splay(start, object->root);
+ if ((object->root = p)->pindex < start)
+ p = TAILQ_NEXT(p, listq);
}
- } else {
- while (size > 0) {
- if ((p = vm_page_lookup(object, start)) != NULL) {
- if (p->wire_count != 0) {
- pmap_remove_all(p);
- if (!clean_only)
- p->valid = 0;
- start += 1;
- size -= 1;
- continue;
- }
-
- /*
- * The busy flags are only cleared at
- * interrupt -- minimize the spl transitions
- */
- if (vm_page_sleep_if_busy(p, TRUE, "vmopar"))
- goto again;
-
- if (clean_only && p->valid) {
- vm_page_test_dirty(p);
- if (p->valid & p->dirty) {
- start += 1;
- size -= 1;
- continue;
- }
- }
- vm_page_busy(p);
- pmap_remove_all(p);
- vm_page_free(p);
- }
- start += 1;
- size -= 1;
+ }
+ /*
+ * Assert: the variable p is either (1) the page with the
+ * least pindex greater than or equal to the parameter pindex
+ * or (2) NULL.
+ */
+ for (;
+ p != NULL && (all || p->pindex < end);
+ p = next) {
+ next = TAILQ_NEXT(p, listq);
+
+ if (p->wire_count != 0) {
+ pmap_remove_all(p);
+ if (!clean_only)
+ p->valid = 0;
+ continue;
+ }
+ if (vm_page_sleep_if_busy(p, TRUE, "vmopar"))
+ goto again;
+ if (clean_only && p->valid) {
+ vm_page_test_dirty(p);
+ if (p->valid & p->dirty)
+ continue;
}
+ vm_page_busy(p);
+ pmap_remove_all(p);
+ vm_page_free(p);
}
vm_page_unlock_queues();
vm_object_pip_wakeup(object);
OpenPOWER on IntegriCloud