From 550f9a075207b6b3f398d292ccae7335eba38189 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Wed, 1 Apr 2015 14:01:14 +0200 Subject: XXX pmm from x15, userspace crashes soon --- vm/vm_object.c | 102 ++++++++++++++++++++------------------------------------- 1 file changed, 36 insertions(+), 66 deletions(-) (limited to 'vm/vm_object.c') diff --git a/vm/vm_object.c b/vm/vm_object.c index ee09e3b..3c7d73c 100644 --- a/vm/vm_object.c +++ b/vm/vm_object.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -219,7 +220,7 @@ static void _vm_object_setup( vm_size_t size) { *object = vm_object_template; - queue_init(&object->memq); + rdxtree_init(&object->memt); vm_object_lock_init(object); object->size = size; } @@ -585,18 +586,15 @@ void vm_object_terminate( * It is possible for us to find busy/absent pages, * if some faults on this object were aborted. */ - + struct rdxtree_iter iter; if ((object->temporary) || (object->pager == IP_NULL)) { - while (!queue_empty(&object->memq)) { - p = (vm_page_t) queue_first(&object->memq); - + rdxtree_for_each(&object->memt, &iter, p) { VM_PAGE_CHECK(p); VM_PAGE_FREE(p); + rdxtree_iter_init(&iter); } - } else while (!queue_empty(&object->memq)) { - p = (vm_page_t) queue_first(&object->memq); - + } else rdxtree_for_each(&object->memt, &iter, p) { VM_PAGE_CHECK(p); vm_page_lock_queues(); @@ -625,6 +623,7 @@ void vm_object_terminate( } else { free_page: VM_PAGE_FREE(p); + rdxtree_iter_init(&iter); } } @@ -737,7 +736,6 @@ void vm_object_abort_activity( vm_object_t object) { vm_page_t p; - vm_page_t next; /* * Abort all activity that would be waiting @@ -748,10 +746,8 @@ void vm_object_abort_activity( * we don't. */ - p = (vm_page_t) queue_first(&object->memq); - while (!queue_end(&object->memq, (queue_entry_t) p)) { - next = (vm_page_t) queue_next(&p->listq); - + struct rdxtree_iter iter; + rdxtree_for_each(&object->memt, &iter, p) { /* * If it's being paged in, destroy it. * If an unlock has been requested, start it again. @@ -765,8 +761,7 @@ void vm_object_abort_activity( p->unlock_request = VM_PROT_NONE; PAGE_WAKEUP(p); } - - p = next; + rdxtree_iter_init(&iter); } /* @@ -874,7 +869,8 @@ void vm_object_deactivate_pages( { vm_page_t p; - queue_iterate(&object->memq, p, vm_page_t, listq) { + struct rdxtree_iter iter; + rdxtree_for_each(&object->memt, &iter, p) { vm_page_lock_queues(); if (!p->busy) vm_page_deactivate(p); @@ -937,7 +933,8 @@ void vm_object_pmap_protect( end = offset + size; - queue_iterate(&object->memq, p, vm_page_t, listq) { + struct rdxtree_iter iter; + rdxtree_for_each(&object->memt, &iter, p) { if (!p->fictitious && (offset <= p->offset) && (p->offset < end)) { @@ -1011,7 +1008,8 @@ void vm_object_pmap_remove( return; vm_object_lock(object); - queue_iterate(&object->memq, p, vm_page_t, listq) { + struct rdxtree_iter iter; + rdxtree_for_each(&object->memt, &iter, p) { if (!p->fictitious && (start <= p->offset) && (p->offset < end)) @@ -1381,7 +1379,8 @@ kern_return_t vm_object_copy_call( * the old memory object that we can. */ - queue_iterate(&src_object->memq, p, vm_page_t, listq) { + struct rdxtree_iter iter; + rdxtree_for_each(&src_object->memt, &iter, p) { if (!p->fictitious && (src_offset <= p->offset) && (p->offset < src_end) && @@ -1570,7 +1569,8 @@ vm_object_t vm_object_copy_delayed( * those pages will already be marked copy-on-write. */ - queue_iterate(&src_object->memq, p, vm_page_t, listq) { + struct rdxtree_iter iter; + rdxtree_for_each(&src_object->memt, &iter, p) { if (!p->fictitious) pmap_page_protect(p->phys_addr, (VM_PROT_ALL & ~VM_PROT_WRITE & @@ -2437,12 +2437,8 @@ void vm_object_collapse( * will be overwritten by any of the parent's * pages that shadow them. */ - - while (!queue_empty(&backing_object->memq)) { - - p = (vm_page_t) - queue_first(&backing_object->memq); - + struct rdxtree_iter iter; + rdxtree_for_each(&backing_object->memt, &iter, p) { new_offset = (p->offset - backing_offset); assert(!p->busy || p->absent); @@ -2504,6 +2500,7 @@ void vm_object_collapse( vm_page_rename(p, object, new_offset); } } + rdxtree_iter_init(&iter); } /* @@ -2637,8 +2634,8 @@ void vm_object_collapse( * of pages here. */ - queue_iterate(&backing_object->memq, p, - vm_page_t, listq) + struct rdxtree_iter iter; + rdxtree_for_each(&backing_object->memt, &iter, p) { new_offset = (p->offset - backing_offset); @@ -2710,47 +2707,21 @@ void vm_object_collapse( * In/out conditions: * The object must be locked. */ -unsigned int vm_object_page_remove_lookup = 0; -unsigned int vm_object_page_remove_iterate = 0; void vm_object_page_remove( vm_object_t object, vm_offset_t start, vm_offset_t end) { - vm_page_t p, next; - - /* - * One and two page removals are most popular. - * The factor of 16 here is somewhat arbitrary. - * It balances vm_object_lookup vs iteration. - */ - - if (atop(end - start) < (unsigned)object->resident_page_count/16) { - vm_object_page_remove_lookup++; - - for (; start < end; start += PAGE_SIZE) { - p = vm_page_lookup(object, start); - if (p != VM_PAGE_NULL) { - if (!p->fictitious) - pmap_page_protect(p->phys_addr, - VM_PROT_NONE); - VM_PAGE_FREE(p); - } - } - } else { - vm_object_page_remove_iterate++; - - p = (vm_page_t) queue_first(&object->memq); - while (!queue_end(&object->memq, (queue_entry_t) p)) { - next = (vm_page_t) queue_next(&p->listq); - if ((start <= p->offset) && (p->offset < end)) { - if (!p->fictitious) - pmap_page_protect(p->phys_addr, - VM_PROT_NONE); - VM_PAGE_FREE(p); - } - p = next; + vm_page_t p; + struct rdxtree_iter iter; + rdxtree_for_each(&object->memt, &iter, p) { + if ((start <= p->offset) && (p->offset < end)) { + if (!p->fictitious) + pmap_page_protect(p->phys_addr, + VM_PROT_NONE); + VM_PAGE_FREE(p); + rdxtree_iter_init(&iter); } } } @@ -2977,15 +2948,14 @@ void vm_object_print( if (vm_object_print_pages) { count = 0; - p = (vm_page_t) queue_first(&object->memq); - while (!queue_end(&object->memq, (queue_entry_t) p)) { + struct rdxtree_iter iter; + rdxtree_for_each(&object->memt, &iter, p) { if (count == 0) iprintf("memory:="); else if (count == 4) {printf("\n"); iprintf(" ..."); count = 0;} else printf(","); count++; printf("(off=0x%X,page=0x%X)", p->offset, (vm_offset_t) p); - p = (vm_page_t) queue_next(&p->listq); } if (count != 0) printf("\n"); -- cgit v1.2.3