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
37#define DEFAULT_JETSAM_PRIORITY -100
38
39enum {
40	kMemorystatusFlagsFrontmost =         (1 << 0),
41	kMemorystatusFlagsKilled =            (1 << 1),
42	kMemorystatusFlagsKilledHiwat =       (1 << 2),
43 	kMemorystatusFlagsFrozen     =        (1 << 3),
44 	kMemorystatusFlagsKilledVnodes =      (1 << 4),
45 	kMemorystatusFlagsKilledSwap =        (1 << 5),
46  	kMemorystatusFlagsThawed =            (1 << 6),
47  	kMemorystatusFlagsKilledVM =          (1 << 7),
48	kMemorystatusFlagsSuspForDiagnosis =  (1 << 8),
49	kMemorystatusFlagsActive =            (1 << 9),
50	kMemorystatusFlagsSupportsIdleExit =  (1 << 10),
51	kMemorystatusFlagsDirty =             (1 << 11)
52};
53
54#if TARGET_OS_EMBEDDED || CONFIG_EMBEDDED
55
56/*
57 * Define Memory Status event subclass.
58 * Subclass of KEV_SYSTEM_CLASS
59 */
60
61/*!
62	@defined KEV_MEMORYSTATUS_SUBCLASS
63	@discussion The kernel event subclass for memory status events.
64*/
65#define KEV_MEMORYSTATUS_SUBCLASS        3
66
67enum {
68	kMemorystatusLevelNote = 1,
69	kMemorystatusSnapshotNote = 2,
70	kMemorystatusFreezeNote = 3,
71	kMemorystatusPressureNote = 4
72};
73
74enum {
75	kMemorystatusLevelAny = -1,
76	kMemorystatusLevelNormal = 0,
77	kMemorystatusLevelWarning = 1,
78	kMemorystatusLevelUrgent = 2,
79	kMemorystatusLevelCritical = 3
80};
81
82typedef struct memorystatus_priority_entry {
83	pid_t pid;
84	uint32_t flags;
85	int32_t hiwat_pages;
86	int32_t priority;
87	int32_t reserved;
88	int32_t reserved2;
89} memorystatus_priority_entry_t;
90
91/*
92** how many processes to snapshot
93*/
94#define kMaxSnapshotEntries 128
95
96typedef 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} memorystatus_kernel_stats_t;
104
105/*
106** This is a variable-length struct.
107** Allocate a buffer of the size returned by the sysctl, cast to a memorystatus_snapshot_t *
108*/
109
110typedef struct jetsam_snapshot_entry {
111	pid_t pid;
112	char name[MAXCOMLEN+1];
113	int32_t priority;
114	uint32_t pages;
115	uint32_t flags;
116	uint8_t uuid[16];
117} memorystatus_jetsam_snapshot_entry_t;
118
119typedef struct jetsam_snapshot {
120	uint64_t snapshot_time;
121	uint64_t notification_time;
122	memorystatus_kernel_stats_t stats;
123	size_t entry_count;
124	memorystatus_jetsam_snapshot_entry_t entries[1];
125} memorystatus_jetsam_snapshot_t;
126
127typedef memorystatus_priority_entry_t 		jetsam_priority_entry_t;
128typedef memorystatus_jetsam_snapshot_t 		jetsam_snapshot_t;
129typedef memorystatus_jetsam_snapshot_entry_t 	jetsam_snapshot_entry_t;
130
131#define kMemoryStatusLevelNote 		kMemorystatusLevelNote
132#define kMemoryStatusSnapshotNote	kMemorystatusSnapshotNote
133#define kMemoryStatusFreezeNote		kMemorystatusFreezeNote
134#define kMemoryStatusPressureNote	kMemorystatusPressureNote
135
136typedef struct memorystatus_freeze_entry {
137 	int32_t pid;
138 	uint32_t flags;
139 	uint32_t pages;
140} memorystatus_freeze_entry_t;
141
142#endif /* TARGET_OS_EMBEDDED */
143
144#ifdef XNU_KERNEL_PRIVATE
145
146/* General tunables */
147
148#define DELTA_PERCENT                    5
149#define CRITICAL_PERCENT                 5
150#define HIGHWATER_PERCENT               10
151#define PRESSURE_PERCENT                15
152#define FREEZE_PERCENT                  50
153
154#define POLICY_MORE_FREE_OFFSET_PERCENT    5
155#define POLICY_DIAGNOSTIC_OFFSET_PERCENT   5
156
157#define IDLE_EXIT_TIME_SECS 			10
158
159enum {
160	kProcessSuspended             = (1 << 0),
161	kProcessFrozen                = (1 << 1),
162	kProcessNoReclaimWorth        = (1 << 2),
163	kProcessIgnored               = (1 << 3),
164	kProcessLocked                = (1 << 4),
165	kProcessKilled                =  (1 << 5),
166	kProcessNotifiedForPressure   = (1 << 6),
167	kProcessPriorityUpdated       = (1 << 7),
168	kProcessActive                = (1 << 8),
169	kProcessForeground            = (1 << 9),
170	kProcessSuspendedForDiag      = (1 << 10),
171	kProcessSupportsIdleExit      = (1 << 11),
172	kProcessDirty                 = (1 << 12),
173	kProcessIgnoreIdleExit        = (1 << 13)
174};
175
176typedef struct memorystatus_node {
177	TAILQ_ENTRY(memorystatus_node) link;
178	pid_t pid;
179	int32_t priority;
180	uint32_t state;
181#if CONFIG_JETSAM
182	int32_t hiwat_pages;
183#endif
184#if CONFIG_FREEZE
185	uint32_t resident_pages;
186#endif
187	uint64_t clean_time;
188} memorystatus_node;
189
190extern int memorystatus_wakeup;
191extern unsigned int memorystatus_running;
192
193extern unsigned int memorystatus_available_pages;
194extern unsigned int memorystatus_available_pages_critical;
195extern unsigned int memorystatus_level;
196extern unsigned int memorystatus_delta;
197
198extern void memorystatus_init(void) __attribute__((section("__TEXT, initcode")));
199
200extern kern_return_t memorystatus_list_add(int pid, int priority, int high_water_mark);
201extern kern_return_t memorystatus_list_change(boolean_t effective, int pid, int priority, int state_flags, int high_water_mark);
202extern kern_return_t memorystatus_list_remove(int pid);
203
204extern kern_return_t memorystatus_on_track_dirty(int pid, boolean_t track);
205extern kern_return_t memorystatus_on_dirty(int pid, boolean_t dirty);
206
207extern void memorystatus_on_suspend(int pid);
208extern void memorystatus_on_resume(int pid);
209extern void memorystatus_on_inactivity(int pid);
210
211#if CONFIG_JETSAM
212
213typedef enum memorystatus_policy_t {
214	kPolicyDefault        = 0x0,
215	kPolicyMoreFree       = 0x1,
216	kPolicyDiagnoseAll    = 0x2,
217	kPolicyDiagnoseFirst  = 0x4,
218	kPolicyDiagnoseActive = (kPolicyDiagnoseAll | kPolicyDiagnoseFirst),
219} memorystatus_policy_t;
220
221extern int memorystatus_jetsam_wakeup;
222extern unsigned int memorystatus_jetsam_running;
223
224extern int memorystatus_kill_top_proc(boolean_t any, uint32_t reason);
225extern int memorystatus_kill_top_proc_from_VM(void);
226
227extern void memorystatus_update(unsigned int pages_avail);
228
229#if VM_PRESSURE_EVENTS
230
231#define MEMORYSTATUS_SUSPENDED_THRESHOLD  4
232
233extern int memorystatus_request_vm_pressure_candidate(void);
234extern void memorystatus_send_pressure_note(int pid);
235
236#endif /* VM_PRESSURE_EVENTS */
237
238#endif /* CONFIG_JETSAM */
239
240#ifdef CONFIG_FREEZE
241
242#define FREEZE_PAGES_MIN   ( 1 * 1024 * 1024 / PAGE_SIZE)
243#define FREEZE_PAGES_MAX   (16 * 1024 * 1024 / PAGE_SIZE)
244
245#define FREEZE_SUSPENDED_THRESHOLD_LOW     2
246#define FREEZE_SUSPENDED_THRESHOLD_DEFAULT 4
247
248#define FREEZE_DAILY_MB_MAX 	  1024
249#define FREEZE_DAILY_PAGEOUTS_MAX (FREEZE_DAILY_MB_MAX * (1024 * 1024 / PAGE_SIZE))
250
251typedef struct throttle_interval_t {
252	uint32_t mins;
253	uint32_t burst_multiple;
254	uint32_t pageouts;
255	uint32_t max_pageouts;
256	mach_timespec_t ts;
257	boolean_t throttle;
258} throttle_interval_t;
259
260extern boolean_t memorystatus_freeze_enabled;
261extern int memorystatus_freeze_wakeup;
262
263extern void memorystatus_freeze_init(void) __attribute__((section("__TEXT, initcode")));
264
265#endif /* CONFIG_FREEZE */
266
267#endif /* XNU_KERNEL_PRIVATE */
268
269#endif /* SYS_MEMORYSTATUS_H */
270