]>
git.saurik.com Git - apple/xnu.git/blob - bsd/kern/kern_malloc.c
16125c3680b43c6348c0f0d1cb04e4f8d011cccd
2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
28 /* Copyright (c) 1995, 1997 Apple Computer, Inc. All Rights Reserved */
30 * Copyright (c) 1987, 1991, 1993
31 * The Regents of the University of California. All rights reserved.
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
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.
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
61 * @(#)kern_malloc.c 8.4 (Berkeley) 5/20/95
64 #include <sys/param.h>
65 #include <sys/malloc.h>
67 #include <sys/socket.h>
68 #include <sys/socketvar.h>
70 #include <net/route.h>
72 #include <netinet/in.h>
73 #include <netinet/in_systm.h>
74 #include <netinet/ip.h>
75 #include <netinet/in_pcb.h>
77 #include <sys/event.h>
78 #include <sys/eventvar.h>
80 #include <sys/proc_internal.h>
81 #include <sys/mount_internal.h>
82 #include <sys/vnode_internal.h>
83 #include <sys/ubc_internal.h>
84 #include <sys/namei.h>
85 #include <sys/file_internal.h>
86 #include <sys/filedesc.h>
88 #include <sys/quota.h>
89 #include <sys/uio_internal.h>
91 #include <ufs/ufs/inode.h>
93 #include <hfs/hfs_cnode.h>
94 #include <isofs/cd9660/cd9660_node.h>
96 #include <miscfs/volfs/volfs.h>
97 #include <miscfs/specfs/specdev.h>
99 #include <nfs/rpcv2.h>
100 #include <nfs/nfsproto.h>
101 #include <nfs/nfsnode.h>
102 #include <nfs/nfsmount.h>
104 #include <vfs/vfs_journal.h>
106 #include <mach/mach_types.h>
108 #include <kern/zalloc.h>
109 #include <kern/kalloc.h>
111 struct kmemstats kmemstats
[M_LAST
];
112 char *memname
[] = INITKMEMNAMES
;
117 #define KMZ_CREATEZONE ((void *)-2)
118 #define KMZ_LOOKUPZONE ((void *)-1)
119 #define KMZ_MALLOC ((void *)0)
120 #define KMZ_SHAREZONE ((void *)1)
121 } kmzones
[M_LAST
] = {
122 #define SOS(sname) sizeof (struct sname)
123 #define SOX(sname) -1
124 -1, 0, /* 0 M_FREE */
125 MSIZE
, KMZ_CREATEZONE
, /* 1 M_MBUF */
126 0, KMZ_MALLOC
, /* 2 M_DEVBUF */
127 SOS(socket
), KMZ_CREATEZONE
, /* 3 M_SOCKET */
128 SOS(inpcb
), KMZ_LOOKUPZONE
, /* 4 M_PCB */
129 M_MBUF
, KMZ_SHAREZONE
, /* 5 M_RTABLE */
130 M_MBUF
, KMZ_SHAREZONE
, /* 6 M_HTABLE */
131 M_MBUF
, KMZ_SHAREZONE
, /* 7 M_FTABLE */
132 SOS(rusage
), KMZ_CREATEZONE
, /* 8 M_ZOMBIE */
133 0, KMZ_MALLOC
, /* 9 M_IFADDR */
134 M_MBUF
, KMZ_SHAREZONE
, /* 10 M_SOOPTS */
135 0, KMZ_MALLOC
, /* 11 M_SONAME */
136 MAXPATHLEN
, KMZ_CREATEZONE
, /* 12 M_NAMEI */
137 0, KMZ_MALLOC
, /* 13 M_GPROF */
138 0, KMZ_MALLOC
, /* 14 M_IOCTLOPS */
139 0, KMZ_MALLOC
, /* 15 M_MAPMEM */
140 SOS(ucred
), KMZ_CREATEZONE
, /* 16 M_CRED */
141 SOS(pgrp
), KMZ_CREATEZONE
, /* 17 M_PGRP */
142 SOS(session
), KMZ_CREATEZONE
, /* 18 M_SESSION */
143 SOS(iovec_32
), KMZ_LOOKUPZONE
, /* 19 M_IOV32 */
144 SOS(mount
), KMZ_CREATEZONE
, /* 20 M_MOUNT */
145 0, KMZ_MALLOC
, /* 21 M_FHANDLE */
146 SOS(nfsreq
), KMZ_CREATEZONE
, /* 22 M_NFSREQ */
147 SOS(nfsmount
), KMZ_CREATEZONE
, /* 23 M_NFSMNT */
148 SOS(nfsnode
), KMZ_CREATEZONE
, /* 24 M_NFSNODE */
149 SOS(vnode
), KMZ_CREATEZONE
, /* 25 M_VNODE */
150 SOS(namecache
), KMZ_CREATEZONE
, /* 26 M_CACHE */
151 SOX(dquot
), KMZ_LOOKUPZONE
, /* 27 M_DQUOT */
152 SOX(ufsmount
), KMZ_LOOKUPZONE
, /* 28 M_UFSMNT */
153 0, KMZ_MALLOC
, /* 29 M_CGSUM */
154 0, KMZ_MALLOC
, /* 30 M_VMMAP */
155 0, KMZ_MALLOC
, /* 31 M_VMMAPENT */
156 0, KMZ_MALLOC
, /* 32 M_VMOBJ */
157 0, KMZ_MALLOC
, /* 33 M_VMOBJHASH */
158 0, KMZ_MALLOC
, /* 34 M_VMPMAP */
159 0, KMZ_MALLOC
, /* 35 M_VMPVENT */
160 0, KMZ_MALLOC
, /* 36 M_VMPAGER */
161 0, KMZ_MALLOC
, /* 37 M_VMPGDATA */
162 SOS(fileproc
), KMZ_CREATEZONE
, /* 38 M_FILEPROC */
163 SOS(filedesc
), KMZ_CREATEZONE
, /* 39 M_FILEDESC */
164 SOX(lockf
), KMZ_CREATEZONE
, /* 40 M_LOCKF */
165 SOS(proc
), KMZ_CREATEZONE
, /* 41 M_PROC */
166 SOS(pstats
), KMZ_CREATEZONE
, /* 42 M_SUBPROC */
167 0, KMZ_MALLOC
, /* 43 M_SEGMENT */
168 M_FFSNODE
, KMZ_SHAREZONE
, /* 44 M_LFSNODE */
169 SOS(inode
), KMZ_CREATEZONE
, /* 45 M_FFSNODE */
170 M_FFSNODE
, KMZ_SHAREZONE
, /* 46 M_MFSNODE */
171 0, KMZ_MALLOC
, /* 47 M_NQLEASE */
172 0, KMZ_MALLOC
, /* 48 M_NQMHOST */
173 0, KMZ_MALLOC
, /* 49 M_NETADDR */
175 KMZ_CREATEZONE
, /* 50 M_NFSSVC */
176 SOS(nfsuid
), KMZ_CREATEZONE
, /* 51 M_NFSUID */
178 KMZ_CREATEZONE
, /* 52 M_NFSD */
180 KMZ_LOOKUPZONE
, /* 53 M_IPMOPTS */
181 SOX(in_multi
), KMZ_LOOKUPZONE
, /* 54 M_IPMADDR */
183 KMZ_LOOKUPZONE
, /* 55 M_IFMADDR */
184 SOX(mrt
), KMZ_CREATEZONE
, /* 56 M_MRTABLE */
185 SOX(iso_mnt
), KMZ_LOOKUPZONE
, /* 57 M_ISOFSMNT */
186 SOS(iso_node
), KMZ_CREATEZONE
, /* 58 M_ISOFSNODE */
188 KMZ_CREATEZONE
, /* 59 M_NFSRVDESC */
189 SOS(nfsdmap
), KMZ_CREATEZONE
, /* 60 M_NFSDIROFF */
190 SOS(fhandle
), KMZ_LOOKUPZONE
, /* 61 M_NFSBIGFH */
191 0, KMZ_MALLOC
, /* 62 M_MSDOSFSMNT */
192 0, KMZ_MALLOC
, /* 63 M_MSDOSFSFAT */
193 0, KMZ_MALLOC
, /* 64 M_MSDOSFSNODE */
194 SOS(tty
), KMZ_CREATEZONE
, /* 65 M_TTYS */
195 0, KMZ_MALLOC
, /* 66 M_EXEC */
196 0, KMZ_MALLOC
, /* 67 M_MISCFSMNT */
197 0, KMZ_MALLOC
, /* 68 M_MISCFSNODE */
198 0, KMZ_MALLOC
, /* 69 M_ADOSFSMNT */
199 0, KMZ_MALLOC
, /* 70 M_ADOSFSNODE */
200 0, KMZ_MALLOC
, /* 71 M_ANODE */
201 SOX(buf
), KMZ_CREATEZONE
, /* 72 M_BUFHDR */
202 (NDFILE
* OFILESIZE
),
203 KMZ_CREATEZONE
, /* 73 M_OFILETABL */
204 MCLBYTES
, KMZ_CREATEZONE
, /* 74 M_MCLUST */
205 SOX(hfsmount
), KMZ_LOOKUPZONE
, /* 75 M_HFSMNT */
206 SOS(cnode
), KMZ_CREATEZONE
, /* 76 M_HFSNODE */
207 SOS(filefork
), KMZ_CREATEZONE
, /* 77 M_HFSFORK */
208 SOX(volfs_mntdata
), KMZ_LOOKUPZONE
, /* 78 M_VOLFSMNT */
209 SOS(volfs_vndata
), KMZ_CREATEZONE
, /* 79 M_VOLFSNODE */
210 0, KMZ_MALLOC
, /* 80 M_TEMP */
211 0, KMZ_MALLOC
, /* 81 M_SECA */
212 0, KMZ_MALLOC
, /* 82 M_DEVFS */
213 0, KMZ_MALLOC
, /* 83 M_IPFW */
214 0, KMZ_MALLOC
, /* 84 M_UDFNODE */
215 0, KMZ_MALLOC
, /* 85 M_UDFMOUNT */
216 0, KMZ_MALLOC
, /* 86 M_IP6NDP */
217 0, KMZ_MALLOC
, /* 87 M_IP6OPT */
218 0, KMZ_MALLOC
, /* 88 M_IP6MISC */
219 0, KMZ_MALLOC
, /* 89 M_TSEGQ */
220 0, KMZ_MALLOC
, /* 90 M_IGMP */
221 SOS(journal
), KMZ_CREATEZONE
, /* 91 M_JNL_JNL */
222 SOS(transaction
), KMZ_CREATEZONE
, /* 92 M_JNL_TR */
223 SOS(specinfo
), KMZ_CREATEZONE
, /* 93 M_SPECINFO */
224 SOS(kqueue
), KMZ_CREATEZONE
, /* 94 M_KQUEUE */
225 SOS(directoryhint
), KMZ_CREATEZONE
, /* 95 M_HFSDIRHINT */
226 SOS(cl_readahead
), KMZ_CREATEZONE
, /* 96 M_CLRDAHEAD */
227 SOS(cl_writebehind
),KMZ_CREATEZONE
, /* 97 M_CLWRBEHIND */
228 SOS(iovec_64
), KMZ_LOOKUPZONE
, /* 98 M_IOV64 */
229 SOS(fileglob
), KMZ_CREATEZONE
, /* 99 M_FILEGLOB */
230 0, KMZ_MALLOC
, /* 100 M_KAUTH */
231 0, KMZ_MALLOC
, /* 101 M_DUMMYNET */
232 SOS(unsafe_fsnode
),KMZ_CREATEZONE
, /* 102 M_UNSAFEFS */
237 extern zone_t
kalloc_zone(vm_size_t
); /* XXX */
240 * Initialize the kernel memory allocator
247 if ((sizeof(kmzones
)/sizeof(kmzones
[0])) != (sizeof(memname
)/sizeof(memname
[0]))) {
248 panic("kmeminit: kmzones has %d elements but memname has %d\n",
249 (sizeof(kmzones
)/sizeof(kmzones
[0])), (sizeof(memname
)/sizeof(memname
[0])));
253 while (kmz
< &kmzones
[M_LAST
]) {
255 if (kmz
->kz_elemsize
== -1)
259 if (kmz
->kz_zalloczone
== KMZ_CREATEZONE
) {
260 kmz
->kz_zalloczone
= zinit(kmz
->kz_elemsize
,
261 1024 * 1024, PAGE_SIZE
,
262 memname
[kmz
- kmzones
]);
264 else if (kmz
->kz_zalloczone
== KMZ_LOOKUPZONE
)
265 kmz
->kz_zalloczone
= kalloc_zone(kmz
->kz_elemsize
);
271 while (kmz
< &kmzones
[M_LAST
]) {
273 if (kmz
->kz_elemsize
== -1)
277 if (kmz
->kz_zalloczone
== KMZ_SHAREZONE
) {
279 kmzones
[kmz
->kz_elemsize
].kz_zalloczone
;
281 kmzones
[kmz
->kz_elemsize
].kz_elemsize
;
288 #define MDECL(reqlen) \
291 char _m[(reqlen) + sizeof (struct _mhead)]; \
299 #define ZEROSIZETOKEN (void *)0xFADEDFAD
308 size_t memsize
= sizeof (*mem
);
311 panic("_malloc TYPE");
314 * On zero request we do not return zero as that
315 * could be mistaken for ENOMEM.
318 return (ZEROSIZETOKEN
);
320 if (flags
& M_NOWAIT
) {
321 mem
= (void *)kalloc_noblock(memsize
);
323 mem
= (void *)kalloc(memsize
);
328 mem
->hdr
.mlen
= memsize
;
331 bzero(mem
->hdr
.dat
, size
);
333 return (mem
->hdr
.dat
);
346 if (addr
== (void *)ZEROSIZETOKEN
)
349 return; /* correct (convenient bsd kernel legacy) */
352 kfree(hdr
, hdr
->mlen
);
365 panic("_malloc_zone TYPE");
367 kmz
= &kmzones
[type
];
368 if (kmz
->kz_zalloczone
== KMZ_MALLOC
)
369 panic("_malloc_zone ZONE: type = %d", type
);
372 if (kmz
->kz_elemsize
== -1)
373 panic("_malloc_zone XXX");
375 if (size
== kmz
->kz_elemsize
)
376 if (flags
& M_NOWAIT
) {
377 elem
= (void *)zalloc_noblock(kmz
->kz_zalloczone
);
379 elem
= (void *)zalloc(kmz
->kz_zalloczone
);
382 if (flags
& M_NOWAIT
) {
383 elem
= (void *)kalloc_noblock(size
);
385 elem
= (void *)kalloc(size
);
402 kmz
= &kmzones
[type
];
403 if (kmz
->kz_zalloczone
== KMZ_MALLOC
)
404 panic("free_zone ZONE");
407 if (kmz
->kz_elemsize
== -1)
408 panic("FREE_SIZE XXX");
410 if (size
== kmz
->kz_elemsize
)
411 zfree(kmz
->kz_zalloczone
, elem
);