]> git.saurik.com Git - apple/xnu.git/blob - bsd/sys/kern_memorystatus.h
xnu-4570.20.62.tar.gz
[apple/xnu.git] / bsd / sys / kern_memorystatus.h
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 #include <sys/proc.h>
35 #include <sys/param.h>
36 #include <mach_debug/zone_info.h>
37
38 #define MEMORYSTATUS_ENTITLEMENT "com.apple.private.memorystatus"
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 /* Keeping this around till all xnu_quick_tests can be moved away from it.*/
46 #define JETSAM_PRIORITY_AGING_BAND1 JETSAM_PRIORITY_IDLE_DEFERRED
47 #define JETSAM_PRIORITY_BACKGROUND_OPPORTUNISTIC 2
48 #define JETSAM_PRIORITY_AGING_BAND2 JETSAM_PRIORITY_BACKGROUND_OPPORTUNISTIC
49 #define JETSAM_PRIORITY_BACKGROUND 3
50 #define JETSAM_PRIORITY_ELEVATED_INACTIVE JETSAM_PRIORITY_BACKGROUND
51 #define JETSAM_PRIORITY_MAIL 4
52 #define JETSAM_PRIORITY_PHONE 5
53 #define JETSAM_PRIORITY_UI_SUPPORT 8
54 #define JETSAM_PRIORITY_FOREGROUND_SUPPORT 9
55 #define JETSAM_PRIORITY_FOREGROUND 10
56 #define JETSAM_PRIORITY_AUDIO_AND_ACCESSORY 12
57 #define JETSAM_PRIORITY_CONDUCTOR 13
58 #define JETSAM_PRIORITY_HOME 16
59 #define JETSAM_PRIORITY_EXECUTIVE 17
60 #define JETSAM_PRIORITY_IMPORTANT 18
61 #define JETSAM_PRIORITY_CRITICAL 19
62
63 #define JETSAM_PRIORITY_MAX 21
64
65 /* TODO - tune. This should probably be lower priority */
66 #define JETSAM_PRIORITY_DEFAULT 18
67 #define JETSAM_PRIORITY_TELEPHONY 19
68
69 /* Compatibility */
70 #define DEFAULT_JETSAM_PRIORITY 18
71
72 #define DEFERRED_IDLE_EXIT_TIME_SECS 10
73
74 #define KEV_MEMORYSTATUS_SUBCLASS 3
75
76 enum {
77 kMemorystatusLevelNote = 1,
78 kMemorystatusSnapshotNote = 2,
79 kMemorystatusFreezeNote = 3,
80 kMemorystatusPressureNote = 4
81 };
82
83 enum {
84 kMemorystatusLevelAny = -1,
85 kMemorystatusLevelNormal = 0,
86 kMemorystatusLevelWarning = 1,
87 kMemorystatusLevelUrgent = 2,
88 kMemorystatusLevelCritical = 3
89 };
90
91 typedef struct memorystatus_priority_entry {
92 pid_t pid;
93 int32_t priority;
94 uint64_t user_data;
95 int32_t limit; /* MB */
96 uint32_t state;
97 } memorystatus_priority_entry_t;
98
99 typedef struct memorystatus_kernel_stats {
100 uint32_t free_pages;
101 uint32_t active_pages;
102 uint32_t inactive_pages;
103 uint32_t throttled_pages;
104 uint32_t purgeable_pages;
105 uint32_t wired_pages;
106 uint32_t speculative_pages;
107 uint32_t filebacked_pages;
108 uint32_t anonymous_pages;
109 uint32_t compressor_pages;
110 uint64_t compressions;
111 uint64_t decompressions;
112 uint64_t total_uncompressed_pages_in_compressor;
113 uint64_t zone_map_size;
114 uint64_t zone_map_capacity;
115 uint64_t largest_zone_size;
116 char largest_zone_name[MACH_ZONE_NAME_MAX_LEN];
117 } memorystatus_kernel_stats_t;
118
119 /*
120 ** This is a variable-length struct.
121 ** Allocate a buffer of the size returned by the sysctl, cast to a memorystatus_snapshot_t *
122 */
123
124 typedef struct jetsam_snapshot_entry {
125 pid_t pid;
126 char name[(2*MAXCOMLEN)+1];
127 int32_t priority;
128 uint32_t state;
129 uint32_t fds;
130 uint8_t uuid[16];
131 uint64_t user_data;
132 uint64_t killed;
133 uint64_t pages;
134 uint64_t max_pages;
135 uint64_t max_pages_lifetime;
136 uint64_t purgeable_pages;
137 uint64_t jse_internal_pages;
138 uint64_t jse_internal_compressed_pages;
139 uint64_t jse_purgeable_nonvolatile_pages;
140 uint64_t jse_purgeable_nonvolatile_compressed_pages;
141 uint64_t jse_alternate_accounting_pages;
142 uint64_t jse_alternate_accounting_compressed_pages;
143 uint64_t jse_iokit_mapped_pages;
144 uint64_t jse_page_table_pages;
145 uint64_t jse_memory_region_count;
146 uint64_t jse_gencount; /* memorystatus_thread generation counter */
147 uint64_t jse_starttime; /* absolute time when process starts */
148 uint64_t jse_killtime; /* absolute time when jetsam chooses to kill a process */
149 uint64_t jse_idle_delta; /* time spent in idle band */
150 uint64_t jse_coalition_jetsam_id; /* we only expose coalition id for COALITION_TYPE_JETSAM */
151 struct timeval cpu_time;
152 } memorystatus_jetsam_snapshot_entry_t;
153
154 typedef struct jetsam_snapshot {
155 uint64_t snapshot_time; /* absolute time snapshot was initialized */
156 uint64_t notification_time; /* absolute time snapshot was consumed */
157 uint64_t js_gencount; /* memorystatus_thread generation counter */
158 memorystatus_kernel_stats_t stats; /* system stat when snapshot is initialized */
159 size_t entry_count;
160 memorystatus_jetsam_snapshot_entry_t entries[];
161 } memorystatus_jetsam_snapshot_t;
162
163 typedef struct memorystatus_freeze_entry {
164 int32_t pid;
165 uint32_t flags;
166 uint32_t pages;
167 } memorystatus_freeze_entry_t;
168
169 /* TODO - deprecate; see <rdar://problem/12969599> */
170 #define kMaxSnapshotEntries 192
171
172 /* State */
173 #define kMemorystatusSuspended 0x01
174 #define kMemorystatusFrozen 0x02
175 #define kMemorystatusWasThawed 0x04
176 #define kMemorystatusTracked 0x08
177 #define kMemorystatusSupportsIdleExit 0x10
178 #define kMemorystatusDirty 0x20
179
180 /*
181 * Jetsam exit reason definitions - related to memorystatus
182 *
183 * When adding new exit reasons also update:
184 * JETSAM_REASON_MEMORYSTATUS_MAX
185 * kMemorystatusKilled... Cause enum
186 * memorystatus_kill_cause_name[]
187 */
188 #define JETSAM_REASON_INVALID 0
189 #define JETSAM_REASON_GENERIC 1
190 #define JETSAM_REASON_MEMORY_HIGHWATER 2
191 #define JETSAM_REASON_VNODE 3
192 #define JETSAM_REASON_MEMORY_VMPAGESHORTAGE 4
193 #define JETSAM_REASON_MEMORY_VMTHRASHING 5
194 #define JETSAM_REASON_MEMORY_FCTHRASHING 6
195 #define JETSAM_REASON_MEMORY_PERPROCESSLIMIT 7
196 #define JETSAM_REASON_MEMORY_DIAGNOSTIC 8
197 #define JETSAM_REASON_MEMORY_IDLE_EXIT 9
198 #define JETSAM_REASON_ZONE_MAP_EXHAUSTION 10
199
200 #define JETSAM_REASON_MEMORYSTATUS_MAX JETSAM_REASON_ZONE_MAP_EXHAUSTION
201
202 /*
203 * Jetsam exit reason definitions - not related to memorystatus
204 */
205 #define JETSAM_REASON_CPULIMIT 100
206
207 /* Cause */
208 enum {
209 kMemorystatusInvalid = JETSAM_REASON_INVALID,
210 kMemorystatusKilled = JETSAM_REASON_GENERIC,
211 kMemorystatusKilledHiwat = JETSAM_REASON_MEMORY_HIGHWATER,
212 kMemorystatusKilledVnodes = JETSAM_REASON_VNODE,
213 kMemorystatusKilledVMPageShortage = JETSAM_REASON_MEMORY_VMPAGESHORTAGE,
214 kMemorystatusKilledVMThrashing = JETSAM_REASON_MEMORY_VMTHRASHING,
215 kMemorystatusKilledFCThrashing = JETSAM_REASON_MEMORY_FCTHRASHING,
216 kMemorystatusKilledPerProcessLimit = JETSAM_REASON_MEMORY_PERPROCESSLIMIT,
217 kMemorystatusKilledDiagnostic = JETSAM_REASON_MEMORY_DIAGNOSTIC,
218 kMemorystatusKilledIdleExit = JETSAM_REASON_MEMORY_IDLE_EXIT,
219 kMemorystatusKilledZoneMapExhaustion = JETSAM_REASON_ZONE_MAP_EXHAUSTION
220 };
221
222 /* Memorystatus control */
223 #define MEMORYSTATUS_BUFFERSIZE_MAX 65536
224
225 #ifndef KERNEL
226 int memorystatus_get_level(user_addr_t level);
227 int memorystatus_control(uint32_t command, int32_t pid, uint32_t flags, void *buffer, size_t buffersize);
228 #endif
229
230 /* Commands */
231 #define MEMORYSTATUS_CMD_GET_PRIORITY_LIST 1
232 #define MEMORYSTATUS_CMD_SET_PRIORITY_PROPERTIES 2
233 #define MEMORYSTATUS_CMD_GET_JETSAM_SNAPSHOT 3
234 #define MEMORYSTATUS_CMD_GET_PRESSURE_STATUS 4
235 #define MEMORYSTATUS_CMD_SET_JETSAM_HIGH_WATER_MARK 5 /* Set active memory limit = inactive memory limit, both non-fatal */
236 #define MEMORYSTATUS_CMD_SET_JETSAM_TASK_LIMIT 6 /* Set active memory limit = inactive memory limit, both fatal */
237 #define MEMORYSTATUS_CMD_SET_MEMLIMIT_PROPERTIES 7 /* Set memory limits plus attributes independently */
238 #define MEMORYSTATUS_CMD_GET_MEMLIMIT_PROPERTIES 8 /* Get memory limits plus attributes */
239 #define MEMORYSTATUS_CMD_PRIVILEGED_LISTENER_ENABLE 9 /* Set the task's status as a privileged listener w.r.t memory notifications */
240 #define MEMORYSTATUS_CMD_PRIVILEGED_LISTENER_DISABLE 10 /* Reset the task's status as a privileged listener w.r.t memory notifications */
241 #define MEMORYSTATUS_CMD_AGGRESSIVE_JETSAM_LENIENT_MODE_ENABLE 11 /* Enable the 'lenient' mode for aggressive jetsam. See comments in kern_memorystatus.c near the top. */
242 #define MEMORYSTATUS_CMD_AGGRESSIVE_JETSAM_LENIENT_MODE_DISABLE 12 /* Disable the 'lenient' mode for aggressive jetsam. */
243 #define MEMORYSTATUS_CMD_GET_MEMLIMIT_EXCESS 13 /* Compute how much a process's phys_footprint exceeds inactive memory limit */
244 #define MEMORYSTATUS_CMD_ELEVATED_INACTIVEJETSAMPRIORITY_ENABLE 14
245 #define MEMORYSTATUS_CMD_ELEVATED_INACTIVEJETSAMPRIORITY_DISABLE 15
246
247 /* Commands that act on a group of processes */
248 #define MEMORYSTATUS_CMD_GRP_SET_PROPERTIES 100
249
250 #if PRIVATE
251 /* Test commands */
252
253 /* Trigger forced jetsam */
254 #define MEMORYSTATUS_CMD_TEST_JETSAM 1000
255 #define MEMORYSTATUS_CMD_TEST_JETSAM_SORT 1001
256
257 /* Panic on jetsam options */
258 typedef struct memorystatus_jetsam_panic_options {
259 uint32_t data;
260 uint32_t mask;
261 } memorystatus_jetsam_panic_options_t;
262
263 #define MEMORYSTATUS_CMD_SET_JETSAM_PANIC_BITS 1002
264
265 /* Select priority band sort order */
266 #define JETSAM_SORT_NOSORT 0
267 #define JETSAM_SORT_DEFAULT 1
268
269 #endif /* PRIVATE */
270
271 /*
272 * For use with memorystatus_control:
273 * MEMORYSTATUS_CMD_GET_JETSAM_SNAPSHOT
274 *
275 * A jetsam snapshot is initialized when a non-idle
276 * jetsam event occurs. The data is held in the
277 * buffer until it is reaped. This is the default
278 * behavior.
279 *
280 * Flags change the default behavior:
281 * Demand mode - this is an on_demand snapshot,
282 * meaning data is populated upon request.
283 *
284 * Boot mode - this is a snapshot of
285 * memstats collected before loading the
286 * init program. Once collected, these
287 * stats do not change. In this mode,
288 * the snapshot entry_count is always 0.
289 *
290 * Snapshots are inherently racey between request
291 * for buffer size and actual data compilation.
292 */
293
294 /* Flags */
295 #define MEMORYSTATUS_SNAPSHOT_ON_DEMAND 0x1 /* A populated snapshot buffer is returned on demand */
296 #define MEMORYSTATUS_SNAPSHOT_AT_BOOT 0x2 /* Returns a snapshot with memstats collected at boot */
297
298
299 /*
300 * For use with memorystatus_control:
301 * MEMORYSTATUS_CMD_SET_PRIORITY_PROPERTIES
302 */
303 typedef struct memorystatus_priority_properties {
304 int32_t priority;
305 uint64_t user_data;
306 } memorystatus_priority_properties_t;
307
308 /*
309 * For use with memorystatus_control:
310 * MEMORYSTATUS_CMD_SET_MEMLIMIT_PROPERTIES
311 * MEMORYSTATUS_CMD_GET_MEMLIMIT_PROPERTIES
312 */
313 typedef struct memorystatus_memlimit_properties {
314 int32_t memlimit_active; /* jetsam memory limit (in MB) when process is active */
315 uint32_t memlimit_active_attr;
316 int32_t memlimit_inactive; /* jetsam memory limit (in MB) when process is inactive */
317 uint32_t memlimit_inactive_attr;
318 } memorystatus_memlimit_properties_t;
319
320 #define MEMORYSTATUS_MEMLIMIT_ATTR_FATAL 0x1 /* if set, exceeding the memlimit is fatal */
321
322 #ifdef XNU_KERNEL_PRIVATE
323
324 /*
325 * A process will be killed immediately if it crosses a memory limit marked as fatal.
326 * Fatal limit types are the
327 * - default system-wide task limit
328 * - per-task custom memory limit
329 *
330 * A process with a non-fatal memory limit can exceed that limit, but becomes an early
331 * candidate for jetsam when the device is under memory pressure.
332 * Non-fatal limit types are the
333 * - high-water-mark limit
334 *
335 * Processes that opt into dirty tracking are evaluated
336 * based on clean vs dirty state.
337 * dirty ==> active
338 * clean ==> inactive
339 *
340 * Processes that do not opt into dirty tracking are
341 * evalulated based on priority level.
342 * Foreground or above ==> active
343 * Below Foreground ==> inactive
344 */
345
346 /*
347 * p_memstat_state flag holds
348 * - in kernel process state and memlimit state
349 */
350
351 #define P_MEMSTAT_SUSPENDED 0x00000001
352 #define P_MEMSTAT_FROZEN 0x00000002
353 #define P_MEMSTAT_NORECLAIM 0x00000004
354 #define P_MEMSTAT_ERROR 0x00000008
355 #define P_MEMSTAT_LOCKED 0x00000010
356 #define P_MEMSTAT_TERMINATED 0x00000020
357 #define P_MEMSTAT_NOTFIED 0x00000040
358 #define P_MEMSTAT_PRIORITYUPDATED 0x00000080
359 #define P_MEMSTAT_FOREGROUND 0x00000100
360 #define P_MEMSTAT_DIAG_SUSPENDED 0x00000200
361 #define P_MEMSTAT_PRIOR_THAW 0x00000400
362 /* unused 0x00000800 */
363 #define P_MEMSTAT_INTERNAL 0x00001000
364 #define P_MEMSTAT_FATAL_MEMLIMIT 0x00002000 /* current fatal state of the process's memlimit */
365 #define P_MEMSTAT_MEMLIMIT_ACTIVE_FATAL 0x00004000 /* if set, exceeding limit is fatal when the process is active */
366 #define P_MEMSTAT_MEMLIMIT_INACTIVE_FATAL 0x00008000 /* if set, exceeding limit is fatal when the process is inactive */
367 #define P_MEMSTAT_USE_ELEVATED_INACTIVE_BAND 0x00010000 /* if set, the process will go into this band & stay there when in the background instead
368 of the aging bands and/or the IDLE band. */
369
370 extern void memorystatus_init(void) __attribute__((section("__TEXT, initcode")));
371
372 extern void memorystatus_init_at_boot_snapshot(void);
373
374 extern int memorystatus_add(proc_t p, boolean_t locked);
375 extern int memorystatus_update(proc_t p, int priority, uint64_t user_data, boolean_t effective,
376 boolean_t update_memlimit, int32_t memlimit_active, boolean_t memlimit_active_is_fatal,
377 int32_t memlimit_inactive, boolean_t memlimit_inactive_is_fatal);
378
379 extern int memorystatus_remove(proc_t p, boolean_t locked);
380
381 int memorystatus_update_inactive_jetsam_priority_band(pid_t pid, uint32_t opflags, boolean_t effective_now);
382
383
384 extern int memorystatus_dirty_track(proc_t p, uint32_t pcontrol);
385 extern int memorystatus_dirty_set(proc_t p, boolean_t self, uint32_t pcontrol);
386 extern int memorystatus_dirty_get(proc_t p);
387 extern int memorystatus_dirty_clear(proc_t p, uint32_t pcontrol);
388
389 extern int memorystatus_on_terminate(proc_t p);
390
391 extern void memorystatus_on_suspend(proc_t p);
392 extern void memorystatus_on_resume(proc_t p);
393 extern void memorystatus_on_inactivity(proc_t p);
394
395 extern void memorystatus_on_pageout_scan_end(void);
396
397 /* Memorystatus kevent */
398
399 void memorystatus_kevent_init(lck_grp_t *grp, lck_attr_t *attr);
400
401 int memorystatus_knote_register(struct knote *kn);
402 void memorystatus_knote_unregister(struct knote *kn);
403
404 #if CONFIG_MEMORYSTATUS
405 void memorystatus_log_exception(const int max_footprint_mb, boolean_t memlimit_is_active, boolean_t memlimit_is_fatal);
406 void memorystatus_on_ledger_footprint_exceeded(int warning, boolean_t memlimit_is_active, boolean_t memlimit_is_fatal);
407 void proc_memstat_terminated(proc_t p, boolean_t set);
408 boolean_t memorystatus_proc_is_dirty_unsafe(void *v);
409 #endif /* CONFIG_MEMORYSTATUS */
410
411 int memorystatus_get_pressure_status_kdp(void);
412
413 #if CONFIG_JETSAM
414
415 typedef enum memorystatus_policy {
416 kPolicyDefault = 0x0,
417 kPolicyMoreFree = 0x1,
418 kPolicyDiagnoseAll = 0x2,
419 kPolicyDiagnoseFirst = 0x4,
420 kPolicyDiagnoseActive = (kPolicyDiagnoseAll | kPolicyDiagnoseFirst),
421 } memorystatus_policy_t;
422
423 extern int memorystatus_jetsam_wakeup;
424 extern unsigned int memorystatus_jetsam_running;
425
426 boolean_t memorystatus_kill_on_VM_page_shortage(boolean_t async);
427 boolean_t memorystatus_kill_on_FC_thrashing(boolean_t async);
428 boolean_t memorystatus_kill_on_vnode_limit(void);
429
430 void jetsam_on_ledger_cpulimit_exceeded(void);
431
432 #endif /* CONFIG_JETSAM */
433
434 boolean_t memorystatus_kill_on_zone_map_exhaustion(pid_t pid);
435 boolean_t memorystatus_kill_on_VM_thrashing(boolean_t async);
436 void memorystatus_pages_update(unsigned int pages_avail);
437
438 boolean_t memorystatus_idle_exit_from_VM(void);
439
440
441 #ifdef CONFIG_FREEZE
442
443 #define FREEZE_PAGES_MIN ( 1 * 1024 * 1024 / PAGE_SIZE)
444 #define FREEZE_PAGES_MAX (16 * 1024 * 1024 / PAGE_SIZE)
445
446 #define FREEZE_SUSPENDED_THRESHOLD_LOW 2
447 #define FREEZE_SUSPENDED_THRESHOLD_DEFAULT 4
448
449 #define FREEZE_DAILY_MB_MAX_DEFAULT 1024
450
451 typedef struct throttle_interval_t {
452 uint32_t mins;
453 uint32_t burst_multiple;
454 uint32_t pageouts;
455 uint32_t max_pageouts;
456 mach_timespec_t ts;
457 boolean_t throttle;
458 } throttle_interval_t;
459
460 extern boolean_t memorystatus_freeze_enabled;
461 extern int memorystatus_freeze_wakeup;
462
463 extern void memorystatus_freeze_init(void) __attribute__((section("__TEXT, initcode")));
464 extern int memorystatus_freeze_process_sync(proc_t p);
465 #endif /* CONFIG_FREEZE */
466
467 #if VM_PRESSURE_EVENTS
468
469 extern kern_return_t memorystatus_update_vm_pressure(boolean_t);
470
471 #if CONFIG_MEMORYSTATUS
472 /* Flags */
473 extern int memorystatus_low_mem_privileged_listener(uint32_t op_flags);
474 extern int memorystatus_send_pressure_note(int pid);
475 extern boolean_t memorystatus_is_foreground_locked(proc_t p);
476 extern boolean_t memorystatus_bg_pressure_eligible(proc_t p);
477 #endif /* CONFIG_MEMORYSTATUS */
478
479 #endif /* VM_PRESSURE_EVENTS */
480
481 #endif /* XNU_KERNEL_PRIVATE */
482
483 #endif /* SYS_MEMORYSTATUS_H */