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