]> git.saurik.com Git - apple/system_cmds.git/blame - zprint.tproj/zprint.c
system_cmds-880.100.5.tar.gz
[apple/system_cmds.git] / zprint.tproj / zprint.c
CommitLineData
8459d725 1/*
cf37c299 2 * Copyright (c) 2009-2016 Apple Inc. All rights reserved.
8459d725
A
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
cf37c299 5 *
8459d725
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.
cf37c299 14 *
8459d725
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
cf37c299 17 *
8459d725
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
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.
cf37c299 25 *
8459d725
A
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
1815bff5
A
28/*
29 * @OSF_COPYRIGHT@
30 */
cf37c299 31/*
1815bff5
A
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
34 * All Rights Reserved.
cf37c299 35 *
1815bff5
A
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.
cf37c299
A
41 *
42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
1815bff5
A
43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
cf37c299 45 *
1815bff5 46 * Carnegie Mellon requests users of this software to return to
cf37c299 47 *
1815bff5
A
48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
cf37c299 52 *
1815bff5
A
53 * any improvements or extensions that they make and grant Carnegie the
54 * rights to redistribute these changes.
55 */
56/*
57 * zprint.c
58 *
59 * utility for printing out zone structures
60 *
61 * With no arguments, prints information on all zone structures.
62 * With an argument, prints information only on those zones for
63 * which the given name is a substring of the zone's name.
64 * With a "-w" flag, calculates how much much space is allocated
65 * to zones but not currently in use.
66 */
67
9726c137 68#include <vm_statistics.h>
1815bff5 69#include <stdio.h>
34d340d7 70#include <stdlib.h>
1815bff5
A
71#include <string.h>
72#include <mach/mach.h>
73#include <mach_debug/mach_debug.h>
74#include <mach/mach_error.h>
ef8ad44b
A
75#include <libutil.h>
76#include <errno.h>
9726c137
A
77#include <sysexits.h>
78#include <getopt.h>
79#include <malloc/malloc.h>
80#include <Kernel/IOKit/IOKitDebug.h>
81#include <Kernel/libkern/OSKextLibPrivate.h>
82#include <IOKit/IOKitLib.h>
83#include <IOKit/IOKitKeys.h>
84#include <IOKit/kext/OSKext.h>
85#include <CoreFoundation/CoreFoundation.h>
86#include <CoreSymbolication/CoreSymbolication.h>
87
c0bbac3a
A
88#ifndef VM_KERN_SITE_ZONE_VIEW
89#define VM_KERN_SITE_ZONE_VIEW 0x00001000
90#endif
91
92#define streql(a, b) (strcmp((a), (b)) == 0)
93#define strneql(a, b, n) (strncmp((a), (b), (n)) == 0)
94#define PRINTK(fmt, value) \
95 printf(fmt "K", (value) / 1024 ) /* ick */
1815bff5 96
639dadd6
A
97static void usage(FILE *stream);
98static void printzone(mach_zone_name_t *, mach_zone_info_t *);
99static void colprintzone(mach_zone_name_t *, mach_zone_info_t *);
100static int find_deltas(mach_zone_name_t *, mach_zone_info_t *, mach_zone_info_t *, char *, int, int);
8459d725 101static void colprintzoneheader(void);
9726c137
A
102static boolean_t substr(const char *a, size_t alen, const char *b, size_t blen);
103
887d5eed
A
104static int SortName(void * thunk, const void * left, const void * right);
105static int SortSize(void * thunk, const void * left, const void * right);
106static void PrintLarge(mach_memory_info_t *wiredInfo, unsigned int wiredInfoCnt,
c0bbac3a
A
107 mach_zone_info_t *zoneInfo, mach_zone_name_t *zoneNames,
108 unsigned int zoneCnt, uint64_t zoneElements,
109 int (*func)(void *, const void *, const void *), boolean_t column);
1815bff5
A
110
111static char *program;
112
8459d725 113static boolean_t ShowDeltas = FALSE;
1815bff5 114static boolean_t ShowWasted = FALSE;
8459d725 115static boolean_t ShowTotal = FALSE;
9726c137 116static boolean_t ShowLarge = TRUE;
1815bff5
A
117static boolean_t SortZones = FALSE;
118static boolean_t ColFormat = TRUE;
119static boolean_t PrintHeader = TRUE;
120
8459d725
A
121static unsigned long long totalsize = 0;
122static unsigned long long totalused = 0;
123static unsigned long long totalsum = 0;
639dadd6
A
124static unsigned long long totalfragmented = 0;
125static unsigned long long totalcollectable = 0;
8459d725
A
126
127static int last_time = 0;
128
c0bbac3a
A
129static char *zname = NULL;
130static size_t znamelen = 0;
8459d725 131
639dadd6
A
132#define LEFTALIGN -1
133#define RIGHTALIGN 1
134
135typedef struct {
136 char *line1;
137 char *line2;
138 int colwidth;
139 int alignment;
140 bool visible;
141} column_format;
142
143enum {
144 COL_ZONE_NAME,
145 COL_ELEM_SIZE,
146 COL_CUR_SIZE,
147 COL_MAX_SIZE,
148 COL_CUR_ELTS,
149 COL_MAX_ELTS,
150 COL_CUR_INUSE,
151 COL_ALLOC_SIZE,
152 COL_ALLOC_COUNT,
153 COL_ZONE_FLAGS,
154 COL_FRAG_SIZE,
155 COL_FREE_SIZE,
156 COL_TOTAL_ALLOCS,
157 COL_MAX
158};
159
160/*
161 * The order in which the columns appear below should match
162 * the order in which the values are printed in colprintzone().
163 */
164static column_format columns[] = {
c0bbac3a
A
165 [COL_ZONE_NAME] = { "", "zone name", 25, LEFTALIGN, true },
166 [COL_ELEM_SIZE] = { "elem", "size", 6, RIGHTALIGN, true },
167 [COL_CUR_SIZE] = { "cur", "size", 11, RIGHTALIGN, true },
168 [COL_MAX_SIZE] = { "max", "size", 11, RIGHTALIGN, true },
169 [COL_CUR_ELTS] = { "cur", "#elts", 10, RIGHTALIGN, true },
170 [COL_MAX_ELTS] = { "max", "#elts", 11, RIGHTALIGN, true },
171 [COL_CUR_INUSE] = { "cur", "inuse", 11, RIGHTALIGN, true },
172 [COL_ALLOC_SIZE] = { "alloc", "size", 6, RIGHTALIGN, true },
173 [COL_ALLOC_COUNT] = { "alloc", "count", 6, RIGHTALIGN, true },
174 [COL_ZONE_FLAGS] = { "", "", 2, RIGHTALIGN, true },
175 /* additional columns for special flags, not visible by default */
176 [COL_FRAG_SIZE] = { "frag", "size", 9, RIGHTALIGN, false },
177 [COL_FREE_SIZE] = { "free", "size", 9, RIGHTALIGN, false },
178 [COL_TOTAL_ALLOCS] = { "total", "allocs", 17, RIGHTALIGN, false }
639dadd6
A
179};
180
8459d725
A
181static void
182sigintr(__unused int signum)
183{
184 last_time = 1;
185}
1815bff5
A
186
187static void
639dadd6 188usage(FILE *stream)
1815bff5 189{
639dadd6
A
190 fprintf(stream, "usage: %s [-w] [-s] [-c] [-h] [-H] [-t] [-d] [-l] [-L] [name]\n\n", program);
191 fprintf(stream, "\t-w\tshow wasted memory for each zone\n");
192 fprintf(stream, "\t-s\tsort zones by wasted memory\n");
193 fprintf(stream, "\t-c\t(default) display output formatted in columns\n");
194 fprintf(stream, "\t-h\tdisplay this help message\n");
195 fprintf(stream, "\t-H\thide column names\n");
196 fprintf(stream, "\t-t\tdisplay the total size of allocations over the life of the zone\n");
197 fprintf(stream, "\t-d\tdisplay deltas over time\n");
198 fprintf(stream, "\t-l\t(default) display wired memory info after zone info\n");
199 fprintf(stream, "\t-L\tdo not show wired memory info, only show zone info\n");
200 fprintf(stream, "\nAny option (including default options) can be overridden by specifying the option in upper-case.\n\n");
201 exit(stream != stdout);
1815bff5
A
202}
203
34d340d7 204int
8459d725 205main(int argc, char **argv)
1815bff5 206{
8459d725
A
207 mach_zone_name_t *name = NULL;
208 unsigned int nameCnt = 0;
639dadd6 209 mach_zone_info_t *info = NULL;
8459d725 210 unsigned int infoCnt = 0;
9726c137
A
211 mach_memory_info_t *wiredInfo = NULL;
212 unsigned int wiredInfoCnt = 0;
639dadd6 213 mach_zone_info_t *max_info = NULL;
c0bbac3a 214 char *deltas = NULL;
887d5eed 215 uint64_t zoneElements;
1815bff5 216
c0bbac3a
A
217 kern_return_t kr;
218 int i, j;
219 int first_time = 1;
220 int must_print = 1;
221 int interval = 1;
1815bff5 222
8459d725 223 signal(SIGINT, sigintr);
ef8ad44b 224
1815bff5 225 program = strrchr(argv[0], '/');
c0bbac3a 226 if (program == NULL) {
1815bff5 227 program = argv[0];
c0bbac3a 228 } else {
1815bff5 229 program++;
c0bbac3a 230 }
1815bff5
A
231
232 for (i = 1; i < argc; i++) {
c0bbac3a 233 if (streql(argv[i], "-d")) {
8459d725 234 ShowDeltas = TRUE;
c0bbac3a 235 } else if (streql(argv[i], "-t")) {
8459d725 236 ShowTotal = TRUE;
c0bbac3a 237 } else if (streql(argv[i], "-T")) {
8459d725 238 ShowTotal = FALSE;
c0bbac3a 239 } else if (streql(argv[i], "-w")) {
1815bff5 240 ShowWasted = TRUE;
c0bbac3a 241 } else if (streql(argv[i], "-W")) {
1815bff5 242 ShowWasted = FALSE;
c0bbac3a 243 } else if (streql(argv[i], "-l")) {
9726c137 244 ShowLarge = TRUE;
c0bbac3a 245 } else if (streql(argv[i], "-L")) {
9726c137 246 ShowLarge = FALSE;
c0bbac3a 247 } else if (streql(argv[i], "-s")) {
1815bff5 248 SortZones = TRUE;
c0bbac3a 249 } else if (streql(argv[i], "-S")) {
1815bff5 250 SortZones = FALSE;
c0bbac3a 251 } else if (streql(argv[i], "-c")) {
1815bff5 252 ColFormat = TRUE;
c0bbac3a 253 } else if (streql(argv[i], "-C")) {
1815bff5 254 ColFormat = FALSE;
c0bbac3a 255 } else if (streql(argv[i], "-h")) {
639dadd6 256 usage(stdout);
c0bbac3a 257 } else if (streql(argv[i], "-H")) {
1815bff5 258 PrintHeader = FALSE;
c0bbac3a 259 } else if (streql(argv[i], "--")) {
1815bff5
A
260 i++;
261 break;
c0bbac3a 262 } else if (argv[i][0] == '-') {
639dadd6 263 usage(stderr);
c0bbac3a 264 } else {
1815bff5 265 break;
c0bbac3a 266 }
1815bff5
A
267 }
268
269 switch (argc - i) {
c0bbac3a 270 case 0:
1815bff5
A
271 zname = "";
272 znamelen = 0;
273 break;
274
c0bbac3a 275 case 1:
1815bff5
A
276 zname = argv[i];
277 znamelen = strlen(zname);
278 break;
279
c0bbac3a 280 default:
639dadd6 281 usage(stderr);
1815bff5
A
282 }
283
8459d725
A
284 if (ShowDeltas) {
285 SortZones = FALSE;
286 ColFormat = TRUE;
287 PrintHeader = TRUE;
288 }
289
639dadd6
A
290 if (ShowWasted) {
291 columns[COL_FRAG_SIZE].visible = true;
292 columns[COL_FREE_SIZE].visible = true;
293 }
294 if (ShowTotal) {
295 columns[COL_TOTAL_ALLOCS].visible = true;
8459d725
A
296 }
297
639dadd6
A
298 for (;;) {
299 kr = mach_memory_info(mach_host_self(),
c0bbac3a
A
300 &name, &nameCnt, &info, &infoCnt,
301 &wiredInfo, &wiredInfoCnt);
639dadd6 302 if (kr != KERN_SUCCESS) {
530d02b6 303 fprintf(stderr, "%s: mach_memory_info: %s (try running as root)\n",
c0bbac3a 304 program, mach_error_string(kr));
639dadd6
A
305 exit(1);
306 }
8459d725 307
639dadd6
A
308 if (nameCnt != infoCnt) {
309 fprintf(stderr, "%s: mach_zone_name/ mach_zone_info: counts not equal?\n",
c0bbac3a 310 program);
639dadd6
A
311 exit(1);
312 }
1815bff5 313
639dadd6
A
314 if (first_time) {
315 deltas = (char *)malloc(infoCnt);
316 max_info = (mach_zone_info_t *)malloc((infoCnt * sizeof *info));
317 }
8459d725 318
639dadd6 319 if (SortZones) {
c0bbac3a
A
320 for (i = 0; i < nameCnt - 1; i++) {
321 for (j = i + 1; j < nameCnt; j++) {
639dadd6
A
322 unsigned long long wastei, wastej;
323
324 wastei = (info[i].mzi_cur_size -
c0bbac3a
A
325 (info[i].mzi_elem_size *
326 info[i].mzi_count));
639dadd6 327 wastej = (info[j].mzi_cur_size -
c0bbac3a
A
328 (info[j].mzi_elem_size *
329 info[j].mzi_count));
639dadd6
A
330
331 if (wastej > wastei) {
332 mach_zone_info_t tinfo;
333 mach_zone_name_t tname;
334
335 tinfo = info[i];
336 info[i] = info[j];
337 info[j] = tinfo;
338
339 tname = name[i];
340 name[i] = name[j];
341 name[j] = tname;
342 }
1815bff5
A
343 }
344 }
8459d725 345 }
639dadd6
A
346
347 must_print = find_deltas(name, info, max_info, deltas, infoCnt, first_time);
348 zoneElements = 0;
349 if (must_print) {
350 if (ColFormat) {
c0bbac3a 351 if (!first_time) {
639dadd6 352 printf("\n");
c0bbac3a 353 }
639dadd6
A
354 colprintzoneheader();
355 }
356 for (i = 0; i < nameCnt; i++) {
357 if (deltas[i]) {
c0bbac3a 358 if (ColFormat) {
639dadd6 359 colprintzone(&name[i], &info[i]);
c0bbac3a 360 } else {
639dadd6 361 printzone(&name[i], &info[i]);
c0bbac3a 362 }
639dadd6
A
363 zoneElements += info[i].mzi_count;
364 }
8459d725
A
365 }
366 }
9726c137 367
639dadd6
A
368 if (ShowLarge && first_time) {
369 PrintLarge(wiredInfo, wiredInfoCnt, &info[0], &name[0],
c0bbac3a
A
370 nameCnt, zoneElements,
371 SortZones ? &SortSize : &SortName, ColFormat);
639dadd6 372 }
8459d725 373
639dadd6 374 first_time = 0;
8459d725 375
639dadd6
A
376 if ((name != NULL) && (nameCnt != 0)) {
377 kr = vm_deallocate(mach_task_self(), (vm_address_t) name,
c0bbac3a 378 (vm_size_t) (nameCnt * sizeof *name));
639dadd6
A
379 if (kr != KERN_SUCCESS) {
380 fprintf(stderr, "%s: vm_deallocate: %s\n",
c0bbac3a 381 program, mach_error_string(kr));
639dadd6
A
382 exit(1);
383 }
1815bff5 384 }
1815bff5 385
639dadd6
A
386 if ((info != NULL) && (infoCnt != 0)) {
387 kr = vm_deallocate(mach_task_self(), (vm_address_t) info,
c0bbac3a 388 (vm_size_t) (infoCnt * sizeof *info));
639dadd6
A
389 if (kr != KERN_SUCCESS) {
390 fprintf(stderr, "%s: vm_deallocate: %s\n",
c0bbac3a 391 program, mach_error_string(kr));
639dadd6
A
392 exit(1);
393 }
1815bff5 394 }
1815bff5 395
639dadd6
A
396 if ((wiredInfo != NULL) && (wiredInfoCnt != 0)) {
397 kr = vm_deallocate(mach_task_self(), (vm_address_t) wiredInfo,
c0bbac3a 398 (vm_size_t) (wiredInfoCnt * sizeof *wiredInfo));
639dadd6
A
399 if (kr != KERN_SUCCESS) {
400 fprintf(stderr, "%s: vm_deallocate: %s\n",
c0bbac3a 401 program, mach_error_string(kr));
639dadd6
A
402 exit(1);
403 }
9726c137 404 }
9726c137 405
c0bbac3a 406 if ((ShowWasted || ShowTotal) && PrintHeader && !ShowDeltas) {
639dadd6
A
407 printf("\nZONE TOTALS\n");
408 printf("---------------------------------------------\n");
409 printf("TOTAL SIZE = %llu\n", totalsize);
410 printf("TOTAL USED = %llu\n", totalused);
411 if (ShowWasted) {
412 printf("TOTAL WASTED = %llu\n", totalsize - totalused);
413 printf("TOTAL FRAGMENTED = %llu\n", totalfragmented);
414 printf("TOTAL COLLECTABLE = %llu\n", totalcollectable);
415 }
c0bbac3a 416 if (ShowTotal) {
639dadd6 417 printf("TOTAL ALLOCS = %llu\n", totalsum);
c0bbac3a 418 }
639dadd6 419 }
1815bff5 420
c0bbac3a 421 if (ShowDeltas == FALSE || last_time) {
639dadd6 422 break;
c0bbac3a 423 }
1815bff5 424
639dadd6
A
425 sleep(interval);
426 }
c0bbac3a 427 exit(0);
1815bff5
A
428}
429
430static boolean_t
9726c137 431substr(const char *a, size_t alen, const char *b, size_t blen)
1815bff5
A
432{
433 int i;
434
c0bbac3a
A
435 if (alen > blen) {
436 return FALSE;
437 }
cf37c299 438
c0bbac3a
A
439 for (i = 0; i <= blen - alen; i++) {
440 if (strneql(a, b + i, alen)) {
1815bff5 441 return TRUE;
c0bbac3a
A
442 }
443 }
1815bff5
A
444
445 return FALSE;
446}
447
448static void
639dadd6 449printzone(mach_zone_name_t *name, mach_zone_info_t *info)
1815bff5 450{
639dadd6 451 unsigned long long used, size, fragmented, collectable;
8459d725
A
452
453 printf("%.*s zone:\n", (int)sizeof name->mzn_name, name->mzn_name);
454 printf("\tcur_size: %lluK bytes (%llu elements)\n",
c0bbac3a
A
455 info->mzi_cur_size / 1024,
456 (info->mzi_elem_size == 0) ? 0 :
457 info->mzi_cur_size / info->mzi_elem_size);
8459d725 458 printf("\tmax_size: %lluK bytes (%llu elements)\n",
c0bbac3a
A
459 info->mzi_max_size / 1024,
460 (info->mzi_elem_size == 0) ? 0 :
461 info->mzi_max_size / info->mzi_elem_size);
8459d725 462 printf("\telem_size: %llu bytes\n",
c0bbac3a 463 info->mzi_elem_size);
8459d725 464 printf("\t# of elems: %llu\n",
c0bbac3a 465 info->mzi_count);
8459d725 466 printf("\talloc_size: %lluK bytes (%llu elements)\n",
c0bbac3a
A
467 info->mzi_alloc_size / 1024,
468 (info->mzi_elem_size == 0) ? 0 :
469 info->mzi_alloc_size / info->mzi_elem_size);
470 if (info->mzi_exhaustible) {
8459d725 471 printf("\tEXHAUSTIBLE\n");
c0bbac3a
A
472 }
473 if (GET_MZI_COLLECTABLE_FLAG(info->mzi_collectable)) {
1815bff5 474 printf("\tCOLLECTABLE\n");
c0bbac3a 475 }
1815bff5 476 if (ShowWasted) {
639dadd6
A
477 totalused += used = info->mzi_elem_size * info->mzi_count;
478 totalsize += size = info->mzi_cur_size;
479 totalcollectable += collectable = GET_MZI_COLLECTABLE_BYTES(info->mzi_collectable);
480 totalfragmented += fragmented = size - used - collectable;
8459d725 481 printf("\t\t\t\t\tWASTED: %llu\n", size - used);
639dadd6
A
482 printf("\t\t\t\t\tFRAGMENTED: %llu\n", fragmented);
483 printf("\t\t\t\t\tCOLLECTABLE: %llu\n", collectable);
8459d725
A
484 }
485 if (ShowTotal) {
639dadd6 486 totalsum += info->mzi_sum_size;
8459d725 487 printf("\t\t\t\t\tTOTAL: %llu\n", totalsum);
1815bff5
A
488 }
489}
490
1815bff5 491static void
639dadd6 492colprintzone(mach_zone_name_t *zone_name, mach_zone_info_t *info)
1815bff5 493{
8459d725 494 char *name = zone_name->mzn_name;
34d340d7 495 int j, namewidth;
639dadd6
A
496 unsigned long long used, size, fragmented, collectable;
497
498 namewidth = columns[COL_ZONE_NAME].colwidth;
1815bff5 499
1815bff5
A
500 for (j = 0; j < namewidth - 1 && name[j]; j++) {
501 if (name[j] == ' ') {
502 putchar('.');
503 } else {
504 putchar(name[j]);
505 }
506 }
507 if (j == namewidth - 1) {
508 if (name[j]) {
509 putchar('$');
510 } else {
511 putchar(' ');
512 }
513 } else {
514 for (; j < namewidth; j++) {
515 putchar(' ');
516 }
517 }
639dadd6
A
518
519
c0bbac3a
A
520#define PRINTCOL(value, index) \
521 if (columns[(index)].visible) { \
522 printf(" %*llu", columns[(index)].colwidth * columns[(index)].alignment, (value)); \
1815bff5 523 }
c0bbac3a
A
524#define PRINTCOLSTR(value, index) \
525 if (columns[(index)].visible) { \
526 printf(" %*s", columns[(index)].colwidth * columns[(index)].alignment, (value)); \
1815bff5 527 }
c0bbac3a
A
528#define PRINTCOLK(value, index) \
529 if (columns[(index)].visible) { \
530 printf(" %*lluK", (columns[(index)].colwidth - 1) * columns[(index)].alignment, (value) / 1024 ); \
1815bff5 531 }
c0bbac3a
A
532#define PRINTCOLSZ(value, index) \
533 if (columns[(index)].visible) { \
534 if ((value) < 1024) { \
535 printf(" %*lluB", (columns[(index)].colwidth - 1) * columns[(index)].alignment, (value)); \
536 } else { \
537 PRINTCOLK(value, index) \
538 } \
8459d725 539 }
639dadd6
A
540
541
542 PRINTCOL(info->mzi_elem_size, COL_ELEM_SIZE);
543 PRINTCOLK(info->mzi_cur_size, COL_CUR_SIZE);
544 if (info->mzi_max_size / 1024 > 9999999) {
545 /*
546 * Zones with preposterously large maximum sizes are shown with `-------'
547 * in the max size and max num elts fields.
548 */
549 PRINTCOLSTR("-------", COL_MAX_SIZE);
550 } else {
551 PRINTCOLK(info->mzi_max_size, COL_MAX_SIZE);
8459d725 552 }
639dadd6
A
553 PRINTCOL(info->mzi_cur_size / info->mzi_elem_size, COL_CUR_ELTS);
554 if (info->mzi_max_size / 1024 > 9999999) {
555 PRINTCOLSTR("-------", COL_MAX_ELTS);
556 } else {
557 PRINTCOL(info->mzi_max_size / info->mzi_elem_size, COL_MAX_ELTS);
558 }
559 PRINTCOL(info->mzi_count, COL_CUR_INUSE);
560 PRINTCOLK(info->mzi_alloc_size, COL_ALLOC_SIZE);
561 PRINTCOL(info->mzi_alloc_size / info->mzi_elem_size, COL_ALLOC_COUNT);
562
563 totalused += used = info->mzi_elem_size * info->mzi_count;
564 totalsize += size = info->mzi_cur_size;
565 totalsum += info->mzi_sum_size;
566 totalcollectable += collectable = GET_MZI_COLLECTABLE_BYTES(info->mzi_collectable);
567 totalfragmented += fragmented = size - used - collectable;
568
569 printf(" %c%c",
c0bbac3a
A
570 (info->mzi_exhaustible ? 'X' : ' '),
571 (GET_MZI_COLLECTABLE_FLAG(info->mzi_collectable) ? 'C' : ' '));
639dadd6
A
572
573 PRINTCOLSZ(fragmented, COL_FRAG_SIZE);
574 PRINTCOLSZ(collectable, COL_FREE_SIZE);
575 PRINTCOLSZ(info->mzi_sum_size, COL_TOTAL_ALLOCS);
576
8459d725 577 printf("\n");
1815bff5
A
578}
579
639dadd6 580
1815bff5 581static void
8459d725 582colprintzoneheader(void)
1815bff5 583{
639dadd6
A
584 int i, totalwidth = 0;
585
c0bbac3a 586 if (!PrintHeader) {
1815bff5
A
587 return;
588 }
639dadd6
A
589
590 for (i = 0; i < COL_MAX; i++) {
591 if (columns[i].visible) {
592 printf("%*s ", columns[i].colwidth * columns[i].alignment, columns[i].line1);
593 }
594 }
595 printf("\n");
596
597 for (i = 0; i < COL_MAX; i++) {
598 if (columns[i].visible) {
599 printf("%*s ", columns[i].colwidth * columns[i].alignment, columns[i].line2);
600 totalwidth += (columns[i].colwidth + 1);
601 }
602 }
603
604 printf("\n");
605 for (i = 0; i < totalwidth; i++) {
606 printf("-");
607 }
8459d725
A
608 printf("\n");
609}
610
611int
639dadd6 612find_deltas(mach_zone_name_t *name, mach_zone_info_t *info, mach_zone_info_t *max_info,
c0bbac3a 613 char *deltas, int cnt, int first_time)
8459d725 614{
c0bbac3a
A
615 int i;
616 int found_one = 0;
617
618 for (i = 0; i < cnt; i++) {
619 deltas[i] = 0;
620 if (substr(zname, znamelen, name[i].mzn_name,
621 strnlen(name[i].mzn_name, sizeof name[i].mzn_name))) {
622 if (first_time || info->mzi_cur_size > max_info->mzi_cur_size ||
623 (ShowTotal && ((info->mzi_sum_size >> 1) > max_info->mzi_sum_size))) {
624 max_info->mzi_cur_size = info->mzi_cur_size;
625 max_info->mzi_sum_size = info->mzi_sum_size;
626 deltas[i] = 1;
627 found_one = 1;
628 }
629 }
630 info++;
631 max_info++;
632 }
633 return found_one;
1815bff5 634}
9726c137
A
635
636/*********************************************************************
637*********************************************************************/
638
639static char *
640kern_vm_tag_name(uint64_t tag)
641{
c0bbac3a
A
642 char * result;
643 const char * name;
644 switch (tag) {
645 case (VM_KERN_MEMORY_NONE): name = "VM_KERN_MEMORY_NONE"; break;
646 case (VM_KERN_MEMORY_OSFMK): name = "VM_KERN_MEMORY_OSFMK"; break;
647 case (VM_KERN_MEMORY_BSD): name = "VM_KERN_MEMORY_BSD"; break;
648 case (VM_KERN_MEMORY_IOKIT): name = "VM_KERN_MEMORY_IOKIT"; break;
649 case (VM_KERN_MEMORY_LIBKERN): name = "VM_KERN_MEMORY_LIBKERN"; break;
650 case (VM_KERN_MEMORY_OSKEXT): name = "VM_KERN_MEMORY_OSKEXT"; break;
651 case (VM_KERN_MEMORY_KEXT): name = "VM_KERN_MEMORY_KEXT"; break;
652 case (VM_KERN_MEMORY_IPC): name = "VM_KERN_MEMORY_IPC"; break;
653 case (VM_KERN_MEMORY_STACK): name = "VM_KERN_MEMORY_STACK"; break;
654 case (VM_KERN_MEMORY_CPU): name = "VM_KERN_MEMORY_CPU"; break;
655 case (VM_KERN_MEMORY_PMAP): name = "VM_KERN_MEMORY_PMAP"; break;
656 case (VM_KERN_MEMORY_PTE): name = "VM_KERN_MEMORY_PTE"; break;
657 case (VM_KERN_MEMORY_ZONE): name = "VM_KERN_MEMORY_ZONE"; break;
658 case (VM_KERN_MEMORY_KALLOC): name = "VM_KERN_MEMORY_KALLOC"; break;
659 case (VM_KERN_MEMORY_COMPRESSOR): name = "VM_KERN_MEMORY_COMPRESSOR"; break;
660 case (VM_KERN_MEMORY_COMPRESSED_DATA): name = "VM_KERN_MEMORY_COMPRESSED_DATA"; break;
661 case (VM_KERN_MEMORY_PHANTOM_CACHE): name = "VM_KERN_MEMORY_PHANTOM_CACHE"; break;
662 case (VM_KERN_MEMORY_WAITQ): name = "VM_KERN_MEMORY_WAITQ"; break;
663 case (VM_KERN_MEMORY_DIAG): name = "VM_KERN_MEMORY_DIAG"; break;
664 case (VM_KERN_MEMORY_LOG): name = "VM_KERN_MEMORY_LOG"; break;
665 case (VM_KERN_MEMORY_FILE): name = "VM_KERN_MEMORY_FILE"; break;
666 case (VM_KERN_MEMORY_MBUF): name = "VM_KERN_MEMORY_MBUF"; break;
667 case (VM_KERN_MEMORY_UBC): name = "VM_KERN_MEMORY_UBC"; break;
668 case (VM_KERN_MEMORY_SECURITY): name = "VM_KERN_MEMORY_SECURITY"; break;
669 case (VM_KERN_MEMORY_MLOCK): name = "VM_KERN_MEMORY_MLOCK"; break;
670 case (VM_KERN_MEMORY_REASON): name = "VM_KERN_MEMORY_REASON"; break;
671 case (VM_KERN_MEMORY_SKYWALK): name = "VM_KERN_MEMORY_SKYWALK"; break;
672 case (VM_KERN_MEMORY_LTABLE): name = "VM_KERN_MEMORY_LTABLE"; break;
00bf83c0 673 case (VM_KERN_MEMORY_HV): name = "VM_KERN_MEMORY_HV"; break;
c0bbac3a 674 case (VM_KERN_MEMORY_ANY): name = "VM_KERN_MEMORY_ANY"; break;
00bf83c0 675 case (VM_KERN_MEMORY_RETIRED): name = "VM_KERN_MEMORY_RETIRED"; break;
c0bbac3a
A
676 default: name = NULL; break;
677 }
678 if (name) {
679 asprintf(&result, "%s", name);
680 } else {
681 asprintf(&result, "VM_KERN_MEMORY_%lld", tag);
682 }
683 return result;
684}
9726c137 685
cf37c299 686static char *
9726c137
A
687kern_vm_counter_name(uint64_t tag)
688{
c0bbac3a
A
689 char * result;
690 const char * name;
691 switch (tag) {
692 case (VM_KERN_COUNT_MANAGED): name = "VM_KERN_COUNT_MANAGED"; break;
693 case (VM_KERN_COUNT_RESERVED): name = "VM_KERN_COUNT_RESERVED"; break;
694 case (VM_KERN_COUNT_WIRED): name = "VM_KERN_COUNT_WIRED"; break;
695 case (VM_KERN_COUNT_WIRED_BOOT): name = "VM_KERN_COUNT_WIRED_BOOT"; break;
696 case (VM_KERN_COUNT_WIRED_MANAGED): name = "VM_KERN_COUNT_WIRED_MANAGED"; break;
697 case (VM_KERN_COUNT_STOLEN): name = "VM_KERN_COUNT_STOLEN"; break;
698 case (VM_KERN_COUNT_BOOT_STOLEN): name = "VM_KERN_COUNT_BOOT_STOLEN"; break;
699 case (VM_KERN_COUNT_LOPAGE): name = "VM_KERN_COUNT_LOPAGE"; break;
700 case (VM_KERN_COUNT_MAP_KERNEL): name = "VM_KERN_COUNT_MAP_KERNEL"; break;
701 case (VM_KERN_COUNT_MAP_ZONE): name = "VM_KERN_COUNT_MAP_ZONE"; break;
702 case (VM_KERN_COUNT_MAP_KALLOC): name = "VM_KERN_COUNT_MAP_KALLOC"; break;
703 case (VM_KERN_COUNT_WIRED_STATIC_KERNELCACHE):
704 name = "VM_KERN_COUNT_WIRED_STATIC_KERNELCACHE";
705 break;
706 default: name = NULL; break;
707 }
708 if (name) {
709 asprintf(&result, "%s", name);
710 } else {
711 asprintf(&result, "VM_KERN_COUNT_%lld", tag);
712 }
713 return result;
9726c137
A
714}
715
716static void
717MakeLoadTagKeys(const void * key, const void * value, void * context)
718{
c0bbac3a
A
719 CFMutableDictionaryRef newDict = context;
720 CFDictionaryRef kextInfo = value;
721 CFNumberRef loadTag;
722 uint32_t loadTagValue;
723
724 loadTag = (CFNumberRef)CFDictionaryGetValue(kextInfo, CFSTR(kOSBundleLoadTagKey));
725 CFNumberGetValue(loadTag, kCFNumberSInt32Type, &loadTagValue);
726 key = (const void *)(uintptr_t) loadTagValue;
727 CFDictionarySetValue(newDict, key, value);
9726c137
A
728}
729
c0bbac3a 730static CSSymbolicatorRef gSym;
9726c137
A
731static CFMutableDictionaryRef gTagDict;
732static mach_memory_info_t * gSites;
733
cf37c299 734static char *
887d5eed 735GetSiteName(int siteIdx, mach_zone_name_t * zoneNames, unsigned int zoneNamesCnt)
9726c137 736{
c0bbac3a
A
737 const char * name;
738 uintptr_t kmodid;
739 char * result;
740 char * append;
741 mach_vm_address_t addr;
742 CFDictionaryRef kextInfo;
743 CFStringRef bundleID;
744 uint32_t type;
745
746 const mach_memory_info_t * site;
747 const char * fileName;
748 CSSymbolRef symbol;
749 const char * symbolName;
750 CSSourceInfoRef sourceInfo;
751
752 name = NULL;
753 result = NULL;
754 site = &gSites[siteIdx];
755 addr = site->site;
756 type = (VM_KERN_SITE_TYPE & site->flags);
757 kmodid = 0;
758
759 if (VM_KERN_SITE_NAMED & site->flags) {
760 asprintf(&result, "%s", &site->name[0]);
761 } else {
762 switch (type) {
763 case VM_KERN_SITE_TAG:
764 result = kern_vm_tag_name(addr);
765 break;
766
767 case VM_KERN_SITE_COUNTER:
768 result = kern_vm_counter_name(addr);
769 break;
770
771 case VM_KERN_SITE_KMOD:
772
773 kmodid = (uintptr_t) addr;
774 kextInfo = CFDictionaryGetValue(gTagDict, (const void *)kmodid);
775 if (kextInfo) {
776 bundleID = (CFStringRef)CFDictionaryGetValue(kextInfo, kCFBundleIdentifierKey);
777 name = CFStringGetCStringPtr(bundleID, kCFStringEncodingUTF8);
778 // wiredSize = (CFNumberRef)CFDictionaryGetValue(kextInfo, CFSTR(kOSBundleWiredSizeKey));
779 }
780
781 if (name) {
782 asprintf(&result, "%s", name);
783 } else {
784 asprintf(&result, "(unloaded kmod)");
785 }
786 break;
787
788 case VM_KERN_SITE_KERNEL:
789 symbolName = NULL;
790 if (addr) {
791 symbol = CSSymbolicatorGetSymbolWithAddressAtTime(gSym, addr, kCSNow);
792 symbolName = CSSymbolGetName(symbol);
793 }
794 if (symbolName) {
795 asprintf(&result, "%s", symbolName);
796 sourceInfo = CSSymbolicatorGetSourceInfoWithAddressAtTime(gSym, addr, kCSNow);
797 fileName = CSSourceInfoGetPath(sourceInfo);
798 if (fileName) {
799 printf(" (%s:%d)", fileName, CSSourceInfoGetLineNumber(sourceInfo));
800 }
801 } else {
802 asprintf(&result, "site 0x%qx", addr);
803 }
804 break;
805 default:
806 asprintf(&result, "");
807 break;
808 }
809 }
810
811 if (result
812 && (VM_KERN_SITE_ZONE & site->flags)
813 && zoneNames
814 && (site->zone < zoneNamesCnt)) {
815 size_t namelen, zonelen;
816 namelen = strlen(result);
817 zonelen = strnlen(zoneNames[site->zone].mzn_name, sizeof(zoneNames[site->zone].mzn_name));
818 if (((namelen + zonelen) > 61) && (zonelen < 61)) {
819 namelen = (61 - zonelen);
820 }
821 asprintf(&append, "%.*s[%.*s]",
887d5eed
A
822 (int)namelen,
823 result,
824 (int)zonelen,
825 zoneNames[site->zone].mzn_name);
c0bbac3a
A
826 free(result);
827 result = append;
828 }
829 if (result && kmodid) {
830 asprintf(&append, "%-64s%3ld", result, kmodid);
831 free(result);
832 result = append;
833 }
834
835 return result;
9726c137
A
836}
837
c0bbac3a
A
838struct CompareThunk {
839 mach_zone_name_t *zoneNames;
840 unsigned int zoneNamesCnt;
887d5eed
A
841};
842
cf37c299 843static int
887d5eed 844SortName(void * thunk, const void * left, const void * right)
9726c137 845{
c0bbac3a
A
846 const struct CompareThunk * t = (typeof(t))thunk;
847 const int * idxL;
848 const int * idxR;
849 char * l;
850 char * r;
851 CFStringRef lcf;
852 CFStringRef rcf;
853 int result;
854
855 idxL = (typeof(idxL))left;
856 idxR = (typeof(idxR))right;
857 l = GetSiteName(*idxL, t->zoneNames, t->zoneNamesCnt);
858 r = GetSiteName(*idxR, t->zoneNames, t->zoneNamesCnt);
859
860 lcf = CFStringCreateWithCString(kCFAllocatorDefault, l, kCFStringEncodingUTF8);
861 rcf = CFStringCreateWithCString(kCFAllocatorDefault, r, kCFStringEncodingUTF8);
862
863 result = (int) CFStringCompareWithOptionsAndLocale(lcf, rcf, CFRangeMake(0, CFStringGetLength(lcf)), kCFCompareNumerically, NULL);
864
865 CFRelease(lcf);
866 CFRelease(rcf);
867 free(l);
868 free(r);
869
870 return result;
9726c137
A
871}
872
cf37c299 873static int
887d5eed 874SortSize(void * thunk, const void * left, const void * right)
9726c137 875{
c0bbac3a
A
876 const mach_memory_info_t * siteL;
877 const mach_memory_info_t * siteR;
878 const int * idxL;
879 const int * idxR;
880
881 idxL = (typeof(idxL))left;
882 idxR = (typeof(idxR))right;
883 siteL = &gSites[*idxL];
884 siteR = &gSites[*idxR];
885
886 if (siteL->size > siteR->size) {
887 return -1;
888 } else if (siteL->size < siteR->size) {
889 return 1;
890 }
891 return 0;
9726c137
A
892}
893
894
895static void
896PrintLarge(mach_memory_info_t *wiredInfo, unsigned int wiredInfoCnt,
c0bbac3a
A
897 mach_zone_info_t *zoneInfo, mach_zone_name_t *zoneNames,
898 unsigned int zoneCnt, uint64_t zoneElements,
899 int (*func)(void *, const void *, const void *), boolean_t column)
9726c137 900{
c0bbac3a
A
901 uint64_t zonetotal;
902 uint64_t top_wired;
903 uint64_t size;
904 uint64_t elemsTagged;
9726c137 905
c0bbac3a
A
906 CFDictionaryRef allKexts;
907 unsigned int idx, site, first;
908 int sorted[wiredInfoCnt];
909 char totalstr[40];
910 char * name;
911 bool headerPrinted;
9726c137 912
c0bbac3a 913 zonetotal = totalsize;
9726c137 914
c0bbac3a 915 gSites = wiredInfo;
9726c137 916
c0bbac3a 917 gSym = CSSymbolicatorCreateWithMachKernel();
cf37c299 918
c0bbac3a
A
919 allKexts = OSKextCopyLoadedKextInfo(NULL, NULL);
920 gTagDict = CFDictionaryCreateMutable(
921 kCFAllocatorDefault, (CFIndex) 0,
922 (CFDictionaryKeyCallBacks *) 0,
923 &kCFTypeDictionaryValueCallBacks);
9726c137 924
c0bbac3a
A
925 CFDictionaryApplyFunction(allKexts, &MakeLoadTagKeys, gTagDict);
926 CFRelease(allKexts);
9726c137 927
c0bbac3a 928 top_wired = 0;
9726c137 929
c0bbac3a
A
930 for (idx = 0; idx < wiredInfoCnt; idx++) {
931 sorted[idx] = idx;
932 }
933 first = 0; // VM_KERN_MEMORY_FIRST_DYNAMIC
934 struct CompareThunk thunk;
935 thunk.zoneNames = zoneNames;
936 thunk.zoneNamesCnt = zoneCnt;
937 qsort_r(&sorted[first],
cf37c299
A
938 wiredInfoCnt - first,
939 sizeof(sorted[0]),
887d5eed 940 &thunk,
9726c137
A
941 func);
942
c0bbac3a
A
943 elemsTagged = 0;
944 for (headerPrinted = false, idx = 0; idx < wiredInfoCnt; idx++) {
945 site = sorted[idx];
946 if ((VM_KERN_SITE_COUNTER & gSites[site].flags)
947 && (VM_KERN_COUNT_WIRED == gSites[site].site)) {
948 top_wired = gSites[site].size;
949 }
950 if (VM_KERN_SITE_HIDE & gSites[site].flags) {
951 continue;
952 }
953 if (!((VM_KERN_SITE_WIRED | VM_KERN_SITE_ZONE) & gSites[site].flags)) {
954 continue;
955 }
887d5eed 956
c0bbac3a
A
957 if ((VM_KERN_SITE_ZONE & gSites[site].flags)
958 && gSites[site].zone < zoneCnt) {
959 elemsTagged += gSites[site].size / zoneInfo[gSites[site].zone].mzi_elem_size;
960 }
887d5eed 961
c0bbac3a
A
962 if ((gSites[site].size < 1024) && (gSites[site].peak < 1024)) {
963 continue;
964 }
9726c137 965
c0bbac3a
A
966 name = GetSiteName(site, zoneNames, zoneCnt);
967 if (!substr(zname, znamelen, name, strlen(name))) {
968 continue;
969 }
970 if (!headerPrinted) {
971 printf("-------------------------------------------------------------------------------------------------------------\n");
972 printf(" kmod vm peak cur\n");
973 printf("wired memory id tag size waste size\n");
974 printf("-------------------------------------------------------------------------------------------------------------\n");
975 headerPrinted = true;
976 }
977 printf("%-67s", name);
978 free(name);
979 printf("%12d", gSites[site].tag);
9726c137 980
c0bbac3a
A
981 if (gSites[site].peak) {
982 PRINTK(" %10llu", gSites[site].peak);
983 } else {
984 printf(" %11s", "");
985 }
887d5eed 986
c0bbac3a
A
987 if (gSites[site].collectable_bytes) {
988 PRINTK(" %5llu", gSites[site].collectable_bytes);
989 } else {
990 printf(" %6s", "");
991 }
887d5eed 992
c0bbac3a 993 PRINTK(" %9llu", gSites[site].size);
887d5eed 994
c0bbac3a
A
995 if (!(VM_KERN_SITE_ZONE & gSites[site].flags)) {
996 totalsize += gSites[site].size;
997 }
9726c137 998
c0bbac3a
A
999 printf("\n");
1000 }
9726c137 1001
c0bbac3a
A
1002 if (!znamelen) {
1003 printf("%-67s", "zones");
1004 printf("%12s", "");
1005 printf(" %11s", "");
1006 printf(" %6s", "");
1007 PRINTK(" %9llu", zonetotal);
1008 printf("\n");
1009 }
1010 if (headerPrinted) {
1011 if (elemsTagged) {
1012 snprintf(totalstr, sizeof(totalstr), "%lld of %lld", elemsTagged, zoneElements);
1013 printf("zone tags%100s\n", totalstr);
1014 }
1015 snprintf(totalstr, sizeof(totalstr), "%6.2fM of %6.2fM", totalsize / 1024.0 / 1024.0, top_wired / 1024.0 / 1024.0);
1016 printf("total%104s\n", totalstr);
1017 }
1018 for (headerPrinted = false, idx = 0; idx < wiredInfoCnt; idx++) {
1019 site = sorted[idx];
1020 size = gSites[site].mapped;
1021 if (!size) {
1022 continue;
1023 }
1024 if (VM_KERN_SITE_HIDE & gSites[site].flags) {
1025 continue;
1026 }
1027 if ((size == gSites[site].size)
1028 && ((VM_KERN_SITE_WIRED | VM_KERN_SITE_ZONE) & gSites[site].flags)) {
1029 continue;
1030 }
1031
1032 name = GetSiteName(site, NULL, 0);
1033 if (!substr(zname, znamelen, name, strlen(name))) {
1034 continue;
1035 }
1036 if (!headerPrinted) {
1037 printf("-------------------------------------------------------------------------------------------------------------\n");
1038 printf(" largest peak cur\n");
1039 printf("maps free free size size\n");
1040 printf("-------------------------------------------------------------------------------------------------------------\n");
1041 headerPrinted = true;
1042 }
1043 printf("%-55s", name);
1044 free(name);
1045
1046 if (gSites[site].free) {
1047 PRINTK(" %10llu", gSites[site].free);
1048 } else {
1049 printf(" %11s", "");
1050 }
1051 if (gSites[site].largest) {
1052 PRINTK(" %10llu", gSites[site].largest);
1053 } else {
1054 printf(" %11s", "");
1055 }
1056 if (gSites[site].peak) {
1057 PRINTK(" %10llu", gSites[site].peak);
1058 } else {
1059 printf(" %11s", "");
1060 }
1061 PRINTK(" %16llu", size);
1062
1063 printf("\n");
1064 }
1065 for (headerPrinted = false, idx = 0; idx < wiredInfoCnt; idx++) {
1066 site = sorted[idx];
1067 size = gSites[site].size;
1068 if (!size || !(VM_KERN_SITE_ZONE_VIEW & gSites[site].flags)) {
1069 continue;
1070 }
1071
1072 name = GetSiteName(site, NULL, 0);
1073 if (!substr(zname, znamelen, name, strlen(name))) {
1074 continue;
1075 }
1076 if (!headerPrinted) {
1077 printf("-------------------------------------------------------------------------------------------------------------\n");
1078 printf(" cur\n");
1079 printf("zone views inuse\n");
1080 printf("-------------------------------------------------------------------------------------------------------------\n");
1081 headerPrinted = true;
1082 }
1083 printf("%-55s", name);
1084 free(name);
1085
1086 printf(" %11s", "");
1087 printf(" %11s", "");
1088 printf(" %11s", "");
1089 PRINTK(" %16llu", size);
1090
1091 printf("\n");
1092 }
639dadd6 1093 totalsize = zonetotal;
9726c137 1094}