xref: /openbsd-src/usr.bin/systat/malloc.c (revision 68acdce2ce14b5d52a5ee2f45dad5ea9199c1c0b)
1*68acdce2Sguenther /*	$OpenBSD: malloc.c,v 1.5 2019/11/28 16:27:25 guenther Exp $	*/
2b284ba03Scanacar /*
3b284ba03Scanacar  * Copyright (c) 2008 Can Erkin Acar <canacar@openbsd.org>
4b284ba03Scanacar  *
5b284ba03Scanacar  * Permission to use, copy, modify, and distribute this software for any
6b284ba03Scanacar  * purpose with or without fee is hereby granted, provided that the above
7b284ba03Scanacar  * copyright notice and this permission notice appear in all copies.
8b284ba03Scanacar  *
9b284ba03Scanacar  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10b284ba03Scanacar  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11b284ba03Scanacar  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12b284ba03Scanacar  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13b284ba03Scanacar  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14b284ba03Scanacar  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15b284ba03Scanacar  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16b284ba03Scanacar  */
17b284ba03Scanacar 
18b284ba03Scanacar #include <sys/types.h>
198f6b3bafSderaadt #include <sys/signal.h>
20b284ba03Scanacar #include <sys/sysctl.h>
21b284ba03Scanacar #include <sys/malloc.h>
22b284ba03Scanacar #include <errno.h>
23b284ba03Scanacar #include <stdlib.h>
24b284ba03Scanacar #include <string.h>
258f6b3bafSderaadt #include <limits.h>
26b284ba03Scanacar 
27b284ba03Scanacar #include "systat.h"
28b284ba03Scanacar 
29b284ba03Scanacar void print_types(void);
30b284ba03Scanacar void print_buckets(void);
31b284ba03Scanacar int  read_types(void);
32b284ba03Scanacar int  read_buckets(void);
33b284ba03Scanacar void sort_types(void);
34b284ba03Scanacar int  select_types(void);
35b284ba03Scanacar int  select_buckets(void);
36b284ba03Scanacar void showtype(int k);
37b284ba03Scanacar void showbucket(int k);
38b284ba03Scanacar 
39b284ba03Scanacar 
40b284ba03Scanacar /* qsort callbacks */
41b284ba03Scanacar int sort_tname_callback(const void *s1, const void *s2);
42b284ba03Scanacar int sort_treq_callback(const void *s1, const void *s2);
43b284ba03Scanacar int sort_inuse_callback(const void *s1, const void *s2);
44b284ba03Scanacar int sort_memuse_callback(const void *s1, const void *s2);
45b284ba03Scanacar 
46b284ba03Scanacar #define MAX_BUCKETS 16
47b284ba03Scanacar 
48b284ba03Scanacar struct type_info {
49b284ba03Scanacar 	const char *name;
50b284ba03Scanacar 	struct kmemstats stats;
51b284ba03Scanacar 	char buckets[MAX_BUCKETS];
52b284ba03Scanacar };
53b284ba03Scanacar 
54b284ba03Scanacar 
55b284ba03Scanacar struct type_info types[M_LAST];
56b284ba03Scanacar 
57b284ba03Scanacar struct kmembuckets buckets[MAX_BUCKETS];
58b284ba03Scanacar int bucket_sizes[MAX_BUCKETS];
59b284ba03Scanacar 
60b284ba03Scanacar int num_types = 0;
61b284ba03Scanacar int num_buckets = 0;
62b284ba03Scanacar 
63b284ba03Scanacar /*
64b284ba03Scanacar  * These names are defined in <sys/malloc.h>.
65b284ba03Scanacar  */
66b284ba03Scanacar const char *kmemnames[] = INITKMEMNAMES;
67b284ba03Scanacar 
68b284ba03Scanacar field_def fields_malloc[] = {
69b284ba03Scanacar 	{"TYPE", 14, 32, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
70b284ba03Scanacar 	{"INUSE", 6, 16, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
71b284ba03Scanacar 	{"MEMUSE", 6, 16, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
72b284ba03Scanacar 	{"HIGHUSE", 6, 16, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
73b284ba03Scanacar 	{"LIMIT", 6, 16, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
74b284ba03Scanacar 	{"REQUESTS", 8, 16, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
75b284ba03Scanacar 	{"TYPE LIMIT", 5, 12, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
76b284ba03Scanacar 	{"KERN LIMIT", 5, 12, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
77b284ba03Scanacar 	{"BUCKETS", MAX_BUCKETS, MAX_BUCKETS, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
78b284ba03Scanacar 
79b284ba03Scanacar 	{"BUCKET", 8, 8, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
80b284ba03Scanacar 	{"REQUESTS", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
81b284ba03Scanacar 	{"INUSE", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
82b284ba03Scanacar 	{"FREE", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
83b284ba03Scanacar 	{"HIWAT", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
84b284ba03Scanacar 	{"COULDFREE", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
85b284ba03Scanacar };
86b284ba03Scanacar 
87b284ba03Scanacar 
88596a8091Sjasper #define FLD_TYPE_NAME		FIELD_ADDR(fields_malloc,0)
89596a8091Sjasper #define FLD_TYPE_INUSE		FIELD_ADDR(fields_malloc,1)
90596a8091Sjasper #define FLD_TYPE_MEMUSE		FIELD_ADDR(fields_malloc,2)
91596a8091Sjasper #define FLD_TYPE_HIGHUSE	FIELD_ADDR(fields_malloc,3)
92596a8091Sjasper #define FLD_TYPE_LIMIT		FIELD_ADDR(fields_malloc,4)
93596a8091Sjasper #define FLD_TYPE_REQUESTS	FIELD_ADDR(fields_malloc,5)
94596a8091Sjasper #define FLD_TYPE_TLIMIT		FIELD_ADDR(fields_malloc,6)
95596a8091Sjasper #define FLD_TYPE_KLIMIT		FIELD_ADDR(fields_malloc,7)
96596a8091Sjasper #define FLD_TYPE_SIZES		FIELD_ADDR(fields_malloc,8)
97b284ba03Scanacar 
98596a8091Sjasper #define FLD_BUCKET_SIZE		FIELD_ADDR(fields_malloc,9)
99596a8091Sjasper #define FLD_BUCKET_REQUESTS	FIELD_ADDR(fields_malloc,10)
100596a8091Sjasper #define FLD_BUCKET_INUSE	FIELD_ADDR(fields_malloc,11)
101596a8091Sjasper #define FLD_BUCKET_FREE		FIELD_ADDR(fields_malloc,12)
102596a8091Sjasper #define FLD_BUCKET_HIWAT	FIELD_ADDR(fields_malloc,13)
103596a8091Sjasper #define FLD_BUCKET_COULDFREE	FIELD_ADDR(fields_malloc,14)
104b284ba03Scanacar 
105b284ba03Scanacar 
106b284ba03Scanacar 
107b284ba03Scanacar /* Define views */
108b284ba03Scanacar field_def *view_malloc_0[] = {
109b284ba03Scanacar 	FLD_TYPE_NAME, FLD_TYPE_INUSE, FLD_TYPE_MEMUSE,
110b284ba03Scanacar 	FLD_TYPE_HIGHUSE, FLD_TYPE_LIMIT, FLD_TYPE_REQUESTS,
111b284ba03Scanacar 	FLD_TYPE_TLIMIT, FLD_TYPE_KLIMIT, FLD_TYPE_SIZES, NULL
112b284ba03Scanacar };
113b284ba03Scanacar 
114b284ba03Scanacar field_def *view_malloc_1[] = {
115b284ba03Scanacar 	FLD_BUCKET_SIZE, FLD_BUCKET_REQUESTS, FLD_BUCKET_INUSE,
116b284ba03Scanacar 	FLD_BUCKET_FREE, FLD_BUCKET_HIWAT, FLD_BUCKET_COULDFREE, NULL
117b284ba03Scanacar };
118b284ba03Scanacar 
119b284ba03Scanacar order_type type_order_list[] = {
120b284ba03Scanacar 	{"name", "name", 'N', sort_tname_callback},
121b284ba03Scanacar 	{"inuse", "in use", 'U', sort_inuse_callback},
122b284ba03Scanacar 	{"memuse", "mem use", 'S', sort_memuse_callback},
123b284ba03Scanacar 	{"requests", "requests", 'Q', sort_treq_callback},
124b284ba03Scanacar 	{NULL, NULL, 0, NULL}
125b284ba03Scanacar };
126b284ba03Scanacar 
127b284ba03Scanacar /* Define view managers */
128b284ba03Scanacar struct view_manager types_mgr = {
129b284ba03Scanacar 	"Types", select_types, read_types, sort_types, print_header,
130b284ba03Scanacar 	print_types, keyboard_callback, type_order_list, type_order_list
131b284ba03Scanacar };
132b284ba03Scanacar 
133b284ba03Scanacar struct view_manager buckets_mgr = {
134b284ba03Scanacar 	"Buckets", select_buckets, read_buckets, NULL, print_header,
135b284ba03Scanacar 	print_buckets, keyboard_callback, NULL, NULL
136b284ba03Scanacar };
137b284ba03Scanacar 
138b284ba03Scanacar field_view views_malloc[] = {
139b284ba03Scanacar 	{view_malloc_0, "malloc", '6', &types_mgr},
140b284ba03Scanacar 	{view_malloc_1, "buckets", '7', &buckets_mgr},
141b284ba03Scanacar 	{NULL, NULL, 0, NULL}
142b284ba03Scanacar };
143b284ba03Scanacar 
144b284ba03Scanacar 
145b284ba03Scanacar int
sort_tname_callback(const void * s1,const void * s2)146b284ba03Scanacar sort_tname_callback(const void *s1, const void *s2)
147b284ba03Scanacar {
148b284ba03Scanacar 	struct type_info *t1, *t2;
149b284ba03Scanacar 	t1 = (struct type_info *)s1;
150b284ba03Scanacar 	t2 = (struct type_info *)s2;
151b284ba03Scanacar 
152b284ba03Scanacar 	return strcmp(t1->name, t2->name) * sortdir;
153b284ba03Scanacar }
154b284ba03Scanacar 
155b284ba03Scanacar int
sort_treq_callback(const void * s1,const void * s2)156b284ba03Scanacar sort_treq_callback(const void *s1, const void *s2)
157b284ba03Scanacar {
158b284ba03Scanacar 	struct type_info *t1, *t2;
159b284ba03Scanacar 	t1 = (struct type_info *)s1;
160b284ba03Scanacar 	t2 = (struct type_info *)s2;
161b284ba03Scanacar 
162b284ba03Scanacar 	if (t1->stats.ks_calls <  t2->stats.ks_calls)
163b284ba03Scanacar 		return sortdir;
164b284ba03Scanacar 	if (t1->stats.ks_calls >  t2->stats.ks_calls)
165b284ba03Scanacar 		return -sortdir;
166b284ba03Scanacar 
167b284ba03Scanacar 	return sort_tname_callback(s1, s2);
168b284ba03Scanacar }
169b284ba03Scanacar 
170b284ba03Scanacar int
sort_inuse_callback(const void * s1,const void * s2)171b284ba03Scanacar sort_inuse_callback(const void *s1, const void *s2)
172b284ba03Scanacar {
173b284ba03Scanacar 	struct type_info *t1, *t2;
174b284ba03Scanacar 	t1 = (struct type_info *)s1;
175b284ba03Scanacar 	t2 = (struct type_info *)s2;
176b284ba03Scanacar 
177b284ba03Scanacar 	if (t1->stats.ks_inuse <  t2->stats.ks_inuse)
178b284ba03Scanacar 		return sortdir;
179b284ba03Scanacar 	if (t1->stats.ks_inuse >  t2->stats.ks_inuse)
180b284ba03Scanacar 		return -sortdir;
181b284ba03Scanacar 
182b284ba03Scanacar 	return sort_tname_callback(s1, s2);
183b284ba03Scanacar }
184b284ba03Scanacar 
185b284ba03Scanacar int
sort_memuse_callback(const void * s1,const void * s2)186b284ba03Scanacar sort_memuse_callback(const void *s1, const void *s2)
187b284ba03Scanacar {
188b284ba03Scanacar 	struct type_info *t1, *t2;
189b284ba03Scanacar 	t1 = (struct type_info *)s1;
190b284ba03Scanacar 	t2 = (struct type_info *)s2;
191b284ba03Scanacar 
192b284ba03Scanacar 	if (t1->stats.ks_memuse <  t2->stats.ks_memuse)
193b284ba03Scanacar 		return sortdir;
194b284ba03Scanacar 	if (t1->stats.ks_memuse >  t2->stats.ks_memuse)
195b284ba03Scanacar 		return -sortdir;
196b284ba03Scanacar 
197b284ba03Scanacar 	return sort_tname_callback(s1, s2);
198b284ba03Scanacar }
199b284ba03Scanacar 
200b284ba03Scanacar 
201b284ba03Scanacar void
sort_types(void)202b284ba03Scanacar sort_types(void)
203b284ba03Scanacar {
204b284ba03Scanacar 	order_type *ordering;
205b284ba03Scanacar 
206b284ba03Scanacar 	if (curr_mgr == NULL)
207b284ba03Scanacar 		return;
208b284ba03Scanacar 
209b284ba03Scanacar 	ordering = curr_mgr->order_curr;
210b284ba03Scanacar 
211b284ba03Scanacar 	if (ordering == NULL)
212b284ba03Scanacar 		return;
213b284ba03Scanacar 	if (ordering->func == NULL)
214b284ba03Scanacar 		return;
215b284ba03Scanacar 	if (num_types <= 0)
216b284ba03Scanacar 		return;
217b284ba03Scanacar 
218b284ba03Scanacar 	mergesort(types, num_types, sizeof(struct type_info), ordering->func);
219b284ba03Scanacar }
220b284ba03Scanacar 
221b284ba03Scanacar int
select_types(void)222b284ba03Scanacar select_types(void)
223b284ba03Scanacar {
224b284ba03Scanacar 	num_disp = num_types;
225b284ba03Scanacar 	return (0);
226b284ba03Scanacar }
227b284ba03Scanacar 
228b284ba03Scanacar int
select_buckets(void)229b284ba03Scanacar select_buckets(void)
230b284ba03Scanacar {
231b284ba03Scanacar 	num_disp = num_buckets;
232b284ba03Scanacar 	return (0);
233b284ba03Scanacar }
234b284ba03Scanacar 
235b284ba03Scanacar int
read_buckets(void)236b284ba03Scanacar read_buckets(void)
237b284ba03Scanacar {
238b284ba03Scanacar 	int mib[4];
239b284ba03Scanacar 	char buf[BUFSIZ], *bufp, *ap;
240b284ba03Scanacar 	const char *errstr;
241b284ba03Scanacar 	size_t siz;
242b284ba03Scanacar 
243b284ba03Scanacar 	mib[0] = CTL_KERN;
244b284ba03Scanacar 	mib[1] = KERN_MALLOCSTATS;
245b284ba03Scanacar 	mib[2] = KERN_MALLOC_BUCKETS;
246b284ba03Scanacar 
247b284ba03Scanacar 	siz = sizeof(buf);
248b284ba03Scanacar 	num_buckets = 0;
249b284ba03Scanacar 
2503aaa63ebSderaadt 	if (sysctl(mib, 3, buf, &siz, NULL, 0) == -1) {
251b284ba03Scanacar 		error("sysctl(kern.malloc.buckets): %s", strerror(errno));
252b284ba03Scanacar 		return (-1);
253b284ba03Scanacar 	}
254b284ba03Scanacar 
255b284ba03Scanacar 	bufp = buf;
256b284ba03Scanacar 	mib[2] = KERN_MALLOC_BUCKET;
257b284ba03Scanacar 	siz = sizeof(struct kmembuckets);
258b284ba03Scanacar 
259b284ba03Scanacar 	while ((ap = strsep(&bufp, ",")) != NULL) {
260b284ba03Scanacar 		if (num_buckets >= MAX_BUCKETS)
261b284ba03Scanacar 			break;
262b284ba03Scanacar 		bucket_sizes[num_buckets] = strtonum(ap, 0, INT_MAX, &errstr);
263b284ba03Scanacar 		if (errstr) {
264b284ba03Scanacar 			error("strtonum(%s): %s", ap, errstr);
265b284ba03Scanacar 			return (-1);
266b284ba03Scanacar 		}
267b284ba03Scanacar 		mib[3] = bucket_sizes[num_buckets];
268b284ba03Scanacar 		if (sysctl(mib, 4, &buckets[num_buckets], &siz,
2693aaa63ebSderaadt 			   NULL, 0) == -1) {
270b284ba03Scanacar 			error("sysctl(kern.malloc.bucket.%d): %s",
271b284ba03Scanacar 			    mib[3], strerror(errno));
272b284ba03Scanacar 			return (-1);
273b284ba03Scanacar 		}
274b284ba03Scanacar 		num_buckets++;
275b284ba03Scanacar 	}
276b284ba03Scanacar 
277b284ba03Scanacar 	return (0);
278b284ba03Scanacar }
279b284ba03Scanacar 
280b284ba03Scanacar int
read_types(void)281b284ba03Scanacar read_types(void)
282b284ba03Scanacar {
283b284ba03Scanacar 	struct type_info *ti;
284b284ba03Scanacar 	int i, j, k, mib[4];
285b284ba03Scanacar 	size_t siz;
286b284ba03Scanacar 
287b284ba03Scanacar 	bzero(types, sizeof(types));
288b284ba03Scanacar 	ti = types;
289b284ba03Scanacar 	siz = sizeof(struct kmemstats);
290b284ba03Scanacar 
291b284ba03Scanacar 	num_types = 0;
292b284ba03Scanacar 
293b284ba03Scanacar 	for (i = 0; i < M_LAST; i++) {
294b284ba03Scanacar 		mib[0] = CTL_KERN;
295b284ba03Scanacar 		mib[1] = KERN_MALLOCSTATS;
296b284ba03Scanacar 		mib[2] = KERN_MALLOC_KMEMSTATS;
297b284ba03Scanacar 		mib[3] = i;
298b284ba03Scanacar 
299b284ba03Scanacar 		/*
300b284ba03Scanacar 		 * Skip errors -- these are presumed to be unallocated
301b284ba03Scanacar 		 * entries.
302b284ba03Scanacar 		 */
3033aaa63ebSderaadt 		if (sysctl(mib, 4, &ti->stats, &siz, NULL, 0) == -1)
304b284ba03Scanacar 			continue;
305b284ba03Scanacar 
306b284ba03Scanacar 		if (ti->stats.ks_calls == 0)
307b284ba03Scanacar 			continue;
308b284ba03Scanacar 
309b284ba03Scanacar 		ti->name = kmemnames[i];
310b284ba03Scanacar 		j = 1 << MINBUCKET;
311b284ba03Scanacar 
312b284ba03Scanacar 		for (k = 0; k < MAX_BUCKETS; k++, j <<= 1)
313b284ba03Scanacar 			ti->buckets[k] = (ti->stats.ks_size & j) ? '|' : '.';
314b284ba03Scanacar 
315b284ba03Scanacar 		ti++;
316b284ba03Scanacar 		num_types++;
317b284ba03Scanacar 	}
318b284ba03Scanacar 
319b284ba03Scanacar 	return (0);
320b284ba03Scanacar }
321b284ba03Scanacar 
322b284ba03Scanacar 
323b284ba03Scanacar void
print_types(void)324b284ba03Scanacar print_types(void)
325b284ba03Scanacar {
326b284ba03Scanacar 	int n, count = 0;
327b284ba03Scanacar 
328b284ba03Scanacar 	for (n = dispstart; n < num_disp; n++) {
329b284ba03Scanacar 		showtype(n);
330b284ba03Scanacar 		count++;
331b284ba03Scanacar 		if (maxprint > 0 && count >= maxprint)
332b284ba03Scanacar 			break;	}
333b284ba03Scanacar }
334b284ba03Scanacar 
335b284ba03Scanacar void
print_buckets(void)336b284ba03Scanacar print_buckets(void)
337b284ba03Scanacar {
338b284ba03Scanacar 	int n, count = 0;
339b284ba03Scanacar 
340b284ba03Scanacar 	for (n = dispstart; n < num_disp; n++) {
341b284ba03Scanacar 		showbucket(n);
342b284ba03Scanacar 		count++;
343b284ba03Scanacar 		if (maxprint > 0 && count >= maxprint)
344b284ba03Scanacar 			break;
345b284ba03Scanacar 	}
346b284ba03Scanacar }
347b284ba03Scanacar 
348b284ba03Scanacar int
initmalloc(void)349b284ba03Scanacar initmalloc(void)
350b284ba03Scanacar {
351b284ba03Scanacar 	field_view *v;
352b284ba03Scanacar 
353b284ba03Scanacar 	for (v = views_malloc; v->name != NULL; v++)
354b284ba03Scanacar 		add_view(v);
355b284ba03Scanacar 
356b284ba03Scanacar 	read_buckets();
357b284ba03Scanacar 	read_types();
358b284ba03Scanacar 
359b284ba03Scanacar 	return(0);
360b284ba03Scanacar }
361b284ba03Scanacar 
362b284ba03Scanacar void
showbucket(int k)363b284ba03Scanacar showbucket(int k)
364b284ba03Scanacar {
365b284ba03Scanacar 	struct kmembuckets *kp = buckets + k;
366b284ba03Scanacar 
367b284ba03Scanacar 	if (k < 0 || k >= num_buckets)
368b284ba03Scanacar 		return;
369b284ba03Scanacar 
370b284ba03Scanacar 	print_fld_size(FLD_BUCKET_SIZE, bucket_sizes[k]);
371b284ba03Scanacar 	print_fld_size(FLD_BUCKET_INUSE, kp->kb_total - kp->kb_totalfree);
372b284ba03Scanacar 	print_fld_size(FLD_BUCKET_FREE, kp->kb_totalfree);
373b284ba03Scanacar 	print_fld_size(FLD_BUCKET_REQUESTS, kp->kb_calls);
374b284ba03Scanacar 	print_fld_size(FLD_BUCKET_HIWAT, kp->kb_highwat);
375b284ba03Scanacar 	print_fld_size(FLD_BUCKET_COULDFREE, kp->kb_couldfree);
376b284ba03Scanacar 
377b284ba03Scanacar 	end_line();
378b284ba03Scanacar }
379b284ba03Scanacar 
380b284ba03Scanacar 
381b284ba03Scanacar void
showtype(int k)382b284ba03Scanacar showtype(int k)
383b284ba03Scanacar {
384b284ba03Scanacar 	struct type_info *t = types + k;
385b284ba03Scanacar 
386b284ba03Scanacar 	if (k < 0 || k >= num_types)
387b284ba03Scanacar 		return;
388b284ba03Scanacar 
389b284ba03Scanacar 
390b284ba03Scanacar 	print_fld_str(FLD_TYPE_NAME, t->name ? t->name : "undefined");
391b284ba03Scanacar 	print_fld_size(FLD_TYPE_INUSE, t->stats.ks_inuse);
392b284ba03Scanacar 	print_fld_size(FLD_TYPE_MEMUSE, t->stats.ks_memuse);
393b284ba03Scanacar 	print_fld_size(FLD_TYPE_HIGHUSE, t->stats.ks_maxused);
394b284ba03Scanacar 	print_fld_size(FLD_TYPE_LIMIT, t->stats.ks_limit);
395b284ba03Scanacar 	print_fld_size(FLD_TYPE_REQUESTS, t->stats.ks_calls);
396b284ba03Scanacar 	print_fld_size(FLD_TYPE_TLIMIT, t->stats.ks_limblocks);
397b284ba03Scanacar 	print_fld_str(FLD_TYPE_SIZES, t->buckets);
398b284ba03Scanacar 
399b284ba03Scanacar 	end_line();
400b284ba03Scanacar }
401