xref: /xnu-12377.81.4/osfmk/vm/vm_pageout.h (revision 043036a2b3718f7f0be807e2870f8f47d3fa0796)
1 /*
2  * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*
29  * @OSF_COPYRIGHT@
30  */
31 /*
32  * Mach Operating System
33  * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
34  * All Rights Reserved.
35  *
36  * Permission to use, copy, modify and distribute this software and its
37  * documentation is hereby granted, provided that both the copyright
38  * notice and this permission notice appear in all copies of the
39  * software, derivative works or modified versions, and any portions
40  * thereof, and that both notices appear in supporting documentation.
41  *
42  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
45  *
46  * Carnegie Mellon requests users of this software to return to
47  *
48  *  Software Distribution Coordinator  or  [email protected]
49  *  School of Computer Science
50  *  Carnegie Mellon University
51  *  Pittsburgh PA 15213-3890
52  *
53  * any improvements or extensions that they make and grant Carnegie Mellon
54  * the rights to redistribute these changes.
55  */
56 /*
57  */
58 /*
59  *	File:	vm/vm_pageout.h
60  *	Author:	Avadis Tevanian, Jr.
61  *	Date:	1986
62  *
63  *	Declarations for the pageout daemon interface.
64  */
65 
66 #ifndef _VM_VM_PAGEOUT_H_
67 #define _VM_VM_PAGEOUT_H_
68 
69 #ifdef  KERNEL_PRIVATE
70 
71 #include <mach/mach_types.h>
72 #include <mach/boolean.h>
73 #include <mach/machine/vm_types.h>
74 #include <mach/memory_object_types.h>
75 
76 #include <kern/kern_types.h>
77 #include <kern/locks.h>
78 #include <kern/sched_prim.h>
79 #include <kern/bits.h>
80 
81 #include <libkern/OSAtomic.h>
82 
83 
84 #include <vm/vm_options.h>
85 
86 #ifdef  MACH_KERNEL_PRIVATE
87 #include <vm/vm_page.h>
88 #endif
89 
90 #include <sys/kdebug.h>
91 
92 #define VM_PAGE_AVAILABLE_COUNT()               ((unsigned int)(vm_page_cleaned_count))
93 
94 /* externally manipulated counters */
95 extern unsigned int vm_pageout_cleaned_fault_reactivated;
96 
97 #if CONFIG_FREEZE
98 extern boolean_t memorystatus_freeze_enabled;
99 
100 struct freezer_context {
101 	/*
102 	 * All these counters & variables track the task
103 	 * being frozen.
104 	 * Currently we only freeze one task at a time. Should that
105 	 * change, we'll need to add support for multiple freezer contexts.
106 	 */
107 
108 	task_t  freezer_ctx_task; /* Task being frozen. */
109 
110 	void    *freezer_ctx_chead; /* The chead used to track c_segs allocated */
111 	                            /* to freeze the task.*/
112 
113 	uint64_t        freezer_ctx_swapped_bytes; /* Tracks # of compressed bytes.*/
114 
115 	int     freezer_ctx_uncompressed_pages; /* Tracks # of uncompressed pages frozen. */
116 
117 	char    *freezer_ctx_compressor_scratch_buf; /* Scratch buffer for the compressor algorithm. */
118 };
119 
120 #endif /* CONFIG_FREEZE */
121 
122 #define VM_DYNAMIC_PAGING_ENABLED() (VM_CONFIG_COMPRESSOR_IS_ACTIVE)
123 
124 #if VM_PRESSURE_EVENTS
125 extern boolean_t vm_pressure_events_enabled;
126 #endif /* VM_PRESSURE_EVENTS */
127 
128 extern int      vm_debug_events;
129 
130 #define VM_DEBUG_EVENT(name, event, control, ...)    \
131 	MACRO_BEGIN                                             \
132 	if (__improbable(vm_debug_events)) {                    \
133 	        KDBG_FILTERED((VMDBG_CODE(event)) | control, __VA_ARGS__); \
134 	}                                                       \
135 	MACRO_END
136 
137 #define VM_DEBUG_CONSTANT_EVENT(name, event, control, ...)   \
138 	MACRO_BEGIN                                             \
139 	        KDBG((VMDBG_CODE(event)) | control, __VA_ARGS__); \
140 	MACRO_END
141 
142 extern upl_size_t upl_get_size(
143 	upl_t                   upl);
144 
145 
146 extern kern_return_t    mach_vm_pressure_level_monitor(boolean_t wait_for_pressure, unsigned int *pressure_level);
147 #if KERNEL_PRIVATE
148 extern kern_return_t    mach_vm_wire_level_monitor(int64_t requested_pages);
149 #endif /* KERNEL_PRIVATE */
150 
151 
152 
153 #if UPL_DEBUG
154 extern kern_return_t  upl_ubc_alias_set(
155 	upl_t upl,
156 	uintptr_t alias1,
157 	uintptr_t alias2);
158 extern int  upl_ubc_alias_get(
159 	upl_t upl,
160 	uintptr_t * al,
161 	uintptr_t * al2);
162 #endif /* UPL_DEBUG */
163 
164 extern void vm_countdirtypages(void);
165 
166 extern kern_return_t upl_transpose(
167 	upl_t   upl1,
168 	upl_t   upl2);
169 
170 extern kern_return_t mach_vm_pressure_monitor(
171 	boolean_t       wait_for_pressure,
172 	unsigned int    nsecs_monitored,
173 	unsigned int    *pages_reclaimed_p,
174 	unsigned int    *pages_wanted_p);
175 
176 extern kern_return_t
177 vm_set_buffer_cleanup_callout(
178 	boolean_t       (*func)(int));
179 
180 struct vm_page_stats_reusable {
181 	SInt32          reusable_count;
182 	uint64_t        reusable;
183 	uint64_t        reused;
184 	uint64_t        reused_wire;
185 	uint64_t        reused_remove;
186 	uint64_t        all_reusable_calls;
187 	uint64_t        partial_reusable_calls;
188 	uint64_t        all_reuse_calls;
189 	uint64_t        partial_reuse_calls;
190 	uint64_t        reusable_pages_success;
191 	uint64_t        reusable_pages_failure;
192 	uint64_t        reusable_pages_shared;
193 	uint64_t        reuse_pages_success;
194 	uint64_t        reuse_pages_failure;
195 	uint64_t        can_reuse_success;
196 	uint64_t        can_reuse_failure;
197 	uint64_t        reusable_reclaimed;
198 	uint64_t        reusable_nonwritable;
199 	uint64_t        reusable_shared;
200 	uint64_t        free_shared;
201 };
202 extern struct vm_page_stats_reusable vm_page_stats_reusable;
203 
204 extern int hibernate_flush_memory(void);
205 extern void hibernate_reset_stats(void);
206 extern void hibernate_create_paddr_map(void);
207 
208 extern void vm_set_restrictions(unsigned int num_cpus);
209 
210 extern int vm_compressor_mode;
211 extern kern_return_t vm_pageout_compress_page(void **, char *, vm_page_t);
212 extern kern_return_t vm_pageout_anonymous_pages(void);
213 extern void vm_pageout_disconnect_all_pages(void);
214 extern int vm_toggle_task_selfdonate_pages(task_t);
215 extern void vm_task_set_selfdonate_pages(task_t, bool);
216 
217 struct  vm_config {
218 	boolean_t       compressor_is_present;          /* compressor is initialized and can be used by the freezer, the sweep or the pager */
219 	boolean_t       compressor_is_active;           /* pager can actively compress pages...  'compressor_is_present' must be set */
220 	boolean_t       swap_is_present;                /* swap is initialized and can be used by the freezer, the sweep or the pager */
221 	boolean_t       swap_is_active;                 /* pager can actively swap out compressed segments... 'swap_is_present' must be set */
222 	boolean_t       freezer_swap_is_active;         /* freezer can swap out frozen tasks... "compressor_is_present + swap_is_present" must be set */
223 };
224 
225 extern  struct vm_config        vm_config;
226 
227 
228 #define VM_PAGER_NOT_CONFIGURED                         0x0     /* no compresser or swap configured */
229 #define VM_PAGER_DEFAULT                                0x1     /* Use default pager... DEPRECATED */
230 #define VM_PAGER_COMPRESSOR_NO_SWAP                     0x2     /* Active in-core compressor only. */
231 #define VM_PAGER_COMPRESSOR_WITH_SWAP                   0x4     /* Active in-core compressor + swap backend. */
232 #define VM_PAGER_FREEZER_DEFAULT                        0x8     /* Freezer backed by default pager... DEPRECATED */
233 #define VM_PAGER_FREEZER_COMPRESSOR_NO_SWAP             0x10    /* Freezer backed by in-core compressor only i.e. frozen data remain in-core compressed.*/
234 #define VM_PAGER_COMPRESSOR_NO_SWAP_PLUS_FREEZER_COMPRESSOR_WITH_SWAP   0x20    /* Active in-core compressor + Freezer backed by in-core compressor with swap support too.*/
235 
236 #define VM_PAGER_MAX_MODES                              6       /* Total number of vm compressor modes supported */
237 
238 
239 #define VM_CONFIG_COMPRESSOR_IS_PRESENT         (vm_config.compressor_is_present == TRUE)
240 #define VM_CONFIG_COMPRESSOR_IS_ACTIVE          (vm_config.compressor_is_active == TRUE)
241 #define VM_CONFIG_SWAP_IS_PRESENT               (vm_config.swap_is_present == TRUE)
242 #define VM_CONFIG_SWAP_IS_ACTIVE                (vm_config.swap_is_active == TRUE)
243 #define VM_CONFIG_FREEZER_SWAP_IS_ACTIVE        (vm_config.freezer_swap_is_active == TRUE)
244 
245 #endif  /* KERNEL_PRIVATE */
246 
247 
248 #endif  /* _VM_VM_PAGEOUT_H_ */
249