1153114Srwatson/*- 2153114Srwatson * Copyright (c) 2005 Robert N. M. Watson 3153114Srwatson * All rights reserved. 4153114Srwatson * 5153114Srwatson * Redistribution and use in source and binary forms, with or without 6153114Srwatson * modification, are permitted provided that the following conditions 7153114Srwatson * are met: 8153114Srwatson * 1. Redistributions of source code must retain the above copyright 9153114Srwatson * notice, this list of conditions and the following disclaimer. 10153114Srwatson * 2. Redistributions in binary form must reproduce the above copyright 11153114Srwatson * notice, this list of conditions and the following disclaimer in the 12153114Srwatson * documentation and/or other materials provided with the distribution. 13153114Srwatson * 14153114Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15153114Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16153114Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17153114Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18153114Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19153114Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20153114Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21153114Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22153114Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23153114Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24153114Srwatson * SUCH DAMAGE. 25153114Srwatson * 26153114Srwatson * $FreeBSD: releng/10.3/tools/tools/umastat/umastat.c 260307 2014-01-04 23:45:55Z mav $ 27153114Srwatson */ 28153114Srwatson 29153114Srwatson#include <sys/param.h> 30153114Srwatson 31153114Srwatson#define LIBMEMSTAT /* Cause vm_page.h not to include opt_vmpage.h */ 32153114Srwatson#include <vm/vm.h> 33153114Srwatson#include <vm/vm_page.h> 34153114Srwatson 35153114Srwatson#include <vm/uma.h> 36153114Srwatson#include <vm/uma_int.h> 37153114Srwatson 38153114Srwatson#include <err.h> 39153114Srwatson#include <kvm.h> 40212949Savg#include <limits.h> 41153114Srwatson#include <memstat.h> 42153114Srwatson#include <stdio.h> 43153114Srwatson#include <stdlib.h> 44166539Spjd#include <unistd.h> 45153114Srwatson 46153114Srwatsonstatic struct nlist namelist[] = { 47153233Srwatson#define X_UMA_KEGS 0 48153114Srwatson { .n_name = "_uma_kegs" }, 49153233Srwatson#define X_MP_MAXCPUS 1 50153233Srwatson { .n_name = "_mp_maxcpus" }, 51153233Srwatson#define X_MP_MAXID 2 52153114Srwatson { .n_name = "_mp_maxid" }, 53153233Srwatson#define X_ALLCPU 3 54153114Srwatson { .n_name = "_all_cpus" }, 55153114Srwatson { .n_name = "" }, 56153114Srwatson}; 57153114Srwatson 58153114Srwatsonstatic void 59153114Srwatsonusage(void) 60153114Srwatson{ 61153114Srwatson 62166539Spjd fprintf(stderr, "umastat [-M core [-N system]]\n"); 63153114Srwatson exit(-1); 64153114Srwatson} 65153114Srwatson 66153114Srwatsonstatic int 67153114Srwatsonkread(kvm_t *kvm, void *kvm_pointer, void *address, size_t size, 68153114Srwatson size_t offset) 69153114Srwatson{ 70153114Srwatson ssize_t ret; 71153114Srwatson 72153114Srwatson ret = kvm_read(kvm, (unsigned long)kvm_pointer + offset, address, 73153114Srwatson size); 74153114Srwatson if (ret < 0) 75153114Srwatson return (MEMSTAT_ERROR_KVM); 76153114Srwatson if ((size_t)ret != size) 77153114Srwatson return (MEMSTAT_ERROR_KVM_SHORTREAD); 78153114Srwatson return (0); 79153114Srwatson} 80153114Srwatson 81153114Srwatsonstatic int 82249430Spluknetkread_string(kvm_t *kvm, const void *kvm_pointer, char *buffer, int buflen) 83153114Srwatson{ 84153114Srwatson ssize_t ret; 85153114Srwatson int i; 86153114Srwatson 87153114Srwatson for (i = 0; i < buflen; i++) { 88153114Srwatson ret = kvm_read(kvm, (unsigned long)kvm_pointer + i, 89153114Srwatson &(buffer[i]), sizeof(char)); 90153114Srwatson if (ret < 0) 91153114Srwatson return (MEMSTAT_ERROR_KVM); 92153114Srwatson if ((size_t)ret != sizeof(char)) 93153114Srwatson return (MEMSTAT_ERROR_KVM_SHORTREAD); 94153114Srwatson if (buffer[i] == '\0') 95153114Srwatson return (0); 96153114Srwatson } 97153114Srwatson /* Truncate. */ 98153114Srwatson buffer[i-1] = '\0'; 99153114Srwatson return (0); 100153114Srwatson} 101153114Srwatson 102153114Srwatsonstatic int 103153114Srwatsonkread_symbol(kvm_t *kvm, int index, void *address, size_t size, 104153114Srwatson size_t offset) 105153114Srwatson{ 106153114Srwatson ssize_t ret; 107153114Srwatson 108153114Srwatson ret = kvm_read(kvm, namelist[index].n_value + offset, address, size); 109153114Srwatson if (ret < 0) 110153114Srwatson return (MEMSTAT_ERROR_KVM); 111153114Srwatson if ((size_t)ret != size) 112153114Srwatson return (MEMSTAT_ERROR_KVM_SHORTREAD); 113153114Srwatson return (0); 114153114Srwatson} 115153114Srwatson 116153114Srwatsonstatic const struct flaginfo { 117153114Srwatson u_int32_t fi_flag; 118153114Srwatson const char *fi_name; 119153114Srwatson} flaginfo[] = { 120260307Smav { UMA_ZFLAG_MULTI, "multi" }, 121260307Smav { UMA_ZFLAG_DRAINING, "draining" }, 122260307Smav { UMA_ZFLAG_BUCKET, "bucket" }, 123153114Srwatson { UMA_ZFLAG_INTERNAL, "internal" }, 124153114Srwatson { UMA_ZFLAG_FULL, "full" }, 125153114Srwatson { UMA_ZFLAG_CACHEONLY, "cacheonly" }, 126153114Srwatson { UMA_ZONE_PAGEABLE, "pageable" }, 127153114Srwatson { UMA_ZONE_ZINIT, "zinit" }, 128153114Srwatson { UMA_ZONE_STATIC, "static" }, 129153114Srwatson { UMA_ZONE_OFFPAGE, "offpage" }, 130153114Srwatson { UMA_ZONE_MALLOC, "malloc" }, 131153114Srwatson { UMA_ZONE_NOFREE, "nofree" }, 132153114Srwatson { UMA_ZONE_MTXCLASS, "mtxclass" }, 133153114Srwatson { UMA_ZONE_VM, "vm" }, 134153114Srwatson { UMA_ZONE_HASH, "hash" }, 135153114Srwatson { UMA_ZONE_SECONDARY, "secondary" }, 136153114Srwatson { UMA_ZONE_REFCNT, "refcnt" }, 137153114Srwatson { UMA_ZONE_MAXBUCKET, "maxbucket" }, 138260307Smav { UMA_ZONE_CACHESPREAD, "cachespread" }, 139260307Smav { UMA_ZONE_VTOSLAB, "vtoslab" }, 140260307Smav { UMA_ZONE_NODUMP, "nodump" }, 141260307Smav { UMA_ZONE_PCPU, "pcpu" }, 142153114Srwatson}; 143153114Srwatsonstatic const int flaginfo_count = sizeof(flaginfo) / sizeof(struct flaginfo); 144153114Srwatson 145153114Srwatsonstatic void 146153114Srwatsonuma_print_keg_flags(struct uma_keg *ukp, const char *spaces) 147153114Srwatson{ 148153114Srwatson int count, i; 149153114Srwatson 150153114Srwatson if (!ukp->uk_flags) { 151153114Srwatson printf("%suk_flags = 0;\n", spaces); 152153114Srwatson return; 153153114Srwatson } 154153114Srwatson 155153114Srwatson printf("%suk_flags = ", spaces); 156153114Srwatson for (i = 0, count = 0; i < flaginfo_count; i++) { 157153114Srwatson if (ukp->uk_flags & flaginfo[i].fi_flag) { 158153114Srwatson if (count++ > 0) 159153114Srwatson printf(" | "); 160249430Spluknet printf("%s", flaginfo[i].fi_name); 161153114Srwatson } 162153114Srwatson 163153114Srwatson } 164153114Srwatson printf(";\n"); 165153114Srwatson} 166153114Srwatson 167153114Srwatsonstatic void 168153114Srwatsonuma_print_keg_align(struct uma_keg *ukp, const char *spaces) 169153114Srwatson{ 170153114Srwatson 171153114Srwatson switch(ukp->uk_align) { 172153114Srwatson case UMA_ALIGN_PTR: 173153114Srwatson printf("%suk_align = UMA_ALIGN_PTR;\n", spaces); 174153114Srwatson break; 175153114Srwatson 176153114Srwatson#if 0 177153114Srwatson case UMA_ALIGN_LONG: 178153114Srwatson printf("%suk_align = UMA_ALIGN_LONG;\n", spaces); 179153114Srwatson break; 180153114Srwatson 181153114Srwatson case UMA_ALIGN_INT: 182153114Srwatson printf("%suk_align = UMA_ALIGN_INT;\n", spaces); 183153114Srwatson break; 184153114Srwatson#endif 185153114Srwatson 186153114Srwatson case UMA_ALIGN_SHORT: 187153114Srwatson printf("%suk_align = UMA_ALIGN_SHORT;\n", spaces); 188153114Srwatson break; 189153114Srwatson 190153114Srwatson case UMA_ALIGN_CHAR: 191153114Srwatson printf("%suk_align = UMA_ALIGN_CHAR;\n", spaces); 192153114Srwatson break; 193153114Srwatson 194153114Srwatson case UMA_ALIGN_CACHE: 195153114Srwatson printf("%suk_align = UMA_ALIGN_CACHE;\n", spaces); 196153114Srwatson break; 197153114Srwatson 198153114Srwatson default: 199153114Srwatson printf("%suk_align = %d\n", spaces, ukp->uk_align); 200153114Srwatson } 201153114Srwatson} 202153114Srwatson 203153114SrwatsonLIST_HEAD(bucketlist, uma_bucket); 204153114Srwatson 205153114Srwatsonstatic void 206212949Savguma_print_bucket(struct uma_bucket *ubp, const char *spaces __unused) 207153114Srwatson{ 208153114Srwatson 209153114Srwatson printf("{ ub_cnt = %d, ub_entries = %d }", ubp->ub_cnt, 210153114Srwatson ubp->ub_entries); 211153114Srwatson} 212153114Srwatson 213153114Srwatsonstatic void 214153114Srwatsonuma_print_bucketlist(kvm_t *kvm, struct bucketlist *bucketlist, 215153114Srwatson const char *name, const char *spaces) 216153114Srwatson{ 217153114Srwatson struct uma_bucket *ubp, ub; 218153114Srwatson uint64_t total_entries, total_cnt; 219153114Srwatson int count, ret; 220153114Srwatson 221153114Srwatson printf("%s%s {", spaces, name); 222153114Srwatson 223153114Srwatson total_entries = total_cnt = 0; 224153114Srwatson count = 0; 225153114Srwatson for (ubp = LIST_FIRST(bucketlist); ubp != NULL; ubp = 226153114Srwatson LIST_NEXT(&ub, ub_link)) { 227153114Srwatson ret = kread(kvm, ubp, &ub, sizeof(ub), 0); 228153114Srwatson if (ret != 0) 229153114Srwatson errx(-1, "uma_print_bucketlist: %s", kvm_geterr(kvm)); 230153114Srwatson if (count % 2 == 0) 231153114Srwatson printf("\n%s ", spaces); 232153114Srwatson uma_print_bucket(&ub, ""); 233153114Srwatson printf(" "); 234153114Srwatson total_entries += ub.ub_entries; 235153114Srwatson total_cnt += ub.ub_cnt; 236153114Srwatson count++; 237153114Srwatson } 238153114Srwatson 239153114Srwatson printf("\n"); 240212932Savg printf("%s}; // total cnt %ju, total entries %ju\n", spaces, 241153114Srwatson total_cnt, total_entries); 242153114Srwatson} 243153114Srwatson 244153114Srwatsonstatic void 245153114Srwatsonuma_print_cache(kvm_t *kvm, struct uma_cache *cache, const char *name, 246153235Srwatson int cpu, const char *spaces, int *ub_cnt_add, int *ub_entries_add) 247153114Srwatson{ 248153114Srwatson struct uma_bucket ub; 249153114Srwatson int ret; 250153114Srwatson 251153114Srwatson printf("%s%s[%d] = {\n", spaces, name, cpu); 252212932Savg printf("%s uc_frees = %ju;\n", spaces, cache->uc_frees); 253212932Savg printf("%s uc_allocs = %ju;\n", spaces, cache->uc_allocs); 254153114Srwatson 255153114Srwatson if (cache->uc_freebucket != NULL) { 256153114Srwatson ret = kread(kvm, cache->uc_freebucket, &ub, sizeof(ub), 0); 257153114Srwatson if (ret != 0) 258153114Srwatson errx(-1, "uma_print_cache: %s", kvm_geterr(kvm)); 259153114Srwatson printf("%s uc_freebucket ", spaces); 260153114Srwatson uma_print_bucket(&ub, spaces); 261153114Srwatson printf(";\n"); 262153235Srwatson if (ub_cnt_add != NULL) 263153235Srwatson *ub_cnt_add += ub.ub_cnt; 264153235Srwatson if (ub_entries_add != NULL) 265153235Srwatson *ub_entries_add += ub.ub_entries; 266153114Srwatson } else 267153114Srwatson printf("%s uc_freebucket = NULL;\n", spaces); 268153114Srwatson if (cache->uc_allocbucket != NULL) { 269153114Srwatson ret = kread(kvm, cache->uc_allocbucket, &ub, sizeof(ub), 0); 270153114Srwatson if (ret != 0) 271153114Srwatson errx(-1, "uma_print_cache: %s", kvm_geterr(kvm)); 272153114Srwatson printf("%s uc_allocbucket ", spaces); 273153114Srwatson uma_print_bucket(&ub, spaces); 274153114Srwatson printf(";\n"); 275153235Srwatson if (ub_cnt_add != NULL) 276153235Srwatson *ub_cnt_add += ub.ub_cnt; 277153235Srwatson if (ub_entries_add != NULL) 278153235Srwatson *ub_entries_add += ub.ub_entries; 279153114Srwatson } else 280153114Srwatson printf("%s uc_allocbucket = NULL;\n", spaces); 281153114Srwatson printf("%s};\n", spaces); 282153114Srwatson} 283153114Srwatson 284153114Srwatsonint 285153114Srwatsonmain(int argc, char *argv[]) 286153114Srwatson{ 287153114Srwatson LIST_HEAD(, uma_keg) uma_kegs; 288153114Srwatson char name[MEMTYPE_MAXNAME]; 289153114Srwatson struct uma_keg *kzp, kz; 290153233Srwatson struct uma_zone *uzp, *uzp_userspace; 291153114Srwatson kvm_t *kvm; 292153235Srwatson int all_cpus, cpu, mp_maxcpus, mp_maxid, ret, ub_cnt, ub_entries; 293153233Srwatson size_t uzp_userspace_len; 294166539Spjd char *memf, *nlistf; 295166539Spjd int ch; 296212949Savg char errbuf[_POSIX2_LINE_MAX]; 297153114Srwatson 298166539Spjd memf = nlistf = NULL; 299166539Spjd while ((ch = getopt(argc, argv, "M:N:")) != -1) { 300166539Spjd switch (ch) { 301166539Spjd case 'M': 302166539Spjd memf = optarg; 303166539Spjd break; 304166539Spjd case 'N': 305166539Spjd nlistf = optarg; 306166539Spjd break; 307166539Spjd default: 308166539Spjd usage(); 309166539Spjd } 310166539Spjd } 311166539Spjd argc -= optind; 312166539Spjd argv += optind; 313166539Spjd 314166539Spjd if (argc != 0) 315153114Srwatson usage(); 316166539Spjd if (nlistf != NULL && memf == NULL) 317166539Spjd usage(); 318153114Srwatson 319212949Savg kvm = kvm_openfiles(nlistf, memf, NULL, 0, errbuf); 320153114Srwatson if (kvm == NULL) 321212949Savg errx(-1, "kvm_openfiles: %s", errbuf); 322153114Srwatson 323153114Srwatson if (kvm_nlist(kvm, namelist) != 0) 324153114Srwatson err(-1, "kvm_nlist"); 325153114Srwatson 326153114Srwatson if (namelist[X_UMA_KEGS].n_type == 0 || 327153114Srwatson namelist[X_UMA_KEGS].n_value == 0) 328153114Srwatson errx(-1, "kvm_nlist return"); 329153114Srwatson 330153233Srwatson ret = kread_symbol(kvm, X_MP_MAXCPUS, &mp_maxcpus, sizeof(mp_maxcpus), 331153233Srwatson 0); 332153233Srwatson if (ret != 0) 333153233Srwatson errx(-1, "kread_symbol: %s", kvm_geterr(kvm)); 334153233Srwatson 335153233Srwatson printf("mp_maxcpus = %d\n", mp_maxcpus); 336153233Srwatson 337153114Srwatson ret = kread_symbol(kvm, X_MP_MAXID, &mp_maxid, sizeof(mp_maxid), 0); 338153114Srwatson if (ret != 0) 339153114Srwatson errx(-1, "kread_symbol: %s", kvm_geterr(kvm)); 340153114Srwatson 341153114Srwatson printf("mp_maxid = %d\n", mp_maxid); 342153114Srwatson 343153114Srwatson ret = kread_symbol(kvm, X_ALLCPU, &all_cpus, sizeof(all_cpus), 0); 344153114Srwatson if (ret != 0) 345153114Srwatson errx(-1, "kread_symbol: %s", kvm_geterr(kvm)); 346153114Srwatson 347153114Srwatson printf("all_cpus = %x\n", all_cpus); 348153114Srwatson 349153114Srwatson ret = kread_symbol(kvm, X_UMA_KEGS, &uma_kegs, sizeof(uma_kegs), 0); 350153114Srwatson if (ret != 0) 351153114Srwatson errx(-1, "kread_symbol: %s", kvm_geterr(kvm)); 352153114Srwatson 353153233Srwatson /* 354153233Srwatson * uma_zone_t ends in an array of mp_maxid cache entries. However, 355153233Srwatson * it is statically declared as an array of size 1, so we need to 356153233Srwatson * provide additional space. 357153233Srwatson */ 358156365Swkoszek uzp_userspace_len = sizeof(struct uma_zone) + mp_maxid * 359153233Srwatson sizeof(struct uma_cache); 360153233Srwatson uzp_userspace = malloc(uzp_userspace_len); 361153233Srwatson if (uzp_userspace == NULL) 362153233Srwatson err(-1, "malloc"); 363153233Srwatson 364153114Srwatson for (kzp = LIST_FIRST(&uma_kegs); kzp != NULL; kzp = 365153114Srwatson LIST_NEXT(&kz, uk_link)) { 366153114Srwatson ret = kread(kvm, kzp, &kz, sizeof(kz), 0); 367153233Srwatson if (ret != 0) { 368153233Srwatson free(uzp_userspace); 369153114Srwatson errx(-1, "kread: %s", kvm_geterr(kvm)); 370153233Srwatson } 371153114Srwatson printf("Keg {\n"); 372153114Srwatson 373153114Srwatson uma_print_keg_align(&kz, " "); 374153114Srwatson printf(" uk_pages = %d\n", kz.uk_pages); 375153114Srwatson printf(" uk_free = %d\n", kz.uk_free); 376260307Smav printf(" uk_reserve = %d\n", kz.uk_reserve); 377153114Srwatson printf(" uk_size = %d\n", kz.uk_size); 378153114Srwatson printf(" uk_rsize = %d\n", kz.uk_rsize); 379153114Srwatson printf(" uk_maxpages = %d\n", kz.uk_maxpages); 380153114Srwatson 381260307Smav printf(" uk_slabsize = %d\n", kz.uk_slabsize); 382153114Srwatson printf(" uk_pgoff = %d\n", kz.uk_pgoff); 383153114Srwatson printf(" uk_ppera = %d\n", kz.uk_ppera); 384153114Srwatson printf(" uk_ipers = %d\n", kz.uk_ipers); 385153114Srwatson uma_print_keg_flags(&kz, " "); 386153114Srwatson 387153114Srwatson if (LIST_FIRST(&kz.uk_zones) == NULL) { 388153114Srwatson printf("; No zones.\n"); 389153114Srwatson printf("};\n"); 390153114Srwatson continue; 391153114Srwatson } 392153114Srwatson for (uzp = LIST_FIRST(&kz.uk_zones); uzp != NULL; uzp = 393153233Srwatson LIST_NEXT(uzp_userspace, uz_link)) { 394153233Srwatson /* 395153233Srwatson * We actually copy in twice: once with the base 396153233Srwatson * structure, so that we can then decide if we also 397153233Srwatson * need to copy in the caches. This prevents us 398153233Srwatson * from reading past the end of the base UMA zones, 399153233Srwatson * which is unlikely to cause problems but could. 400153233Srwatson */ 401153233Srwatson ret = kread(kvm, uzp, uzp_userspace, 402153233Srwatson sizeof(struct uma_zone), 0); 403153233Srwatson if (ret != 0) { 404153233Srwatson free(uzp_userspace); 405153114Srwatson errx(-1, "kread: %s", kvm_geterr(kvm)); 406153233Srwatson } 407153233Srwatson if (!(kz.uk_flags & UMA_ZFLAG_INTERNAL)) { 408153233Srwatson ret = kread(kvm, uzp, uzp_userspace, 409153233Srwatson uzp_userspace_len, 0); 410153233Srwatson if (ret != 0) { 411153233Srwatson free(uzp_userspace); 412153233Srwatson errx(-1, "kread: %s", 413153233Srwatson kvm_geterr(kvm)); 414153233Srwatson } 415153233Srwatson } 416153233Srwatson ret = kread_string(kvm, uzp_userspace->uz_name, name, 417153114Srwatson MEMTYPE_MAXNAME); 418153233Srwatson if (ret != 0) { 419153233Srwatson free(uzp_userspace); 420153114Srwatson errx(-1, "kread_string: %s", kvm_geterr(kvm)); 421153233Srwatson } 422153114Srwatson printf(" Zone {\n"); 423153114Srwatson printf(" uz_name = \"%s\";\n", name); 424260307Smav printf(" uz_allocs = %lu;\n", 425153233Srwatson uzp_userspace->uz_allocs); 426260307Smav printf(" uz_frees = %lu;\n", 427153233Srwatson uzp_userspace->uz_frees); 428260307Smav printf(" uz_fails = %lu;\n", 429153233Srwatson uzp_userspace->uz_fails); 430260307Smav printf(" uz_sleeps = %ju;\n", 431260307Smav uzp_userspace->uz_sleeps); 432153233Srwatson printf(" uz_count = %u;\n", 433153233Srwatson uzp_userspace->uz_count); 434212932Savg uma_print_bucketlist(kvm, (void *) 435260307Smav &uzp_userspace->uz_buckets, "uz_buckets", 436153233Srwatson " "); 437153114Srwatson 438153114Srwatson if (!(kz.uk_flags & UMA_ZFLAG_INTERNAL)) { 439153235Srwatson ub_cnt = ub_entries = 0; 440153235Srwatson for (cpu = 0; cpu <= mp_maxid; cpu++) { 441153114Srwatson /* if (CPU_ABSENT(cpu)) */ 442153114Srwatson if ((all_cpus & (1 << cpu)) == 0) 443153114Srwatson continue; 444153233Srwatson uma_print_cache(kvm, 445153233Srwatson &uzp_userspace->uz_cpu[cpu], 446153235Srwatson "uc_cache", cpu, " ", &ub_cnt, 447153235Srwatson &ub_entries); 448153114Srwatson } 449153235Srwatson printf(" // %d cache total cnt, %d total " 450153235Srwatson "entries\n", ub_cnt, ub_entries); 451153114Srwatson } 452153114Srwatson 453153114Srwatson printf(" };\n"); 454153114Srwatson } 455153114Srwatson printf("};\n"); 456153114Srwatson } 457153114Srwatson 458153233Srwatson free(uzp_userspace); 459153114Srwatson return (0); 460153114Srwatson} 461