X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/0b4e3aa066abc0728aacb4bbeb86f53f9737156e..d7e50217d7adf6e52786a38bcaa4cd698cb9a79e:/osfmk/vm/memory_object.c diff --git a/osfmk/vm/memory_object.c b/osfmk/vm/memory_object.c index 90de30229..c3e0f22f0 100644 --- a/osfmk/vm/memory_object.c +++ b/osfmk/vm/memory_object.c @@ -3,19 +3,22 @@ * * @APPLE_LICENSE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -132,7 +135,7 @@ vm_object_update(vm_object_t, vm_object_offset_t, #define memory_object_should_return_page(m, should_return) \ (should_return != MEMORY_OBJECT_RETURN_NONE && \ - (((m)->dirty || ((m)->dirty = pmap_is_modified((m)->phys_addr))) || \ + (((m)->dirty || ((m)->dirty = pmap_is_modified((m)->phys_page))) || \ ((m)->precious && (should_return) == MEMORY_OBJECT_RETURN_ALL) || \ (should_return) == MEMORY_OBJECT_RETURN_ANYTHING)) @@ -188,8 +191,19 @@ memory_object_lock_page( * does not have any data. */ - if (m->absent || m->error || m->restart) - return(MEMORY_OBJECT_LOCK_RESULT_DONE); + if (m->absent || m->error || m->restart) { + if(m->error && should_flush) { + /* dump the page, pager wants us to */ + /* clean it up and there is no */ + /* relevant data to return */ + if(m->wire_count == 0) { + VM_PAGE_FREE(m); + return(MEMORY_OBJECT_LOCK_RESULT_DONE); + } + } else { + return(MEMORY_OBJECT_LOCK_RESULT_DONE); + } + } assert(!m->fictitious); @@ -244,7 +258,7 @@ memory_object_lock_page( if (prot != VM_PROT_NO_CHANGE) { if ((m->page_lock ^ prot) & prot) { - pmap_page_protect(m->phys_addr, VM_PROT_ALL & ~prot); + pmap_page_protect(m->phys_page, VM_PROT_ALL & ~prot); } #if 0 /* code associated with the vestigial @@ -289,7 +303,7 @@ memory_object_lock_page( vm_page_unlock_queues(); if (!should_flush) - pmap_page_protect(m->phys_addr, VM_PROT_NONE); + pmap_page_protect(m->phys_page, VM_PROT_NONE); if (m->dirty) return(MEMORY_OBJECT_LOCK_RESULT_MUST_CLEAN); @@ -395,7 +409,7 @@ memory_object_lock_request( if ((prot & ~VM_PROT_ALL) != 0 && prot != VM_PROT_NO_CHANGE) return (KERN_INVALID_ARGUMENT); - size = round_page(size); + size = round_page_64(size); /* * Lock the object, and acquire a paging reference to @@ -765,10 +779,7 @@ BYPASS_COW_COPYIN: continue; } - PAGE_ASSERT_WAIT(m, THREAD_UNINT); - vm_object_unlock(object); - thread_block((void (*)(void))0); - vm_object_lock(object); + PAGE_SLEEP(object, m, THREAD_UNINT); continue; case MEMORY_OBJECT_LOCK_RESULT_MUST_CLEAN: @@ -801,9 +812,7 @@ BYPASS_COW_COPYIN: m->busy = FALSE; holding_page = VM_PAGE_NULL; if(m->cleaning) { - PAGE_ASSERT_WAIT(m, THREAD_UNINT); - vm_object_unlock(object); - thread_block((void (*)(void))0); + PAGE_SLEEP(object, m, THREAD_UNINT); continue; } if(!pending_pageout) { @@ -954,7 +963,7 @@ vm_object_set_attributes_common( temporary = TRUE; if (cluster_size != 0) { int pages_per_cluster; - pages_per_cluster = atop(cluster_size); + pages_per_cluster = atop_32(cluster_size); /* * Cluster size must be integral multiple of page size, * and be a power of 2 number of pages. @@ -1090,7 +1099,7 @@ memory_object_change_attributes( perf = (memory_object_perf_info_t) attributes; may_cache = perf->may_cache; - cluster_size = round_page(perf->cluster_size); + cluster_size = round_page_32(perf->cluster_size); break; } @@ -1415,7 +1424,7 @@ host_default_memory_manager( mutex_unlock(&memory_manager_default_lock); return KERN_INVALID_ARGUMENT; #else - cluster_size = round_page(cluster_size); + cluster_size = round_page_32(cluster_size); #endif } memory_manager_default_cluster = cluster_size; @@ -1451,9 +1460,12 @@ memory_manager_default_reference( mutex_lock(&memory_manager_default_lock); current_manager = memory_manager_default; while (current_manager == MEMORY_OBJECT_DEFAULT_NULL) { - thread_sleep_mutex((event_t) &memory_manager_default, - &memory_manager_default_lock, THREAD_UNINT); - mutex_lock(&memory_manager_default_lock); + wait_result_t res; + + res = thread_sleep_mutex((event_t) &memory_manager_default, + &memory_manager_default_lock, + THREAD_UNINT); + assert(res == THREAD_AWAKENED); current_manager = memory_manager_default; } memory_object_default_reference(current_manager); @@ -1539,17 +1551,25 @@ memory_object_deactivate_pages( if ((m->wire_count == 0) && (!m->private) && (!m->gobbled) && (!m->busy)) { m->reference = FALSE; - pmap_clear_reference(m->phys_addr); + pmap_clear_reference(m->phys_page); if ((kill_page) && (object->internal)) { m->precious = FALSE; m->dirty = FALSE; - pmap_clear_modify(m->phys_addr); + pmap_clear_modify(m->phys_page); vm_external_state_clr(object->existence_map, offset); } VM_PAGE_QUEUES_REMOVE(m); - queue_enter_first(&vm_page_queue_inactive, m, vm_page_t, pageq); + if(m->zero_fill) { + queue_enter_first( + &vm_page_queue_zf, + m, vm_page_t, pageq); + } else { + queue_enter_first( + &vm_page_queue_inactive, + m, vm_page_t, pageq); + } m->inactive = TRUE; if (!m->fictitious) @@ -1590,7 +1610,7 @@ memory_object_page_op( memory_object_control_t control, memory_object_offset_t offset, int ops, - vm_offset_t *phys_entry, + ppnum_t *phys_entry, int *flags) { vm_object_t object; @@ -1606,8 +1626,8 @@ memory_object_page_op( if(ops & UPL_POP_PHYSICAL) { if(object->phys_contiguous) { if (phys_entry) { - *phys_entry = (vm_offset_t) - object->shadow_offset; + *phys_entry = (ppnum_t) + (object->shadow_offset >> 12); } vm_object_unlock(object); return KERN_SUCCESS; @@ -1634,10 +1654,7 @@ memory_object_page_op( (ops & UPL_POP_BUSY)) || (ops & UPL_POP_DUMP))) { /* someone else is playing with the page, we will */ /* have to wait */ - PAGE_ASSERT_WAIT(dst_page, THREAD_UNINT); - vm_object_unlock(object); - thread_block((void(*)(void))0); - vm_object_lock(object); + PAGE_SLEEP(object, dst_page, THREAD_UNINT); continue; } @@ -1661,7 +1678,7 @@ memory_object_page_op( if(dst_page->busy) *flags |= UPL_POP_BUSY; } if (phys_entry) - *phys_entry = dst_page->phys_addr; + *phys_entry = dst_page->phys_page; /* The caller should have made a call either contingent with */ /* or prior to this call to set UPL_POP_BUSY */