xref: /NextBSD/include/apple/sys/kern_memorystatus.h (revision 33da5adc555b3bc29986eeadca03829e4ad06b1e)
1 /*
2  * Copyright (c) 2006 Apple Computer, 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 #ifndef SYS_MEMORYSTATUS_H
30 #define SYS_MEMORYSTATUS_H
31 
32 #include <stdint.h>
33 #include <sys/time.h>
34 #if 0
35 #include <sys/proc.h>
36 #endif
37 #include <sys/param.h>
38 typedef u_int64_t              user_addr_t;
39 
40 #define JETSAM_PRIORITY_REVISION                  2
41 
42 #define JETSAM_PRIORITY_IDLE_HEAD                -2
43 /* The value -1 is an alias to JETSAM_PRIORITY_DEFAULT */
44 #define JETSAM_PRIORITY_IDLE                      0
45 #define JETSAM_PRIORITY_IDLE_DEFERRED             1
46 #define JETSAM_PRIORITY_BACKGROUND_OPPORTUNISTIC  2
47 #define JETSAM_PRIORITY_BACKGROUND                3
48 #define JETSAM_PRIORITY_MAIL                      4
49 #define JETSAM_PRIORITY_PHONE                     5
50 #define JETSAM_PRIORITY_UI_SUPPORT                8
51 #define JETSAM_PRIORITY_FOREGROUND_SUPPORT        9
52 #define JETSAM_PRIORITY_FOREGROUND               10
53 #define JETSAM_PRIORITY_AUDIO_AND_ACCESSORY      12
54 #define JETSAM_PRIORITY_CONDUCTOR                13
55 #define JETSAM_PRIORITY_HOME                     16
56 #define JETSAM_PRIORITY_EXECUTIVE                17
57 #define JETSAM_PRIORITY_IMPORTANT                18
58 #define JETSAM_PRIORITY_CRITICAL                 19
59 
60 #define JETSAM_PRIORITY_MAX                      21
61 
62 /* TODO - tune. This should probably be lower priority */
63 #define JETSAM_PRIORITY_DEFAULT                  18
64 #define JETSAM_PRIORITY_TELEPHONY                19
65 
66 /* Compatibility */
67 #define DEFAULT_JETSAM_PRIORITY                  18
68 
69 #define DEFERRED_IDLE_EXIT_TIME_SECS             10
70 
71 #define KEV_MEMORYSTATUS_SUBCLASS                 3
72 
73 enum {
74 	kMemorystatusLevelNote = 1,
75 	kMemorystatusSnapshotNote = 2,
76 	kMemorystatusFreezeNote = 3,
77 	kMemorystatusPressureNote = 4
78 };
79 
80 enum {
81 	kMemorystatusLevelAny = -1,
82 	kMemorystatusLevelNormal = 0,
83 	kMemorystatusLevelWarning = 1,
84 	kMemorystatusLevelUrgent = 2,
85 	kMemorystatusLevelCritical = 3
86 };
87 
88 typedef struct memorystatus_priority_entry {
89 	pid_t pid;
90 	int32_t priority;
91 	uint64_t user_data;
92 	int32_t limit;
93 	uint32_t state;
94 } memorystatus_priority_entry_t;
95 
96 typedef struct memorystatus_kernel_stats {
97 	uint32_t free_pages;
98 	uint32_t active_pages;
99 	uint32_t inactive_pages;
100 	uint32_t throttled_pages;
101 	uint32_t purgeable_pages;
102 	uint32_t wired_pages;
103 	uint32_t speculative_pages;
104 	uint32_t filebacked_pages;
105 	uint32_t anonymous_pages;
106 	uint32_t compressor_pages;
107 	uint64_t compressions;
108 	uint64_t decompressions;
109 	uint64_t total_uncompressed_pages_in_compressor;
110 } memorystatus_kernel_stats_t;
111 
112 /*
113 ** This is a variable-length struct.
114 ** Allocate a buffer of the size returned by the sysctl, cast to a memorystatus_snapshot_t *
115 */
116 
117 typedef struct jetsam_snapshot_entry {
118 	pid_t    pid;
119 	char     name[MAXCOMLEN+1];
120 	int32_t  priority;
121 	uint32_t pages;
122 	uint32_t max_pages;
123 	uint32_t state;
124 	uint32_t killed;
125 	uint64_t user_data;
126 	uint8_t  uuid[16];
127 	uint32_t fds;
128 	uint32_t max_pages_lifetime;
129 	uint32_t purgeable_pages;
130 	struct timeval cpu_time;
131 } memorystatus_jetsam_snapshot_entry_t;
132 
133 typedef struct jetsam_snapshot {
134 	uint64_t snapshot_time;
135 	uint64_t notification_time;
136 	memorystatus_kernel_stats_t stats;
137 	size_t entry_count;
138 	memorystatus_jetsam_snapshot_entry_t entries[];
139 } memorystatus_jetsam_snapshot_t;
140 
141 typedef struct memorystatus_freeze_entry {
142  	int32_t pid;
143  	uint32_t flags;
144  	uint32_t pages;
145 } memorystatus_freeze_entry_t;
146 
147 /* TODO - deprecate; see <rdar://problem/12969599> */
148 #define kMaxSnapshotEntries 192
149 
150 /* State */
151 #define kMemorystatusSuspended        0x01
152 #define kMemorystatusFrozen           0x02
153 #define kMemorystatusWasThawed        0x04
154 #define kMemorystatusTracked          0x08
155 #define kMemorystatusSupportsIdleExit 0x10
156 #define kMemorystatusDirty            0x20
157 
158 /* Cause */
159 enum {
160 	kMemorystatusKilled = 1,
161 	kMemorystatusKilledHiwat,
162  	kMemorystatusKilledVnodes,
163   	kMemorystatusKilledVMPageShortage,
164   	kMemorystatusKilledVMThrashing,
165   	kMemorystatusKilledFCThrashing,
166   	kMemorystatusKilledPerProcessLimit,
167 	kMemorystatusKilledDiagnostic,
168 	kMemorystatusKilledIdleExit
169 };
170 
171 /* Temporary, to prevent the need for a linked submission of ReportCrash */
172 /* Remove when <rdar://problem/13210532> has been integrated */
173 enum {
174 	kMemorystatusKilledVM = kMemorystatusKilledVMPageShortage
175 };
176 
177 /* Memorystatus control */
178 #define MEMORYSTATUS_BUFFERSIZE_MAX 65536
179 
180 #ifndef KERNEL
181 int memorystatus_get_level(user_addr_t level);
182 int memorystatus_control(uint32_t command, int32_t pid, uint32_t flags, void *buffer, size_t buffersize);
183 #endif
184 
185 /* Commands */
186 #define MEMORYSTATUS_CMD_GET_PRIORITY_LIST            1
187 #define MEMORYSTATUS_CMD_SET_PRIORITY_PROPERTIES      2
188 #define MEMORYSTATUS_CMD_GET_JETSAM_SNAPSHOT          3
189 #define MEMORYSTATUS_CMD_GET_PRESSURE_STATUS          4
190 #define MEMORYSTATUS_CMD_SET_JETSAM_HIGH_WATER_MARK   5
191 #define MEMORYSTATUS_CMD_SET_JETSAM_TASK_LIMIT	      6
192 
193 /* Group Commands */
194 #define MEMORYSTATUS_CMD_GRP_SET_PROPERTIES           7
195 
196 #if PRIVATE
197 /* Test commands */
198 
199 /* Trigger forced jetsam */
200 #define MEMORYSTATUS_CMD_TEST_JETSAM                  1000
201 
202 /* Panic on jetsam options */
203 typedef struct memorystatus_jetsam_panic_options {
204 	uint32_t data;
205 	uint32_t mask;
206 } memorystatus_jetsam_panic_options_t;
207 
208 #define MEMORYSTATUS_CMD_SET_JETSAM_PANIC_BITS        1001
209 #endif /* PRIVATE */
210 
211 typedef struct memorystatus_priority_properties {
212 	int32_t  priority;
213 	uint64_t user_data;
214 } memorystatus_priority_properties_t;
215 
216 #ifdef XNU_KERNEL_PRIVATE
217 
218 /* p_memstat_state flags */
219 
220 #define P_MEMSTAT_SUSPENDED            0x00000001
221 #define P_MEMSTAT_FROZEN               0x00000002
222 #define P_MEMSTAT_NORECLAIM            0x00000004
223 #define P_MEMSTAT_ERROR                0x00000008
224 #define P_MEMSTAT_LOCKED               0x00000010
225 #define P_MEMSTAT_TERMINATED           0x00000020
226 #define P_MEMSTAT_NOTFIED              0x00000040
227 #define P_MEMSTAT_PRIORITYUPDATED      0x00000080
228 #define P_MEMSTAT_FOREGROUND           0x00000100
229 #define P_MEMSTAT_DIAG_SUSPENDED       0x00000200
230 #define P_MEMSTAT_PRIOR_THAW           0x00000400
231 #define P_MEMSTAT_MEMLIMIT_BACKGROUND  0x00000800 /* Task has a memory limit for when it's in the background. Used for a process' "high water mark".*/
232 #define P_MEMSTAT_INTERNAL             0x00001000
233 #define P_MEMSTAT_FATAL_MEMLIMIT       0x00002000 /* cross this limit and the process is killed. Types: system-wide default task memory limit and per-task custom memory limit. */
234 
235 extern void memorystatus_init(void) __attribute__((section("__TEXT, initcode")));
236 
237 extern int memorystatus_add(proc_t p, boolean_t locked);
238 extern int memorystatus_update(proc_t p, int priority, uint64_t user_data, boolean_t effective, boolean_t update_memlimit, int32_t memlimit, boolean_t memlimit_background, boolean_t is_fatal_limit);
239 extern int memorystatus_remove(proc_t p, boolean_t locked);
240 
241 extern int memorystatus_dirty_track(proc_t p, uint32_t pcontrol);
242 extern int memorystatus_dirty_set(proc_t p, boolean_t self, uint32_t pcontrol);
243 extern int memorystatus_dirty_get(proc_t p);
244 extern int memorystatus_dirty_clear(proc_t p, uint32_t pcontrol);
245 
246 extern int memorystatus_on_terminate(proc_t p);
247 
248 extern void memorystatus_on_suspend(proc_t p);
249 extern void memorystatus_on_resume(proc_t p);
250 extern void memorystatus_on_inactivity(proc_t p);
251 
252 extern void memorystatus_on_pageout_scan_end(void);
253 
254 /* Memorystatus kevent */
255 
256 void memorystatus_kevent_init(lck_grp_t *grp, lck_attr_t *attr);
257 
258 int memorystatus_knote_register(struct knote *kn);
259 void memorystatus_knote_unregister(struct knote *kn);
260 
261 #if CONFIG_JETSAM
262 
263 typedef enum memorystatus_policy {
264 	kPolicyDefault        = 0x0,
265 	kPolicyMoreFree       = 0x1,
266 	kPolicyDiagnoseAll    = 0x2,
267 	kPolicyDiagnoseFirst  = 0x4,
268 	kPolicyDiagnoseActive = (kPolicyDiagnoseAll | kPolicyDiagnoseFirst),
269 } memorystatus_policy_t;
270 
271 extern int memorystatus_jetsam_wakeup;
272 extern unsigned int memorystatus_jetsam_running;
273 
274 boolean_t memorystatus_kill_on_VM_page_shortage(boolean_t async);
275 boolean_t memorystatus_kill_on_VM_thrashing(boolean_t async);
276 boolean_t memorystatus_kill_on_FC_thrashing(boolean_t async);
277 boolean_t memorystatus_kill_on_vnode_limit(void);
278 
279 void memorystatus_on_ledger_footprint_exceeded(int warning, const int max_footprint_mb);
280 void jetsam_on_ledger_cpulimit_exceeded(void);
281 
282 void memorystatus_pages_update(unsigned int pages_avail);
283 
284 #else /* CONFIG_JETSAM */
285 
286 boolean_t memorystatus_idle_exit_from_VM(void);
287 
288 #endif /* !CONFIG_JETSAM */
289 
290 #ifdef CONFIG_FREEZE
291 
292 #define FREEZE_PAGES_MIN   ( 1 * 1024 * 1024 / PAGE_SIZE)
293 #define FREEZE_PAGES_MAX   (16 * 1024 * 1024 / PAGE_SIZE)
294 
295 #define FREEZE_SUSPENDED_THRESHOLD_LOW     2
296 #define FREEZE_SUSPENDED_THRESHOLD_DEFAULT 4
297 
298 #define FREEZE_DAILY_MB_MAX 	  1024
299 #define FREEZE_DAILY_PAGEOUTS_MAX (FREEZE_DAILY_MB_MAX * (1024 * 1024 / PAGE_SIZE))
300 
301 typedef struct throttle_interval_t {
302 	uint32_t mins;
303 	uint32_t burst_multiple;
304 	uint32_t pageouts;
305 	uint32_t max_pageouts;
306 	mach_timespec_t ts;
307 	boolean_t throttle;
308 } throttle_interval_t;
309 
310 extern boolean_t memorystatus_freeze_enabled;
311 extern int memorystatus_freeze_wakeup;
312 
313 extern void memorystatus_freeze_init(void) __attribute__((section("__TEXT, initcode")));
314 
315 #endif /* CONFIG_FREEZE */
316 
317 #if VM_PRESSURE_EVENTS
318 
319 extern kern_return_t memorystatus_update_vm_pressure(boolean_t);
320 
321 #if CONFIG_MEMORYSTATUS
322 extern int memorystatus_send_pressure_note(int pid);
323 extern boolean_t memorystatus_is_foreground_locked(proc_t p);
324 extern boolean_t memorystatus_bg_pressure_eligible(proc_t p);
325 #endif /* CONFIG_MEMORYSTATUS */
326 
327 #endif /* VM_PRESSURE_EVENTS */
328 
329 #endif /* XNU_KERNEL_PRIVATE */
330 
331 #endif /* SYS_MEMORYSTATUS_H */
332