X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/cf7d32b81c573a0536dc4da4157f9c26f8d0bed3..593a1d5fd87cdf5b46dd5fcb84467b432cea0f91:/osfmk/vm/vm_resident.c?ds=sidebyside diff --git a/osfmk/vm/vm_resident.c b/osfmk/vm/vm_resident.c index 313549ecf..7e7520ce1 100644 --- a/osfmk/vm/vm_resident.c +++ b/osfmk/vm/vm_resident.c @@ -340,7 +340,7 @@ vm_page_set_colors( void ) { unsigned int n, override; - if ( PE_parse_boot_arg("colors", &override) ) /* colors specified as a boot-arg? */ + if ( PE_parse_boot_argn("colors", &override, sizeof (override)) ) /* colors specified as a boot-arg? */ n = override; else if ( vm_cache_geometry_colors ) /* do we know what the cache geometry is? */ n = vm_cache_geometry_colors; @@ -684,7 +684,7 @@ pmap_startup( * Check if we want to initialize pages to a known value */ fill = 0; /* Assume no fill */ - if (PE_parse_boot_arg("fill", &fillval)) fill = 1; /* Set fill */ + if (PE_parse_boot_argn("fill", &fillval, sizeof (fillval))) fill = 1; /* Set fill */ /* @@ -957,13 +957,19 @@ vm_page_insert_internal( object->resident_page_count++; - if (object->purgable == VM_PURGABLE_VOLATILE || - object->purgable == VM_PURGABLE_EMPTY) { + if (object->purgable == VM_PURGABLE_VOLATILE) { if (queues_lock_held == FALSE) vm_page_lockspin_queues(); vm_page_purgeable_count++; + if (queues_lock_held == FALSE) + vm_page_unlock_queues(); + } else if (object->purgable == VM_PURGABLE_EMPTY && + mem->throttled) { + if (queues_lock_held == FALSE) + vm_page_lock_queues(); + vm_page_deactivate(mem); if (queues_lock_held == FALSE) vm_page_unlock_queues(); } @@ -1053,8 +1059,7 @@ vm_page_replace( found_m->offset = (vm_object_offset_t) -1; object->resident_page_count--; - if (object->purgable == VM_PURGABLE_VOLATILE || - object->purgable == VM_PURGABLE_EMPTY) { + if (object->purgable == VM_PURGABLE_VOLATILE) { assert(vm_page_purgeable_count > 0); vm_page_purgeable_count--; } @@ -1079,9 +1084,12 @@ vm_page_replace( object->resident_page_count++; - if (object->purgable == VM_PURGABLE_VOLATILE || - object->purgable == VM_PURGABLE_EMPTY) { + if (object->purgable == VM_PURGABLE_VOLATILE) { vm_page_purgeable_count++; + } else if (object->purgable == VM_PURGABLE_EMPTY) { + if (mem->throttled) { + vm_page_deactivate(mem); + } } } @@ -1151,8 +1159,7 @@ vm_page_remove( mem->object->resident_page_count--; - if (mem->object->purgable == VM_PURGABLE_VOLATILE || - mem->object->purgable == VM_PURGABLE_EMPTY) { + if (mem->object->purgable == VM_PURGABLE_VOLATILE) { assert(vm_page_purgeable_count > 0); vm_page_purgeable_count--; } @@ -2164,18 +2171,23 @@ vm_page_free_list( nxt = (vm_page_t)(mem->pageq.next); if (!mem->fictitious) { - mem->free = TRUE; + if (mem->phys_page <= vm_lopage_poolend && mem->phys_page >= vm_lopage_poolstart) { + mem->pageq.next = NULL; + vm_page_release(mem); + } else { + mem->free = TRUE; - color = mem->phys_page & vm_color_mask; - if (queue_empty(&free_list[color])) { - inuse[color] = inuse_list_head; - inuse_list_head = color; + color = mem->phys_page & vm_color_mask; + if (queue_empty(&free_list[color])) { + inuse[color] = inuse_list_head; + inuse_list_head = color; + } + queue_enter_first(&free_list[color], + mem, + vm_page_t, + pageq); + pg_count++; } - queue_enter_first(&free_list[color], - mem, - vm_page_t, - pageq); - pg_count++; } else { assert(mem->phys_page == vm_page_fictitious_addr || mem->phys_page == vm_page_guard_addr); @@ -2301,6 +2313,24 @@ vm_page_wire( mem->zero_fill = FALSE; OSAddAtomic(-1, (SInt32 *)&vm_zf_count); } +#if CONFIG_EMBEDDED + { + int percent_avail; + + /* + * Decide if we need to poke the memorystatus notification thread. + */ + percent_avail = + (vm_page_active_count + vm_page_inactive_count + + vm_page_speculative_count + vm_page_free_count + + (IP_VALID(memory_manager_default)?0:vm_page_purgeable_count) ) * 100 / + atop_64(max_mem); + if (percent_avail <= (kern_memorystatus_level - 5)) { + kern_memorystatus_level = percent_avail; + thread_wakeup((event_t)&kern_memorystatus_wakeup); + } + } +#endif /* * ENCRYPTED SWAP: * The page could be encrypted, but @@ -2369,20 +2399,29 @@ vm_page_unwire( assert(!mem->laundry); assert(mem->object != kernel_object); assert(mem->pageq.next == NULL && mem->pageq.prev == NULL); - if (!IP_VALID(memory_manager_default) && - mem->dirty && mem->object->internal && - (mem->object->purgable == VM_PURGABLE_DENY || - mem->object->purgable == VM_PURGABLE_NONVOLATILE || - mem->object->purgable == VM_PURGABLE_VOLATILE)) { - queue_enter(&vm_page_queue_throttled, mem, vm_page_t, pageq); - vm_page_throttled_count++; - mem->throttled = TRUE; + if (mem->object->purgable == VM_PURGABLE_EMPTY) { + vm_page_deactivate(mem); } else { - queue_enter(&vm_page_queue_active, mem, vm_page_t, pageq); - vm_page_active_count++; - mem->active = TRUE; + vm_page_activate(mem); } - mem->reference = TRUE; +#if CONFIG_EMBEDDED + { + int percent_avail; + + /* + * Decide if we need to poke the memorystatus notification thread. + */ + percent_avail = + (vm_page_active_count + vm_page_inactive_count + + vm_page_speculative_count + vm_page_free_count + + (IP_VALID(memory_manager_default)?0:vm_page_purgeable_count) ) * 100 / + atop_64(max_mem); + if (percent_avail >= (kern_memorystatus_level + 5)) { + kern_memorystatus_level = percent_avail; + thread_wakeup((event_t)&kern_memorystatus_wakeup); + } + } +#endif } } @@ -2987,8 +3026,10 @@ vm_page_find_contiguous( unsigned int page_idx, start_idx; int free_considered, free_available; int substitute_needed; -#if MACH_ASSERT +#if DEBUG uint32_t tv_start_sec, tv_start_usec, tv_end_sec, tv_end_usec; +#endif +#if MACH_ASSERT int yielded = 0; int dumped_run = 0; int stolen_pages = 0; @@ -2999,7 +3040,8 @@ vm_page_find_contiguous( #if MACH_ASSERT vm_page_verify_free_lists(); - +#endif +#if DEBUG clock_get_system_microtime(&tv_start_sec, &tv_start_usec); #endif vm_page_lock_queues(); @@ -3368,7 +3410,7 @@ retry: done_scanning: vm_page_unlock_queues(); -#if MACH_ASSERT +#if DEBUG clock_get_system_microtime(&tv_end_sec, &tv_end_usec); tv_end_sec -= tv_start_sec; @@ -3384,6 +3426,8 @@ done_scanning: printf("vm_find_page_contiguous(num=%d,low=%d): found %d pages in %d.%06ds... scanned %d pages... yielded %d times... dumped run %d times... stole %d pages\n", contig_pages, max_pnum, npages, tv_end_sec, tv_end_usec, page_idx, yielded, dumped_run, stolen_pages); +#endif +#if MACH_ASSERT vm_page_verify_free_lists(); #endif return m;