1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #ifndef _SYS_MALLOC_H_
36 #define _SYS_MALLOC_H_
37
38 #define KERN_MALLOC_BUCKETS 1
39 #define KERN_MALLOC_BUCKET 2
40 #define KERN_MALLOC_KMEMNAMES 3
41 #define KERN_MALLOC_KMEMSTATS 4
42 #define KERN_MALLOC_MAXID 5
43
44 #define CTL_KERN_MALLOC_NAMES { \
45 { 0, 0 }, \
46 { "buckets", CTLTYPE_STRING }, \
47 { "bucket", CTLTYPE_NODE }, \
48 { "kmemnames", CTLTYPE_STRING }, \
49 { "kmemstat", CTLTYPE_NODE }, \
50 }
51
52
53
54
55 #define M_WAITOK 0x0000
56 #define M_NOWAIT 0x0001
57 #define M_CANFAIL 0x0002
58
59
60
61
62 #define M_FREE 0
63 #define M_MBUF 1
64 #define M_DEVBUF 2
65 #define M_DEBUG 3
66 #define M_PCB 4
67 #define M_RTABLE 5
68
69 #define M_FTABLE 7
70
71 #define M_IFADDR 9
72 #define M_SOOPTS 10
73 #define M_SYSCTL 11
74
75
76 #define M_IOCTLOPS 14
77
78 #define M_IOV 19
79 #define M_MOUNT 20
80
81 #define M_NFSREQ 22
82 #define M_NFSMNT 23
83 #define M_NFSNODE 24
84 #define M_VNODE 25
85 #define M_CACHE 26
86 #define M_DQUOT 27
87 #define M_UFSMNT 28
88 #define M_SHM 29
89 #define M_VMMAP 30
90 #define M_SEM 31
91 #define M_DIRHASH 32
92
93 #define M_VMPMAP 34
94
95 #define M_FILE 38
96 #define M_FILEDESC 39
97
98 #define M_PROC 41
99 #define M_SUBPROC 42
100 #define M_VCLUSTER 43
101
102 #define M_MFSNODE 46
103
104 #define M_NETADDR 49
105 #define M_NFSSVC 50
106 #define M_NFSUID 51
107 #define M_NFSD 52
108 #define M_IPMOPTS 53
109 #define M_IPMADDR 54
110 #define M_IFMADDR 55
111 #define M_MRTABLE 56
112 #define M_ISOFSMNT 57
113 #define M_ISOFSNODE 58
114 #define M_MSDOSFSMNT 59
115 #define M_MSDOSFSFAT 60
116 #define M_MSDOSFSNODE 61
117 #define M_TTYS 62
118 #define M_EXEC 63
119 #define M_MISCFSMNT 64
120
121 #define M_PFKEY 74
122 #define M_TDB 75
123 #define M_XDATA 76
124
125 #define M_PAGEDEP 78
126 #define M_INODEDEP 79
127 #define M_NEWBLK 80
128
129 #define M_INDIRDEP 83
130
131 #define M_VMSWAP 92
132
133 #define M_RAIDFRAME 97
134 #define M_UVMAMAP 98
135 #define M_UVMAOBJ 99
136
137 #define M_USB 101
138 #define M_USBDEV 102
139 #define M_USBHC 103
140
141 #define M_MEMDESC 105
142
143 #define M_CRYPTO_DATA 108
144
145 #define M_CREDENTIALS 110
146 #define M_PACKET_TAGS 111
147 #define M_1394CTL 112
148 #define M_1394DATA 113
149 #define M_EMULDATA 114
150
151
152
153 #define M_IP6OPT 123
154 #define M_IP6NDP 124
155 #define M_IP6RR 125
156 #define M_RR_ADDR 126
157 #define M_TEMP 127
158
159 #define M_NTFSMNT 128
160 #define M_NTFSNTNODE 129
161 #define M_NTFSFNODE 130
162 #define M_NTFSDIR 131
163 #define M_NTFSNTHASH 132
164 #define M_NTFSNTVATTR 133
165 #define M_NTFSRDATA 134
166 #define M_NTFSDECOMP 135
167 #define M_NTFSRUN 136
168
169 #define M_KEVENT 137
170
171 #define M_BLUETOOTH 138
172
173 #define M_BWMETER 139
174
175 #define M_UDFMOUNT 140
176 #define M_UDFFENTRY 141
177 #define M_UDFFID 142
178
179 #define M_LAST 143
180
181 #define INITKMEMNAMES { \
182 "free", \
183 "mbuf", \
184 "devbuf", \
185 "debug", \
186 "pcb", \
187 "routetbl", \
188 NULL, \
189 "fragtbl", \
190 NULL, \
191 "ifaddr", \
192 "soopts", \
193 "sysctl", \
194 NULL, \
195 NULL, \
196 "ioctlops", \
197 NULL, \
198 NULL, \
199 NULL, \
200 NULL, \
201 "iov", \
202 "mount", \
203 NULL, \
204 "NFS req", \
205 "NFS mount", \
206 "NFS node", \
207 "vnodes", \
208 "namecache", \
209 "UFS quota", \
210 "UFS mount", \
211 "shm", \
212 "VM map", \
213 "sem", \
214 "dirhash", \
215 NULL, \
216 "VM pmap", \
217 NULL, \
218 NULL, \
219 NULL, \
220 "file", \
221 "file desc", \
222 NULL, \
223 "proc", \
224 "subproc", \
225 "VFS cluster", \
226 NULL, \
227 NULL, \
228 "MFS node", \
229 NULL, \
230 NULL, \
231 "Export Host", \
232 "NFS srvsock", \
233 "NFS uid", \
234 "NFS daemon", \
235 "ip_moptions", \
236 "in_multi", \
237 "ether_multi", \
238 "mrt", \
239 "ISOFS mount", \
240 "ISOFS node", \
241 "MSDOSFS mount", \
242 "MSDOSFS fat", \
243 "MSDOSFS node", \
244 "ttys", \
245 "exec", \
246 "miscfs mount", \
247 NULL, \
248 NULL, \
249 NULL, \
250 NULL, \
251 NULL, \
252 NULL, \
253 NULL, \
254 NULL, \
255 NULL, \
256 "pfkey data", \
257 "tdb", \
258 "xform_data", \
259 NULL, \
260 "pagedep", \
261 "inodedep", \
262 "newblk", \
263 NULL, \
264 NULL, \
265 "indirdep", \
266 NULL, NULL, NULL, NULL, \
267 NULL, NULL, NULL, NULL, \
268 "VM swap", \
269 NULL, NULL, NULL, NULL, \
270 "RAIDframe data", \
271 "UVM amap", \
272 "UVM aobj", \
273 NULL, \
274 "USB", \
275 "USB device", \
276 "USB HC", \
277 NULL, \
278 "memdesc", \
279 NULL, \
280 NULL, \
281 "crypto data", \
282 NULL, \
283 "IPsec creds", \
284 "packet tags", \
285 "1394ctl", \
286 "1394data", \
287 "emuldata", \
288 NULL, NULL, NULL, NULL, \
289 NULL, NULL, NULL, NULL, \
290 "ip6_options", \
291 "NDP", \
292 "ip6rr", \
293 "rp_addr", \
294 "temp", \
295 "NTFS mount", \
296 "NTFS node", \
297 "NTFS fnode", \
298 "NTFS dir", \
299 "NTFS hash tables", \
300 "NTFS file attr", \
301 "NTFS resident data ", \
302 "NTFS decomp", \
303 "NTFS vrun", \
304 "kqueue", \
305 "bluetooth", \
306 "bwmeter", \
307 "UDF mount", \
308 "UDF file entry", \
309 "UDF file id", \
310 }
311
312 struct kmemstats {
313 long ks_inuse;
314 long ks_calls;
315 long ks_memuse;
316 u_short ks_limblocks;
317 u_short ks_mapblocks;
318 long ks_maxused;
319 long ks_limit;
320 long ks_size;
321 long ks_spare;
322 };
323
324
325
326
327 struct kmemusage {
328 short ku_indx;
329 union {
330 u_short freecnt;
331 u_short pagecnt;
332 } ku_un;
333 };
334 #define ku_freecnt ku_un.freecnt
335 #define ku_pagecnt ku_un.pagecnt
336
337
338
339
340 struct kmembuckets {
341 caddr_t kb_next;
342 caddr_t kb_last;
343 u_int64_t kb_calls;
344 u_int64_t kb_total;
345 u_int64_t kb_totalfree;
346 u_int64_t kb_elmpercl;
347 u_int64_t kb_highwat;
348 u_int64_t kb_couldfree;
349 };
350
351 #ifdef _KERNEL
352 #define MINALLOCSIZE (1 << MINBUCKET)
353 #define BUCKETINDX(size) \
354 ((size) <= (MINALLOCSIZE * 128) \
355 ? (size) <= (MINALLOCSIZE * 8) \
356 ? (size) <= (MINALLOCSIZE * 2) \
357 ? (size) <= (MINALLOCSIZE * 1) \
358 ? (MINBUCKET + 0) \
359 : (MINBUCKET + 1) \
360 : (size) <= (MINALLOCSIZE * 4) \
361 ? (MINBUCKET + 2) \
362 : (MINBUCKET + 3) \
363 : (size) <= (MINALLOCSIZE* 32) \
364 ? (size) <= (MINALLOCSIZE * 16) \
365 ? (MINBUCKET + 4) \
366 : (MINBUCKET + 5) \
367 : (size) <= (MINALLOCSIZE * 64) \
368 ? (MINBUCKET + 6) \
369 : (MINBUCKET + 7) \
370 : (size) <= (MINALLOCSIZE * 2048) \
371 ? (size) <= (MINALLOCSIZE * 512) \
372 ? (size) <= (MINALLOCSIZE * 256) \
373 ? (MINBUCKET + 8) \
374 : (MINBUCKET + 9) \
375 : (size) <= (MINALLOCSIZE * 1024) \
376 ? (MINBUCKET + 10) \
377 : (MINBUCKET + 11) \
378 : (size) <= (MINALLOCSIZE * 8192) \
379 ? (size) <= (MINALLOCSIZE * 4096) \
380 ? (MINBUCKET + 12) \
381 : (MINBUCKET + 13) \
382 : (size) <= (MINALLOCSIZE * 16384) \
383 ? (MINBUCKET + 14) \
384 : (MINBUCKET + 15))
385
386
387
388
389 #define kmemxtob(alloc) (kmembase + (alloc) * NBPG)
390 #define btokmemx(addr) (((caddr_t)(addr) - kmembase) / NBPG)
391 #define btokup(addr) (&kmemusage[((caddr_t)(addr) - kmembase) >> PAGE_SHIFT])
392
393
394
395
396 #if defined(KMEMSTATS) || defined(DIAGNOSTIC) || defined(_LKM) || defined(SMALL_KERNEL)
397 #define MALLOC(space, cast, size, type, flags) \
398 (space) = (cast)malloc((u_long)(size), type, flags)
399 #define FREE(addr, type) free((caddr_t)(addr), type)
400
401 #else
402 #define MALLOC(space, cast, size, type, flags) do { \
403 u_long kbp_size = (u_long)(size); \
404 struct kmembuckets *kbp = &bucket[BUCKETINDX(kbp_size)]; \
405 int __s = splvm(); \
406 if (kbp->kb_next == NULL) { \
407 (space) = (cast)malloc(kbp_size, type, flags); \
408 } else { \
409 (space) = (cast)kbp->kb_next; \
410 kbp->kb_next = *(caddr_t *)(space); \
411 } \
412 splx(__s); \
413 } while (0)
414
415 #define FREE(addr, type) do { \
416 struct kmembuckets *kbp; \
417 struct kmemusage *kup = btokup(addr); \
418 int __s = splvm(); \
419 if (1 << kup->ku_indx > MAXALLOCSAVE) { \
420 free((caddr_t)(addr), type); \
421 } else { \
422 kbp = &bucket[kup->ku_indx]; \
423 if (kbp->kb_next == NULL) \
424 kbp->kb_next = (caddr_t)(addr); \
425 else \
426 *(caddr_t *)(kbp->kb_last) = (caddr_t)(addr); \
427 *(caddr_t *)(addr) = NULL; \
428 kbp->kb_last = (caddr_t)(addr); \
429 } \
430 splx(__s); \
431 } while(0)
432 #endif
433
434 extern struct kmemstats kmemstats[];
435 extern struct kmemusage *kmemusage;
436 extern char *kmembase;
437 extern struct kmembuckets bucket[];
438
439 extern void *malloc(unsigned long size, int type, int flags);
440 extern void free(void *addr, int type);
441 extern int sysctl_malloc(int *, u_int, void *, size_t *, void *, size_t,
442 struct proc *);
443
444 size_t malloc_roundup(size_t);
445 void malloc_printit(int (*)(const char *, ...));
446
447 #ifdef MALLOC_DEBUG
448 int debug_malloc(unsigned long, int, int, void **);
449 int debug_free(void *, int);
450 void debug_malloc_init(void);
451 void debug_malloc_assert_allocated(void *, const char *);
452 #define DEBUG_MALLOC_ASSERT_ALLOCATED(addr) \
453 debug_malloc_assert_allocated(addr, __func__)
454
455 void debug_malloc_print(void);
456 void debug_malloc_printit(int (*)(const char *, ...), vaddr_t);
457 #endif
458 #endif
459 #endif