]>
Commit | Line | Data |
---|---|---|
1c79356b | 1 | /* |
91447636 | 2 | * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. |
1c79356b | 3 | * |
2d21ac55 | 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
1c79356b | 5 | * |
2d21ac55 A |
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. | |
8f6c56a5 | 14 | * |
2d21ac55 A |
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 | |
8f6c56a5 A |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
2d21ac55 A |
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. | |
8f6c56a5 | 25 | * |
2d21ac55 | 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
1c79356b A |
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 Software.Distribution@CS.CMU.EDU | |
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: zalloc.h | |
60 | * Author: Avadis Tevanian, Jr. | |
61 | * Date: 1985 | |
62 | * | |
63 | */ | |
64 | ||
91447636 A |
65 | #ifdef KERNEL_PRIVATE |
66 | ||
1c79356b A |
67 | #ifndef _KERN_ZALLOC_H_ |
68 | #define _KERN_ZALLOC_H_ | |
69 | ||
70 | #include <mach/machine/vm_types.h> | |
71 | #include <kern/kern_types.h> | |
91447636 | 72 | #include <sys/cdefs.h> |
9bccf70c A |
73 | |
74 | #ifdef MACH_KERNEL_PRIVATE | |
75 | ||
1c79356b A |
76 | #include <zone_debug.h> |
77 | #include <mach_kdb.h> | |
78 | #include <kern/lock.h> | |
2d21ac55 | 79 | #include <kern/locks.h> |
1c79356b | 80 | #include <kern/queue.h> |
0b4e3aa0 | 81 | #include <kern/call_entry.h> |
1c79356b A |
82 | |
83 | /* | |
84 | * A zone is a collection of fixed size blocks for which there | |
85 | * is fast allocation/deallocation access. Kernel routines can | |
86 | * use zones to manage data structures dynamically, creating a zone | |
87 | * for each type of data structure to be managed. | |
88 | * | |
89 | */ | |
90 | ||
91 | struct zone { | |
92 | int count; /* Number of elements used now */ | |
93 | vm_offset_t free_elements; | |
2d21ac55 A |
94 | decl_lck_mtx_data(,lock) /* zone lock */ |
95 | lck_mtx_ext_t lock_ext; /* placeholder for indirect mutex */ | |
96 | lck_attr_t lock_attr; /* zone lock attribute */ | |
97 | lck_grp_t lock_grp; /* zone lock group */ | |
98 | lck_grp_attr_t lock_grp_attr; /* zone lock group attribute */ | |
1c79356b A |
99 | vm_size_t cur_size; /* current memory utilization */ |
100 | vm_size_t max_size; /* how large can this zone grow */ | |
101 | vm_size_t elem_size; /* size of an element */ | |
102 | vm_size_t alloc_size; /* size used for more memory */ | |
6d2010ae | 103 | uint64_t sum_count; /* count of allocs (life of zone) */ |
1c79356b A |
104 | unsigned int |
105 | /* boolean_t */ exhaustible :1, /* (F) merely return if empty? */ | |
106 | /* boolean_t */ collectable :1, /* (F) garbage collect empty pages */ | |
107 | /* boolean_t */ expandable :1, /* (T) expand zone (with message)? */ | |
108 | /* boolean_t */ allows_foreign :1,/* (F) allow non-zalloc space */ | |
109 | /* boolean_t */ doing_alloc :1, /* is zone expanding now? */ | |
0b4e3aa0 | 110 | /* boolean_t */ waiting :1, /* is thread waiting for expansion? */ |
a3d08fcd | 111 | /* boolean_t */ async_pending :1, /* asynchronous allocation pending? */ |
6d2010ae A |
112 | #if CONFIG_ZLEAKS |
113 | /* boolean_t */ zleak_on :1, /* Are we collecting allocation information? */ | |
114 | #endif /* ZONE_DEBUG */ | |
115 | /* boolean_t */ caller_acct: 1, /* do we account allocation/free to the caller? */ | |
0b4c1975 | 116 | /* boolean_t */ doing_gc :1, /* garbage collect in progress? */ |
7ddcb079 A |
117 | /* boolean_t */ noencrypt :1, |
118 | /* boolean_t */ no_callout:1, | |
119 | /* boolean_t */ async_prio_refill:1; | |
6d2010ae | 120 | int index; /* index into zone_info arrays for this zone */ |
1c79356b | 121 | struct zone * next_zone; /* Link for all-zones list */ |
0b4e3aa0 | 122 | call_entry_data_t call_async_alloc; /* callout for asynchronous alloc */ |
91447636 | 123 | const char *zone_name; /* a name for the zone */ |
1c79356b A |
124 | #if ZONE_DEBUG |
125 | queue_head_t active_zones; /* active elements */ | |
126 | #endif /* ZONE_DEBUG */ | |
6d2010ae A |
127 | |
128 | #if CONFIG_ZLEAKS | |
129 | uint32_t num_allocs; /* alloc stats for zleak benchmarks */ | |
130 | uint32_t num_frees; /* free stats for zleak benchmarks */ | |
131 | uint32_t zleak_capture; /* per-zone counter for capturing every N allocations */ | |
132 | #endif /* CONFIG_ZLEAKS */ | |
7ddcb079 A |
133 | vm_size_t prio_refill_watermark; |
134 | thread_t zone_replenish_thread; | |
1c79356b A |
135 | }; |
136 | ||
6d2010ae A |
137 | /* |
138 | * structure for tracking zone usage | |
139 | * Used either one per task/thread for all zones or <per-task,per-zone>. | |
140 | */ | |
141 | typedef struct zinfo_usage_store_t { | |
142 | /* These fields may be updated atomically, and so must be 8 byte aligned */ | |
143 | uint64_t alloc __attribute__((aligned(8))); /* allocation counter */ | |
144 | uint64_t free __attribute__((aligned(8))); /* free counter */ | |
145 | } zinfo_usage_store_t; | |
146 | typedef zinfo_usage_store_t *zinfo_usage_t; | |
147 | ||
1c79356b | 148 | extern void zone_gc(void); |
b0d623f7 | 149 | extern void consider_zone_gc(boolean_t); |
1c79356b A |
150 | |
151 | /* Steal memory for zone module */ | |
152 | extern void zone_steal_memory(void); | |
153 | ||
154 | /* Bootstrap zone module (create zone zone) */ | |
2d21ac55 | 155 | extern void zone_bootstrap(void) __attribute__((section("__TEXT, initcode"))); |
1c79356b A |
156 | |
157 | /* Init zone module */ | |
91447636 | 158 | extern void zone_init( |
2d21ac55 | 159 | vm_size_t map_size) __attribute__((section("__TEXT, initcode"))); |
1c79356b | 160 | |
6d2010ae A |
161 | /* Handle per-task zone info */ |
162 | extern void zinfo_task_init(task_t task); | |
163 | extern void zinfo_task_free(task_t task); | |
164 | ||
165 | ||
91447636 | 166 | /* Stack use statistics */ |
6d2010ae | 167 | extern void stack_fake_zone_init(int zone_index); |
91447636 A |
168 | extern void stack_fake_zone_info( |
169 | int *count, | |
170 | vm_size_t *cur_size, | |
171 | vm_size_t *max_size, | |
172 | vm_size_t *elem_size, | |
173 | vm_size_t *alloc_size, | |
6d2010ae | 174 | uint64_t *sum_size, |
91447636 | 175 | int *collectable, |
6d2010ae A |
176 | int *exhaustable, |
177 | int *caller_acct); | |
1c79356b | 178 | |
91447636 | 179 | #if ZONE_DEBUG |
1c79356b | 180 | |
91447636 | 181 | #if MACH_KDB |
1c79356b | 182 | |
91447636 A |
183 | extern void * next_element( |
184 | zone_t z, | |
185 | void *elt); | |
1c79356b | 186 | |
91447636 A |
187 | extern void * first_element( |
188 | zone_t z); | |
1c79356b | 189 | |
91447636 A |
190 | #endif /* MACH_KDB */ |
191 | ||
192 | extern void zone_debug_enable( | |
193 | zone_t z); | |
194 | ||
195 | extern void zone_debug_disable( | |
196 | zone_t z); | |
197 | ||
198 | #endif /* ZONE_DEBUG */ | |
199 | ||
200 | #endif /* MACH_KERNEL_PRIVATE */ | |
201 | ||
202 | __BEGIN_DECLS | |
203 | ||
204 | #ifdef XNU_KERNEL_PRIVATE | |
205 | ||
206 | /* Allocate from zone */ | |
207 | extern void * zalloc( | |
208 | zone_t zone); | |
1c79356b A |
209 | |
210 | /* Free zone element */ | |
211 | extern void zfree( | |
91447636 A |
212 | zone_t zone, |
213 | void *elem); | |
214 | ||
215 | /* Create zone */ | |
216 | extern zone_t zinit( | |
217 | vm_size_t size, /* the size of an element */ | |
218 | vm_size_t maxmem, /* maximum memory to use */ | |
219 | vm_size_t alloc, /* allocation size */ | |
220 | const char *name); /* a name for the zone */ | |
221 | ||
222 | ||
223 | /* Non-blocking version of zalloc */ | |
224 | extern void * zalloc_noblock( | |
225 | zone_t zone); | |
226 | ||
227 | /* direct (non-wrappered) interface */ | |
228 | extern void * zalloc_canblock( | |
229 | zone_t zone, | |
230 | boolean_t canblock); | |
231 | ||
232 | /* Get from zone free list */ | |
233 | extern void * zget( | |
234 | zone_t zone); | |
1c79356b A |
235 | |
236 | /* Fill zone with memory */ | |
237 | extern void zcram( | |
91447636 | 238 | zone_t zone, |
7ddcb079 | 239 | vm_offset_t newmem, |
91447636 | 240 | vm_size_t size); |
1c79356b A |
241 | |
242 | /* Initially fill zone with specified number of elements */ | |
243 | extern int zfill( | |
91447636 A |
244 | zone_t zone, |
245 | int nelem); | |
246 | ||
1c79356b A |
247 | /* Change zone parameters */ |
248 | extern void zone_change( | |
91447636 A |
249 | zone_t zone, |
250 | unsigned int item, | |
251 | boolean_t value); | |
7ddcb079 | 252 | extern void zone_prio_refill_configure(zone_t, vm_size_t); |
91447636 | 253 | /* Item definitions */ |
1c79356b A |
254 | #define Z_EXHAUST 1 /* Make zone exhaustible */ |
255 | #define Z_COLLECT 2 /* Make zone collectable */ | |
256 | #define Z_EXPAND 3 /* Make zone expandable */ | |
91447636 | 257 | #define Z_FOREIGN 4 /* Allow collectable zone to contain foreign elements */ |
6d2010ae | 258 | #define Z_CALLERACCT 5 /* Account alloc/free against the caller */ |
0b4c1975 | 259 | #define Z_NOENCRYPT 6 /* Don't encrypt zone during hibernation */ |
7ddcb079 A |
260 | #define Z_NOCALLOUT 7 /* Don't asynchronously replenish the zone via |
261 | * callouts | |
262 | */ | |
91447636 A |
263 | /* Preallocate space for zone from zone map */ |
264 | extern void zprealloc( | |
265 | zone_t zone, | |
266 | vm_size_t size); | |
9bccf70c | 267 | |
91447636 A |
268 | extern integer_t zone_free_count( |
269 | zone_t zone); | |
9bccf70c | 270 | |
6d2010ae A |
271 | /* |
272 | * MAX_ZTRACE_DEPTH configures how deep of a stack trace is taken on each zalloc in the zone of interest. 15 | |
273 | * levels is usually enough to get past all the layers of code in kalloc and IOKit and see who the actual | |
274 | * caller is up above these lower levels. | |
275 | * | |
276 | * This is used both for the zone leak detector and the zone corruption log. | |
277 | */ | |
278 | ||
279 | #define MAX_ZTRACE_DEPTH 15 | |
280 | ||
281 | /* | |
282 | * Structure for keeping track of a backtrace, used for leak detection. | |
283 | * This is in the .h file because it is used during panic, see kern/debug.c | |
284 | * A non-zero size indicates that the trace is in use. | |
285 | */ | |
286 | struct ztrace { | |
287 | vm_size_t zt_size; /* How much memory are all the allocations referring to this trace taking up? */ | |
288 | uint32_t zt_depth; /* depth of stack (0 to MAX_ZTRACE_DEPTH) */ | |
289 | void* zt_stack[MAX_ZTRACE_DEPTH]; /* series of return addresses from OSBacktrace */ | |
290 | uint32_t zt_collisions; /* How many times did a different stack land here while it was occupied? */ | |
291 | uint32_t zt_hit_count; /* for determining effectiveness of hash function */ | |
292 | }; | |
293 | ||
294 | #if CONFIG_ZLEAKS | |
295 | ||
296 | /* support for the kern.zleak.* sysctls */ | |
297 | ||
298 | extern kern_return_t zleak_activate(void); | |
299 | extern vm_size_t zleak_max_zonemap_size; | |
300 | extern vm_size_t zleak_global_tracking_threshold; | |
301 | extern vm_size_t zleak_per_zone_tracking_threshold; | |
302 | ||
303 | extern int get_zleak_state(void); | |
304 | ||
305 | #endif /* CONFIG_ZLEAKS */ | |
306 | ||
307 | /* These functions used for leak detection both in zalloc.c and mbuf.c */ | |
308 | extern uint32_t fastbacktrace(uintptr_t* bt, uint32_t max_frames); | |
309 | extern uintptr_t hash_mix(uintptr_t x); | |
310 | extern uint32_t hashbacktrace(uintptr_t* bt, uint32_t depth, uint32_t max_size); | |
311 | extern uint32_t hashaddr(uintptr_t pt, uint32_t max_size); | |
312 | ||
91447636 | 313 | #endif /* XNU_KERNEL_PRIVATE */ |
9bccf70c | 314 | |
91447636 | 315 | __END_DECLS |
1c79356b A |
316 | |
317 | #endif /* _KERN_ZALLOC_H_ */ | |
91447636 A |
318 | |
319 | #endif /* KERNEL_PRIVATE */ |