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;