]> git.saurik.com Git - apple/xnu.git/blame - bsd/kern/kern_malloc.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / bsd / kern / kern_malloc.c
CommitLineData
1c79356b 1/*
f427ee49 2 * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
5d5c5d0d 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
0a7de745 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.
0a7de745 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.
0a7de745 17 *
2d21ac55
A
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.
0a7de745 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
27 */
28/* Copyright (c) 1995, 1997 Apple Computer, Inc. All Rights Reserved */
29/*
30 * Copyright (c) 1987, 1991, 1993
31 * The Regents of the University of California. All rights reserved.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. All advertising materials mentioning features or use of this software
42 * must display the following acknowledgement:
43 * This product includes software developed by the University of
44 * California, Berkeley and its contributors.
45 * 4. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 *
61 * @(#)kern_malloc.c 8.4 (Berkeley) 5/20/95
62 */
2d21ac55
A
63/*
64 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
65 * support for mandatory and extensible security protections. This notice
66 * is included in support of clause 2.2 (b) of the Apple Public License,
67 * Version 2.0.
68 */
1c79356b 69
1c79356b
A
70#include <kern/zalloc.h>
71#include <kern/kalloc.h>
72
f427ee49
A
73#include <sys/malloc.h>
74#include <sys/sysctl.h>
1c79356b 75
f427ee49 76#include <libkern/libkern.h>
1c79356b 77
f427ee49 78ZONE_VIEW_DEFINE(ZV_NAMEI, "vfs.namei", KHEAP_ID_DATA_BUFFERS, MAXPATHLEN);
1c79356b 79
f427ee49
A
80static void *
81__MALLOC_ext(
0a7de745
A
82 size_t size,
83 int type,
84 int flags,
f427ee49
A
85 vm_allocation_site_t *site,
86 kalloc_heap_t heap)
1c79356b 87{
0a7de745 88 void *addr = NULL;
1c79356b 89
0a7de745 90 if (type >= M_LAST) {
1c79356b 91 panic("_malloc TYPE");
0a7de745 92 }
1c79356b 93
0a7de745
A
94 if (size == 0) {
95 return NULL;
96 }
1c79356b 97
f427ee49
A
98 static_assert(sizeof(vm_size_t) == sizeof(size_t));
99 static_assert(M_WAITOK == Z_WAITOK);
100 static_assert(M_NOWAIT == Z_NOWAIT);
101 static_assert(M_ZERO == Z_ZERO);
39037602 102
f427ee49
A
103 addr = kalloc_ext(heap, size,
104 flags & (M_WAITOK | M_NOWAIT | M_ZERO), site).addr;
105 if (__probable(addr)) {
106 return addr;
0a7de745 107 }
1c79356b 108
f427ee49
A
109 if (flags & (M_NOWAIT | M_NULL)) {
110 return NULL;
0a7de745 111 }
55e303ae 112
f427ee49
A
113 /*
114 * We get here when the caller told us to block waiting for memory, but
115 * kalloc said there's no memory left to get. Generally, this means there's a
116 * leak or the caller asked for an impossibly large amount of memory. If the caller
117 * is expecting a NULL return code then it should explicitly set the flag M_NULL.
118 * If the caller isn't expecting a NULL return code, we just panic. This is less
119 * than ideal, but returning NULL when the caller isn't expecting it doesn't help
120 * since the majority of callers don't check the return value and will just
121 * dereference the pointer and trap anyway. We may as well get a more
122 * descriptive message out while we can.
123 */
124 panic("_MALLOC: kalloc returned NULL (potential leak), size %llu", (uint64_t) size);
1c79356b
A
125}
126
f427ee49
A
127void *
128__MALLOC(size_t size, int type, int flags, vm_allocation_site_t *site)
1c79356b 129{
f427ee49 130 return __MALLOC_ext(size, type, flags, site, KHEAP_DEFAULT);
1c79356b
A
131}
132
6d2010ae 133void *
3e170ce0 134__REALLOC(
0a7de745
A
135 void *addr,
136 size_t size,
f427ee49 137 int type __unused,
0a7de745 138 int flags,
3e170ce0 139 vm_allocation_site_t *site)
6d2010ae 140{
f427ee49
A
141 addr = kheap_realloc_addr(KHEAP_DEFAULT, addr, size,
142 flags & (M_WAITOK | M_NOWAIT | M_ZERO), site).addr;
6d2010ae 143
f427ee49 144 if (__probable(addr)) {
39037602 145 return addr;
813fb2f6 146 }
39037602 147
f427ee49 148 if (flags & (M_NOWAIT | M_NULL)) {
0a7de745
A
149 return NULL;
150 }
6d2010ae 151
f427ee49 152 panic("_REALLOC: kalloc returned NULL (potential leak), size %llu", (uint64_t) size);
6d2010ae
A
153}
154
91447636 155void *
f427ee49 156_MALLOC_external(size_t size, int type, int flags);
3e170ce0 157void *
f427ee49 158_MALLOC_external(size_t size, int type, int flags)
3e170ce0 159{
f427ee49
A
160 static vm_allocation_site_t site = {
161 .tag = VM_KERN_MEMORY_KALLOC,
162 .flags = VM_TAG_BT,
163 };
164 return __MALLOC_ext(size, type, flags, &site, KHEAP_KEXT);
3e170ce0
A
165}
166
f427ee49
A
167void
168_FREE_external(void *addr, int type);
169void
170_FREE_external(void *addr, int type __unused)
1c79356b 171{
f427ee49
A
172 /*
173 * hashinit and other functions allocate on behalf of kexts and do not have
174 * a matching hashdestroy, so we sadly have to allow this for now.
175 */
176 kheap_free_addr(KHEAP_ANY, addr);
1c79356b
A
177}
178
91447636 179void
f427ee49
A
180_FREE_ZONE_external(void *elem, size_t size, int type);
181void
182_FREE_ZONE_external(void *elem, size_t size, int type __unused)
1c79356b 183{
f427ee49 184 (kheap_free)(KHEAP_KEXT, elem, size);
1c79356b 185}
6d2010ae 186
5ba3f43e
A
187#if DEBUG || DEVELOPMENT
188
189extern unsigned int zone_map_jetsam_limit;
190
191static int
192sysctl_zone_map_jetsam_limit SYSCTL_HANDLER_ARGS
193{
194#pragma unused(oidp, arg1, arg2)
195 int oldval = 0, val = 0, error = 0;
196
197 oldval = zone_map_jetsam_limit;
198 error = sysctl_io_number(req, oldval, sizeof(int), &val, NULL);
199 if (error || !req->newptr) {
0a7de745 200 return error;
5ba3f43e
A
201 }
202
203 if (val <= 0 || val > 100) {
204 printf("sysctl_zone_map_jetsam_limit: new jetsam limit value is invalid.\n");
205 return EINVAL;
206 }
207
208 zone_map_jetsam_limit = val;
0a7de745 209 return 0;
5ba3f43e
A
210}
211
0a7de745
A
212SYSCTL_PROC(_kern, OID_AUTO, zone_map_jetsam_limit, CTLTYPE_INT | CTLFLAG_RW, 0, 0,
213 sysctl_zone_map_jetsam_limit, "I", "Zone map jetsam limit");
5ba3f43e 214
a39ff7e2
A
215
216extern void get_zone_map_size(uint64_t *current_size, uint64_t *capacity);
217
218static int
219sysctl_zone_map_size_and_capacity SYSCTL_HANDLER_ARGS
220{
221#pragma unused(oidp, arg1, arg2)
222 uint64_t zstats[2];
223 get_zone_map_size(&zstats[0], &zstats[1]);
224
225 return SYSCTL_OUT(req, &zstats, sizeof(zstats));
226}
227
228SYSCTL_PROC(_kern, OID_AUTO, zone_map_size_and_capacity,
0a7de745
A
229 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_MASKED | CTLFLAG_LOCKED,
230 0, 0, &sysctl_zone_map_size_and_capacity, "Q", "Current size and capacity of the zone map");
a39ff7e2
A
231
232
5ba3f43e
A
233extern boolean_t run_zone_test(void);
234
235static int
236sysctl_run_zone_test SYSCTL_HANDLER_ARGS
237{
238#pragma unused(oidp, arg1, arg2)
a39ff7e2
A
239 /* require setting this sysctl to prevent sysctl -a from running this */
240 if (!req->newptr) {
241 return 0;
242 }
5ba3f43e 243
a39ff7e2 244 int ret_val = run_zone_test();
5ba3f43e
A
245 return SYSCTL_OUT(req, &ret_val, sizeof(ret_val));
246}
247
248SYSCTL_PROC(_kern, OID_AUTO, run_zone_test,
0a7de745
A
249 CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_MASKED | CTLFLAG_LOCKED,
250 0, 0, &sysctl_run_zone_test, "I", "Test zone allocator KPI");
5ba3f43e
A
251
252#endif /* DEBUG || DEVELOPMENT */
253
6d2010ae
A
254#if CONFIG_ZLEAKS
255
256SYSCTL_DECL(_kern_zleak);
257SYSCTL_NODE(_kern, OID_AUTO, zleak, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "zleak");
258
259/*
260 * kern.zleak.active
261 *
262 * Show the status of the zleak subsystem (0 = enabled, 1 = active,
263 * and -1 = failed), and if enabled, allow it to be activated immediately.
264 */
265static int
266sysctl_zleak_active SYSCTL_HANDLER_ARGS
267{
268#pragma unused(arg1, arg2)
269 int oldval, val, error;
270
271 val = oldval = get_zleak_state();
272 error = sysctl_handle_int(oidp, &val, 0, req);
0a7de745
A
273 if (error || !req->newptr) {
274 return error;
275 }
6d2010ae
A
276 /*
277 * Can only be activated if it's off (and not failed.)
278 * Cannot be deactivated once it's on.
279 */
280 if (val == 1 && oldval == 0) {
281 kern_return_t kr = zleak_activate();
282
0a7de745 283 if (KERN_SUCCESS != kr) {
6d2010ae
A
284 printf("zleak_active: failed to activate "
285 "live zone leak debugging (%d).\n", kr);
0a7de745
A
286 }
287 }
288 if (val == 0 && oldval == 1) {
6d2010ae 289 printf("zleak_active: active, cannot be disabled.\n");
0a7de745 290 return EINVAL;
6d2010ae 291 }
0a7de745 292 return 0;
6d2010ae
A
293}
294
295SYSCTL_PROC(_kern_zleak, OID_AUTO, active,
296 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
297 0, 0, sysctl_zleak_active, "I", "zleak activity");
298
299/*
300 * kern.zleak.max_zonemap_size
301 *
302 * Read the value of the maximum zonemap size in bytes; useful
303 * as the maximum size that zleak.global_threshold and
304 * zleak.zone_threshold should be set to.
305 */
306static int
307sysctl_zleak_max_zonemap_size SYSCTL_HANDLER_ARGS
308{
309 uint64_t zmap_max_size = *(vm_size_t *)arg1;
310
311 return sysctl_handle_quad(oidp, &zmap_max_size, arg2, req);
312}
313
314SYSCTL_PROC(_kern_zleak, OID_AUTO, max_zonemap_size,
315 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
316 &zleak_max_zonemap_size, 0,
317 sysctl_zleak_max_zonemap_size, "Q", "zleak max zonemap size");
318
319
320static int
321sysctl_zleak_threshold SYSCTL_HANDLER_ARGS
322{
323#pragma unused(oidp, arg2)
324 int error;
325 uint64_t value = *(vm_size_t *)arg1;
326
0a7de745 327 error = sysctl_io_number(req, value, sizeof(value), &value, NULL);
6d2010ae 328
0a7de745
A
329 if (error || !req->newptr) {
330 return error;
331 }
6d2010ae 332
0a7de745
A
333 if (value > (uint64_t)zleak_max_zonemap_size) {
334 return ERANGE;
335 }
6d2010ae
A
336
337 *(vm_size_t *)arg1 = value;
0a7de745 338 return 0;
6d2010ae
A
339}
340
341/*
342 * kern.zleak.global_threshold
343 *
344 * Set the global zleak threshold size (in bytes). If the zone map
345 * grows larger than this value, zleaks are automatically activated.
346 *
347 * The default value is set in zleak_init().
348 */
349SYSCTL_PROC(_kern_zleak, OID_AUTO, global_threshold,
350 CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED,
351 &zleak_global_tracking_threshold, 0,
352 sysctl_zleak_threshold, "Q", "zleak global threshold");
353
354/*
355 * kern.zleak.zone_threshold
356 *
357 * Set the per-zone threshold size (in bytes) above which any
358 * zone will automatically start zleak tracking.
359 *
360 * The default value is set in zleak_init().
361 *
362 * Setting this variable will have no effect until zleak tracking is
363 * activated (See above.)
364 */
365SYSCTL_PROC(_kern_zleak, OID_AUTO, zone_threshold,
366 CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED,
367 &zleak_per_zone_tracking_threshold, 0,
368 sysctl_zleak_threshold, "Q", "zleak per-zone threshold");
369
0a7de745 370#endif /* CONFIG_ZLEAKS */
5ba3f43e
A
371
372extern uint64_t get_zones_collectable_bytes(void);
373
374static int
375sysctl_zones_collectable_bytes SYSCTL_HANDLER_ARGS
376{
377#pragma unused(oidp, arg1, arg2)
378 uint64_t zones_free_mem = get_zones_collectable_bytes();
379
380 return SYSCTL_OUT(req, &zones_free_mem, sizeof(zones_free_mem));
381}
382
383SYSCTL_PROC(_kern, OID_AUTO, zones_collectable_bytes,
0a7de745
A
384 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_MASKED | CTLFLAG_LOCKED,
385 0, 0, &sysctl_zones_collectable_bytes, "Q", "Collectable memory in zones");
f427ee49
A
386
387
388#if DEBUG || DEVELOPMENT
389
390static int
391sysctl_zone_gc_replenish_test SYSCTL_HANDLER_ARGS
392{
393#pragma unused(oidp, arg1, arg2)
394 /* require setting this sysctl to prevent sysctl -a from running this */
395 if (!req->newptr) {
396 return 0;
397 }
398
399 int ret_val = 0;
400 zone_gc_replenish_test();
401 return SYSCTL_OUT(req, &ret_val, sizeof(ret_val));
402}
403
404static int
405sysctl_zone_alloc_replenish_test SYSCTL_HANDLER_ARGS
406{
407#pragma unused(oidp, arg1, arg2)
408 /* require setting this sysctl to prevent sysctl -a from running this */
409 if (!req->newptr) {
410 return 0;
411 }
412
413 int ret_val = 0;
414 zone_alloc_replenish_test();
415 return SYSCTL_OUT(req, &ret_val, sizeof(ret_val));
416}
417
418SYSCTL_PROC(_kern, OID_AUTO, zone_gc_replenish_test,
419 CTLTYPE_INT | CTLFLAG_MASKED | CTLFLAG_LOCKED | CTLFLAG_WR,
420 0, 0, &sysctl_zone_gc_replenish_test, "I", "Test zone GC replenish");
421SYSCTL_PROC(_kern, OID_AUTO, zone_alloc_replenish_test,
422 CTLTYPE_INT | CTLFLAG_MASKED | CTLFLAG_LOCKED | CTLFLAG_WR,
423 0, 0, &sysctl_zone_alloc_replenish_test, "I", "Test zone alloc replenish");
424
425#endif /* DEBUG || DEVELOPMENT */