17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5789d94c2Sjwadams  * Common Development and Distribution License (the "License").
6789d94c2Sjwadams  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
220c3b83b1SJonathan Adams  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
264f364e7cSRobert Mustacchi /*
274f364e7cSRobert Mustacchi  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
284f364e7cSRobert Mustacchi  */
294f364e7cSRobert Mustacchi 
307c478bd9Sstevel@tonic-gate #include "umem.h"
317c478bd9Sstevel@tonic-gate #include <libproc.h>
327c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #include "kgrep.h"
357c478bd9Sstevel@tonic-gate #include "leaky.h"
367c478bd9Sstevel@tonic-gate #include "misc.h"
377c478bd9Sstevel@tonic-gate #include "proc_kludges.h"
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate #include <umem_impl.h>
407c478bd9Sstevel@tonic-gate #include <sys/vmem_impl_user.h>
414f364e7cSRobert Mustacchi #include <thr_uberdata.h>
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #include "umem_pagesize.h"
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate typedef struct datafmt {
467c478bd9Sstevel@tonic-gate 	char	*hdr1;
477c478bd9Sstevel@tonic-gate 	char	*hdr2;
487c478bd9Sstevel@tonic-gate 	char	*dashes;
497c478bd9Sstevel@tonic-gate 	char	*fmt;
507c478bd9Sstevel@tonic-gate } datafmt_t;
517c478bd9Sstevel@tonic-gate 
524f364e7cSRobert Mustacchi static datafmt_t ptcfmt[] = {
534f364e7cSRobert Mustacchi 	{ "   ",	"tid",		"---",		"%3u "		},
544f364e7cSRobert Mustacchi 	{ " memory",	" cached",	"-------",	"%7lH "		},
554f364e7cSRobert Mustacchi 	{ "  %",	"cap",		"---",		"%3u "		},
564f364e7cSRobert Mustacchi 	{ "  %",	NULL,		"---",		"%3u "		},
574f364e7cSRobert Mustacchi 	{ NULL,		NULL,		NULL,		NULL		}
584f364e7cSRobert Mustacchi };
594f364e7cSRobert Mustacchi 
607c478bd9Sstevel@tonic-gate static datafmt_t umemfmt[] = {
617c478bd9Sstevel@tonic-gate 	{ "cache                    ", "name                     ",
627c478bd9Sstevel@tonic-gate 	"-------------------------", "%-25s "				},
637c478bd9Sstevel@tonic-gate 	{ "   buf",	"  size",	"------",	"%6u "		},
644f364e7cSRobert Mustacchi 	{ "    buf",	" in use",	"-------",	"%7u "		},
654f364e7cSRobert Mustacchi 	{ "    buf",	" in ptc",	"-------",	"%7s "		},
664f364e7cSRobert Mustacchi 	{ "    buf",	"  total",	"-------",	"%7u "		},
674f364e7cSRobert Mustacchi 	{ " memory",	" in use",	"-------",	"%7H "		},
687c478bd9Sstevel@tonic-gate 	{ "    alloc",	"  succeed",	"---------",	"%9u "		},
694f364e7cSRobert Mustacchi 	{ "alloc",	" fail",	"-----",	"%5llu"		},
707c478bd9Sstevel@tonic-gate 	{ NULL,		NULL,		NULL,		NULL		}
717c478bd9Sstevel@tonic-gate };
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate static datafmt_t vmemfmt[] = {
747c478bd9Sstevel@tonic-gate 	{ "vmem                     ", "name                     ",
757c478bd9Sstevel@tonic-gate 	"-------------------------", "%-*s "				},
764f364e7cSRobert Mustacchi 	{ "   memory",	"   in use",	"---------",	"%9H "		},
774f364e7cSRobert Mustacchi 	{ "    memory",	"     total",	"----------",	"%10H "		},
784f364e7cSRobert Mustacchi 	{ "   memory",	"   import",	"---------",	"%9H "		},
797c478bd9Sstevel@tonic-gate 	{ "    alloc",	"  succeed",	"---------",	"%9llu "	},
807c478bd9Sstevel@tonic-gate 	{ "alloc",	" fail",	"-----",	"%5llu "	},
817c478bd9Sstevel@tonic-gate 	{ NULL,		NULL,		NULL,		NULL		}
827c478bd9Sstevel@tonic-gate };
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate /*ARGSUSED*/
857c478bd9Sstevel@tonic-gate static int
umastat_cpu_avail(uintptr_t addr,const umem_cpu_cache_t * ccp,int * avail)867c478bd9Sstevel@tonic-gate umastat_cpu_avail(uintptr_t addr, const umem_cpu_cache_t *ccp, int *avail)
877c478bd9Sstevel@tonic-gate {
887c478bd9Sstevel@tonic-gate 	if (ccp->cc_rounds > 0)
897c478bd9Sstevel@tonic-gate 		*avail += ccp->cc_rounds;
907c478bd9Sstevel@tonic-gate 	if (ccp->cc_prounds > 0)
917c478bd9Sstevel@tonic-gate 		*avail += ccp->cc_prounds;
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
947c478bd9Sstevel@tonic-gate }
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate /*ARGSUSED*/
977c478bd9Sstevel@tonic-gate static int
umastat_cpu_alloc(uintptr_t addr,const umem_cpu_cache_t * ccp,int * alloc)987c478bd9Sstevel@tonic-gate umastat_cpu_alloc(uintptr_t addr, const umem_cpu_cache_t *ccp, int *alloc)
997c478bd9Sstevel@tonic-gate {
1007c478bd9Sstevel@tonic-gate 	*alloc += ccp->cc_alloc;
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
1037c478bd9Sstevel@tonic-gate }
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1067c478bd9Sstevel@tonic-gate static int
umastat_slab_avail(uintptr_t addr,const umem_slab_t * sp,int * avail)1077c478bd9Sstevel@tonic-gate umastat_slab_avail(uintptr_t addr, const umem_slab_t *sp, int *avail)
1087c478bd9Sstevel@tonic-gate {
1097c478bd9Sstevel@tonic-gate 	*avail += sp->slab_chunks - sp->slab_refcnt;
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
1127c478bd9Sstevel@tonic-gate }
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate typedef struct umastat_vmem {
1157c478bd9Sstevel@tonic-gate 	uintptr_t kv_addr;
1167c478bd9Sstevel@tonic-gate 	struct umastat_vmem *kv_next;
1177c478bd9Sstevel@tonic-gate 	int kv_meminuse;
1187c478bd9Sstevel@tonic-gate 	int kv_alloc;
1197c478bd9Sstevel@tonic-gate 	int kv_fail;
1207c478bd9Sstevel@tonic-gate } umastat_vmem_t;
1217c478bd9Sstevel@tonic-gate 
1224f364e7cSRobert Mustacchi /*ARGSUSED*/
1234f364e7cSRobert Mustacchi static int
umastat_cache_nptc(uintptr_t addr,const umem_cache_t * cp,int * nptc)1244f364e7cSRobert Mustacchi umastat_cache_nptc(uintptr_t addr, const umem_cache_t *cp, int *nptc)
1254f364e7cSRobert Mustacchi {
1264f364e7cSRobert Mustacchi 	if (!(cp->cache_flags & UMF_PTC))
1274f364e7cSRobert Mustacchi 		return (WALK_NEXT);
1284f364e7cSRobert Mustacchi 
1294f364e7cSRobert Mustacchi 	(*nptc)++;
1304f364e7cSRobert Mustacchi 	return (WALK_NEXT);
1314f364e7cSRobert Mustacchi }
1324f364e7cSRobert Mustacchi 
1334f364e7cSRobert Mustacchi /*ARGSUSED*/
1344f364e7cSRobert Mustacchi static int
umastat_cache_hdr(uintptr_t addr,const umem_cache_t * cp,void * ignored)1354f364e7cSRobert Mustacchi umastat_cache_hdr(uintptr_t addr, const umem_cache_t *cp, void *ignored)
1364f364e7cSRobert Mustacchi {
1374f364e7cSRobert Mustacchi 	if (!(cp->cache_flags & UMF_PTC))
1384f364e7cSRobert Mustacchi 		return (WALK_NEXT);
1394f364e7cSRobert Mustacchi 
1404f364e7cSRobert Mustacchi 	mdb_printf("%3d ", cp->cache_bufsize);
1414f364e7cSRobert Mustacchi 	return (WALK_NEXT);
1424f364e7cSRobert Mustacchi }
1434f364e7cSRobert Mustacchi 
1444f364e7cSRobert Mustacchi /*ARGSUSED*/
1454f364e7cSRobert Mustacchi static int
umastat_lwp_ptc(uintptr_t addr,void * buf,int * nbufs)1464f364e7cSRobert Mustacchi umastat_lwp_ptc(uintptr_t addr, void *buf, int *nbufs)
1474f364e7cSRobert Mustacchi {
1484f364e7cSRobert Mustacchi 	(*nbufs)++;
1494f364e7cSRobert Mustacchi 	return (WALK_NEXT);
1504f364e7cSRobert Mustacchi }
1514f364e7cSRobert Mustacchi 
1524f364e7cSRobert Mustacchi /*ARGSUSED*/
1534f364e7cSRobert Mustacchi static int
umastat_lwp_cache(uintptr_t addr,const umem_cache_t * cp,ulwp_t * ulwp)1544f364e7cSRobert Mustacchi umastat_lwp_cache(uintptr_t addr, const umem_cache_t *cp, ulwp_t *ulwp)
1554f364e7cSRobert Mustacchi {
1564f364e7cSRobert Mustacchi 	char walk[60];
1574f364e7cSRobert Mustacchi 	int nbufs = 0;
1584f364e7cSRobert Mustacchi 
1594f364e7cSRobert Mustacchi 	if (!(cp->cache_flags & UMF_PTC))
1604f364e7cSRobert Mustacchi 		return (WALK_NEXT);
1614f364e7cSRobert Mustacchi 
1629c720e3bSIgor Kozhukhov 	(void) mdb_snprintf(walk, sizeof (walk), "umem_ptc_%d",
1639c720e3bSIgor Kozhukhov 	    cp->cache_bufsize);
1644f364e7cSRobert Mustacchi 
1654f364e7cSRobert Mustacchi 	if (mdb_pwalk(walk, (mdb_walk_cb_t)umastat_lwp_ptc,
1664f364e7cSRobert Mustacchi 	    &nbufs, (uintptr_t)ulwp->ul_self) == -1) {
1674f364e7cSRobert Mustacchi 		mdb_warn("unable to walk '%s'", walk);
1684f364e7cSRobert Mustacchi 		return (WALK_ERR);
1694f364e7cSRobert Mustacchi 	}
1704f364e7cSRobert Mustacchi 
1714f364e7cSRobert Mustacchi 	mdb_printf("%3d ", ulwp->ul_tmem.tm_size ?
1724f364e7cSRobert Mustacchi 	    (nbufs * cp->cache_bufsize * 100) / ulwp->ul_tmem.tm_size : 0);
1734f364e7cSRobert Mustacchi 
1744f364e7cSRobert Mustacchi 	return (WALK_NEXT);
1754f364e7cSRobert Mustacchi }
1764f364e7cSRobert Mustacchi 
1774f364e7cSRobert Mustacchi /*ARGSUSED*/
1784f364e7cSRobert Mustacchi static int
umastat_lwp(uintptr_t addr,const ulwp_t * ulwp,void * ignored)1794f364e7cSRobert Mustacchi umastat_lwp(uintptr_t addr, const ulwp_t *ulwp, void *ignored)
1804f364e7cSRobert Mustacchi {
1814f364e7cSRobert Mustacchi 	size_t size;
1824f364e7cSRobert Mustacchi 	datafmt_t *dfp = ptcfmt;
1834f364e7cSRobert Mustacchi 
1844f364e7cSRobert Mustacchi 	mdb_printf((dfp++)->fmt, ulwp->ul_lwpid);
1854f364e7cSRobert Mustacchi 	mdb_printf((dfp++)->fmt, ulwp->ul_tmem.tm_size);
1864f364e7cSRobert Mustacchi 
1874f364e7cSRobert Mustacchi 	if (umem_readvar(&size, "umem_ptc_size") == -1) {
1884f364e7cSRobert Mustacchi 		mdb_warn("unable to read 'umem_ptc_size'");
1894f364e7cSRobert Mustacchi 		return (WALK_ERR);
1904f364e7cSRobert Mustacchi 	}
1914f364e7cSRobert Mustacchi 
1924f364e7cSRobert Mustacchi 	mdb_printf((dfp++)->fmt, (ulwp->ul_tmem.tm_size * 100) / size);
1934f364e7cSRobert Mustacchi 
1944f364e7cSRobert Mustacchi 	if (mdb_walk("umem_cache",
1954f364e7cSRobert Mustacchi 	    (mdb_walk_cb_t)umastat_lwp_cache, (void *)ulwp) == -1) {
1964f364e7cSRobert Mustacchi 		mdb_warn("can't walk 'umem_cache'");
1974f364e7cSRobert Mustacchi 		return (WALK_ERR);
1984f364e7cSRobert Mustacchi 	}
1994f364e7cSRobert Mustacchi 
2004f364e7cSRobert Mustacchi 	mdb_printf("\n");
2014f364e7cSRobert Mustacchi 
2024f364e7cSRobert Mustacchi 	return (WALK_NEXT);
2034f364e7cSRobert Mustacchi }
2044f364e7cSRobert Mustacchi 
2054f364e7cSRobert Mustacchi /*ARGSUSED*/
2064f364e7cSRobert Mustacchi static int
umastat_cache_ptc(uintptr_t addr,const void * ignored,int * nptc)2074f364e7cSRobert Mustacchi umastat_cache_ptc(uintptr_t addr, const void *ignored, int *nptc)
2084f364e7cSRobert Mustacchi {
2094f364e7cSRobert Mustacchi 	(*nptc)++;
2104f364e7cSRobert Mustacchi 	return (WALK_NEXT);
2114f364e7cSRobert Mustacchi }
2124f364e7cSRobert Mustacchi 
2137c478bd9Sstevel@tonic-gate static int
umastat_cache(uintptr_t addr,const umem_cache_t * cp,umastat_vmem_t ** kvp)2147c478bd9Sstevel@tonic-gate umastat_cache(uintptr_t addr, const umem_cache_t *cp, umastat_vmem_t **kvp)
2157c478bd9Sstevel@tonic-gate {
2167c478bd9Sstevel@tonic-gate 	umastat_vmem_t *kv;
2177c478bd9Sstevel@tonic-gate 	datafmt_t *dfp = umemfmt;
2184f364e7cSRobert Mustacchi 	char buf[10];
2197c478bd9Sstevel@tonic-gate 	int magsize;
2207c478bd9Sstevel@tonic-gate 
2214f364e7cSRobert Mustacchi 	int avail, alloc, total, nptc = 0;
2227c478bd9Sstevel@tonic-gate 	size_t meminuse = (cp->cache_slab_create - cp->cache_slab_destroy) *
2237c478bd9Sstevel@tonic-gate 	    cp->cache_slabsize;
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 	mdb_walk_cb_t cpu_avail = (mdb_walk_cb_t)umastat_cpu_avail;
2267c478bd9Sstevel@tonic-gate 	mdb_walk_cb_t cpu_alloc = (mdb_walk_cb_t)umastat_cpu_alloc;
2277c478bd9Sstevel@tonic-gate 	mdb_walk_cb_t slab_avail = (mdb_walk_cb_t)umastat_slab_avail;
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 	magsize = umem_get_magsize(cp);
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 	alloc = cp->cache_slab_alloc + cp->cache_full.ml_alloc;
2327c478bd9Sstevel@tonic-gate 	avail = cp->cache_full.ml_total * magsize;
2337c478bd9Sstevel@tonic-gate 	total = cp->cache_buftotal;
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate 	(void) mdb_pwalk("umem_cpu_cache", cpu_alloc, &alloc, addr);
2367c478bd9Sstevel@tonic-gate 	(void) mdb_pwalk("umem_cpu_cache", cpu_avail, &avail, addr);
2377c478bd9Sstevel@tonic-gate 	(void) mdb_pwalk("umem_slab_partial", slab_avail, &avail, addr);
2387c478bd9Sstevel@tonic-gate 
2394f364e7cSRobert Mustacchi 	if (cp->cache_flags & UMF_PTC) {
2404f364e7cSRobert Mustacchi 		char walk[60];
2414f364e7cSRobert Mustacchi 
2429c720e3bSIgor Kozhukhov 		(void) mdb_snprintf(walk, sizeof (walk),
2434f364e7cSRobert Mustacchi 		    "umem_ptc_%d", cp->cache_bufsize);
2444f364e7cSRobert Mustacchi 
2454f364e7cSRobert Mustacchi 		if (mdb_walk(walk,
2464f364e7cSRobert Mustacchi 		    (mdb_walk_cb_t)umastat_cache_ptc, &nptc) == -1) {
2474f364e7cSRobert Mustacchi 			mdb_warn("unable to walk '%s'", walk);
2484f364e7cSRobert Mustacchi 			return (WALK_ERR);
2494f364e7cSRobert Mustacchi 		}
2504f364e7cSRobert Mustacchi 
2519c720e3bSIgor Kozhukhov 		(void) mdb_snprintf(buf, sizeof (buf), "%d", nptc);
2524f364e7cSRobert Mustacchi 	}
2534f364e7cSRobert Mustacchi 
2547c478bd9Sstevel@tonic-gate 	for (kv = *kvp; kv != NULL; kv = kv->kv_next) {
2557c478bd9Sstevel@tonic-gate 		if (kv->kv_addr == (uintptr_t)cp->cache_arena)
2567c478bd9Sstevel@tonic-gate 			goto out;
2577c478bd9Sstevel@tonic-gate 	}
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate 	kv = mdb_zalloc(sizeof (umastat_vmem_t), UM_SLEEP | UM_GC);
2607c478bd9Sstevel@tonic-gate 	kv->kv_next = *kvp;
2617c478bd9Sstevel@tonic-gate 	kv->kv_addr = (uintptr_t)cp->cache_arena;
2627c478bd9Sstevel@tonic-gate 	*kvp = kv;
2637c478bd9Sstevel@tonic-gate out:
2647c478bd9Sstevel@tonic-gate 	kv->kv_meminuse += meminuse;
2657c478bd9Sstevel@tonic-gate 	kv->kv_alloc += alloc;
2667c478bd9Sstevel@tonic-gate 	kv->kv_fail += cp->cache_alloc_fail;
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate 	mdb_printf((dfp++)->fmt, cp->cache_name);
2697c478bd9Sstevel@tonic-gate 	mdb_printf((dfp++)->fmt, cp->cache_bufsize);
2707c478bd9Sstevel@tonic-gate 	mdb_printf((dfp++)->fmt, total - avail);
2714f364e7cSRobert Mustacchi 	mdb_printf((dfp++)->fmt, cp->cache_flags & UMF_PTC ? buf : "-");
2727c478bd9Sstevel@tonic-gate 	mdb_printf((dfp++)->fmt, total);
2737c478bd9Sstevel@tonic-gate 	mdb_printf((dfp++)->fmt, meminuse);
2747c478bd9Sstevel@tonic-gate 	mdb_printf((dfp++)->fmt, alloc);
2757c478bd9Sstevel@tonic-gate 	mdb_printf((dfp++)->fmt, cp->cache_alloc_fail);
2767c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
2797c478bd9Sstevel@tonic-gate }
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate static int
umastat_vmem_totals(uintptr_t addr,const vmem_t * v,umastat_vmem_t * kv)2827c478bd9Sstevel@tonic-gate umastat_vmem_totals(uintptr_t addr, const vmem_t *v, umastat_vmem_t *kv)
2837c478bd9Sstevel@tonic-gate {
2847c478bd9Sstevel@tonic-gate 	while (kv != NULL && kv->kv_addr != addr)
2857c478bd9Sstevel@tonic-gate 		kv = kv->kv_next;
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate 	if (kv == NULL || kv->kv_alloc == 0)
2887c478bd9Sstevel@tonic-gate 		return (WALK_NEXT);
2897c478bd9Sstevel@tonic-gate 
2904f364e7cSRobert Mustacchi 	mdb_printf("Total [%s]%*s %6s %7s %7s %7s %7H %9u %5u\n", v->vm_name,
2914f364e7cSRobert Mustacchi 	    17 - strlen(v->vm_name), "", "", "", "", "",
2927c478bd9Sstevel@tonic-gate 	    kv->kv_meminuse, kv->kv_alloc, kv->kv_fail);
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
2957c478bd9Sstevel@tonic-gate }
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2987c478bd9Sstevel@tonic-gate static int
umastat_vmem(uintptr_t addr,const vmem_t * v,void * ignored)2997c478bd9Sstevel@tonic-gate umastat_vmem(uintptr_t addr, const vmem_t *v, void *ignored)
3007c478bd9Sstevel@tonic-gate {
3017c478bd9Sstevel@tonic-gate 	datafmt_t *dfp = vmemfmt;
3027c478bd9Sstevel@tonic-gate 	uintptr_t paddr;
3037c478bd9Sstevel@tonic-gate 	vmem_t parent;
3047c478bd9Sstevel@tonic-gate 	int ident = 0;
3057c478bd9Sstevel@tonic-gate 
306*892ad162SToomas Soome 	for (paddr = (uintptr_t)v->vm_source; paddr != 0; ident += 4) {
3077c478bd9Sstevel@tonic-gate 		if (mdb_vread(&parent, sizeof (parent), paddr) == -1) {
3087c478bd9Sstevel@tonic-gate 			mdb_warn("couldn't trace %p's ancestry", addr);
3097c478bd9Sstevel@tonic-gate 			ident = 0;
3107c478bd9Sstevel@tonic-gate 			break;
3117c478bd9Sstevel@tonic-gate 		}
3127c478bd9Sstevel@tonic-gate 		paddr = (uintptr_t)parent.vm_source;
3137c478bd9Sstevel@tonic-gate 	}
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	mdb_printf("%*s", ident, "");
3167c478bd9Sstevel@tonic-gate 	mdb_printf((dfp++)->fmt, 25 - ident, v->vm_name);
3177c478bd9Sstevel@tonic-gate 	mdb_printf((dfp++)->fmt, v->vm_kstat.vk_mem_inuse);
3187c478bd9Sstevel@tonic-gate 	mdb_printf((dfp++)->fmt, v->vm_kstat.vk_mem_total);
3197c478bd9Sstevel@tonic-gate 	mdb_printf((dfp++)->fmt, v->vm_kstat.vk_mem_import);
3207c478bd9Sstevel@tonic-gate 	mdb_printf((dfp++)->fmt, v->vm_kstat.vk_alloc);
3217c478bd9Sstevel@tonic-gate 	mdb_printf((dfp++)->fmt, v->vm_kstat.vk_fail);
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
3267c478bd9Sstevel@tonic-gate }
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate /*ARGSUSED*/
3297c478bd9Sstevel@tonic-gate int
umastat(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)3307c478bd9Sstevel@tonic-gate umastat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3317c478bd9Sstevel@tonic-gate {
3327c478bd9Sstevel@tonic-gate 	umastat_vmem_t *kv = NULL;
3337c478bd9Sstevel@tonic-gate 	datafmt_t *dfp;
3344f364e7cSRobert Mustacchi 	int nptc = 0, i;
3357c478bd9Sstevel@tonic-gate 
3367c478bd9Sstevel@tonic-gate 	if (argc != 0)
3377c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
3387c478bd9Sstevel@tonic-gate 
3394f364e7cSRobert Mustacchi 	/*
3404f364e7cSRobert Mustacchi 	 * We need to determine if we have any caches that have per-thread
3414f364e7cSRobert Mustacchi 	 * caching enabled.
3424f364e7cSRobert Mustacchi 	 */
3434f364e7cSRobert Mustacchi 	if (mdb_walk("umem_cache",
3444f364e7cSRobert Mustacchi 	    (mdb_walk_cb_t)umastat_cache_nptc, &nptc) == -1) {
3454f364e7cSRobert Mustacchi 		mdb_warn("can't walk 'umem_cache'");
3464f364e7cSRobert Mustacchi 		return (DCMD_ERR);
3474f364e7cSRobert Mustacchi 	}
3484f364e7cSRobert Mustacchi 
3494f364e7cSRobert Mustacchi 	if (nptc) {
3504f364e7cSRobert Mustacchi 		for (dfp = ptcfmt; dfp->hdr2 != NULL; dfp++)
3514f364e7cSRobert Mustacchi 			mdb_printf("%s ", dfp->hdr1);
3524f364e7cSRobert Mustacchi 
3534f364e7cSRobert Mustacchi 		for (i = 0; i < nptc; i++)
3544f364e7cSRobert Mustacchi 			mdb_printf("%s ", dfp->hdr1);
3554f364e7cSRobert Mustacchi 
3564f364e7cSRobert Mustacchi 		mdb_printf("\n");
3574f364e7cSRobert Mustacchi 
3584f364e7cSRobert Mustacchi 		for (dfp = ptcfmt; dfp->hdr2 != NULL; dfp++)
3594f364e7cSRobert Mustacchi 			mdb_printf("%s ", dfp->hdr2);
3604f364e7cSRobert Mustacchi 
3614f364e7cSRobert Mustacchi 		if (mdb_walk("umem_cache",
3624f364e7cSRobert Mustacchi 		    (mdb_walk_cb_t)umastat_cache_hdr, NULL) == -1) {
3634f364e7cSRobert Mustacchi 			mdb_warn("can't walk 'umem_cache'");
3644f364e7cSRobert Mustacchi 			return (DCMD_ERR);
3654f364e7cSRobert Mustacchi 		}
3664f364e7cSRobert Mustacchi 
3674f364e7cSRobert Mustacchi 		mdb_printf("\n");
3684f364e7cSRobert Mustacchi 
3694f364e7cSRobert Mustacchi 		for (dfp = ptcfmt; dfp->hdr2 != NULL; dfp++)
3704f364e7cSRobert Mustacchi 			mdb_printf("%s ", dfp->dashes);
3714f364e7cSRobert Mustacchi 
3724f364e7cSRobert Mustacchi 		for (i = 0; i < nptc; i++)
3734f364e7cSRobert Mustacchi 			mdb_printf("%s ", dfp->dashes);
3744f364e7cSRobert Mustacchi 
3754f364e7cSRobert Mustacchi 		mdb_printf("\n");
3764f364e7cSRobert Mustacchi 
3774f364e7cSRobert Mustacchi 		if (mdb_walk("ulwp", (mdb_walk_cb_t)umastat_lwp, NULL) == -1) {
3784f364e7cSRobert Mustacchi 			mdb_warn("can't walk 'ulwp'");
3794f364e7cSRobert Mustacchi 			return (DCMD_ERR);
3804f364e7cSRobert Mustacchi 		}
3814f364e7cSRobert Mustacchi 
3824f364e7cSRobert Mustacchi 		mdb_printf("\n");
3834f364e7cSRobert Mustacchi 	}
3844f364e7cSRobert Mustacchi 
3857c478bd9Sstevel@tonic-gate 	for (dfp = umemfmt; dfp->hdr1 != NULL; dfp++)
3864f364e7cSRobert Mustacchi 		mdb_printf("%s%s", dfp == umemfmt ? "" : " ", dfp->hdr1);
3877c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate 	for (dfp = umemfmt; dfp->hdr1 != NULL; dfp++)
3904f364e7cSRobert Mustacchi 		mdb_printf("%s%s", dfp == umemfmt ? "" : " ", dfp->hdr2);
3917c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate 	for (dfp = umemfmt; dfp->hdr1 != NULL; dfp++)
3944f364e7cSRobert Mustacchi 		mdb_printf("%s%s", dfp == umemfmt ? "" : " ", dfp->dashes);
3957c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate 	if (mdb_walk("umem_cache", (mdb_walk_cb_t)umastat_cache, &kv) == -1) {
3987c478bd9Sstevel@tonic-gate 		mdb_warn("can't walk 'umem_cache'");
3997c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
4007c478bd9Sstevel@tonic-gate 	}
4017c478bd9Sstevel@tonic-gate 
4027c478bd9Sstevel@tonic-gate 	for (dfp = umemfmt; dfp->hdr1 != NULL; dfp++)
4034f364e7cSRobert Mustacchi 		mdb_printf("%s%s", dfp == umemfmt ? "" : " ", dfp->dashes);
4047c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
4057c478bd9Sstevel@tonic-gate 
4067c478bd9Sstevel@tonic-gate 	if (mdb_walk("vmem", (mdb_walk_cb_t)umastat_vmem_totals, kv) == -1) {
4077c478bd9Sstevel@tonic-gate 		mdb_warn("can't walk 'vmem'");
4087c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
4097c478bd9Sstevel@tonic-gate 	}
4107c478bd9Sstevel@tonic-gate 
4117c478bd9Sstevel@tonic-gate 	for (dfp = umemfmt; dfp->hdr1 != NULL; dfp++)
4127c478bd9Sstevel@tonic-gate 		mdb_printf("%s ", dfp->dashes);
4137c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
4147c478bd9Sstevel@tonic-gate 
4157c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate 	for (dfp = vmemfmt; dfp->hdr1 != NULL; dfp++)
4187c478bd9Sstevel@tonic-gate 		mdb_printf("%s ", dfp->hdr1);
4197c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
4207c478bd9Sstevel@tonic-gate 
4217c478bd9Sstevel@tonic-gate 	for (dfp = vmemfmt; dfp->hdr1 != NULL; dfp++)
4227c478bd9Sstevel@tonic-gate 		mdb_printf("%s ", dfp->hdr2);
4237c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
4247c478bd9Sstevel@tonic-gate 
4257c478bd9Sstevel@tonic-gate 	for (dfp = vmemfmt; dfp->hdr1 != NULL; dfp++)
4267c478bd9Sstevel@tonic-gate 		mdb_printf("%s ", dfp->dashes);
4277c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
4287c478bd9Sstevel@tonic-gate 
4297c478bd9Sstevel@tonic-gate 	if (mdb_walk("vmem", (mdb_walk_cb_t)umastat_vmem, NULL) == -1) {
4307c478bd9Sstevel@tonic-gate 		mdb_warn("can't walk 'vmem'");
4317c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
4327c478bd9Sstevel@tonic-gate 	}
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate 	for (dfp = vmemfmt; dfp->hdr1 != NULL; dfp++)
4357c478bd9Sstevel@tonic-gate 		mdb_printf("%s ", dfp->dashes);
4367c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
4377c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
4387c478bd9Sstevel@tonic-gate }
4397c478bd9Sstevel@tonic-gate 
4407c478bd9Sstevel@tonic-gate /*
4417c478bd9Sstevel@tonic-gate  * kmdb doesn't use libproc, and thus doesn't have any prmap_t's to walk.
4427c478bd9Sstevel@tonic-gate  * We have other ways to grep kmdb's address range.
4437c478bd9Sstevel@tonic-gate  */
4447c478bd9Sstevel@tonic-gate #ifndef _KMDB
4457c478bd9Sstevel@tonic-gate 
4467c478bd9Sstevel@tonic-gate typedef struct ugrep_walk_data {
4477c478bd9Sstevel@tonic-gate 	kgrep_cb_func *ug_cb;
4487c478bd9Sstevel@tonic-gate 	void *ug_cbdata;
4497c478bd9Sstevel@tonic-gate } ugrep_walk_data_t;
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate /*ARGSUSED*/
4527c478bd9Sstevel@tonic-gate int
ugrep_mapping_cb(uintptr_t addr,const void * prm_arg,void * data)4537c478bd9Sstevel@tonic-gate ugrep_mapping_cb(uintptr_t addr, const void *prm_arg, void *data)
4547c478bd9Sstevel@tonic-gate {
4557c478bd9Sstevel@tonic-gate 	ugrep_walk_data_t *ug = data;
4567c478bd9Sstevel@tonic-gate 	const prmap_t *prm = prm_arg;
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate 	return (ug->ug_cb(prm->pr_vaddr, prm->pr_vaddr + prm->pr_size,
4597c478bd9Sstevel@tonic-gate 	    ug->ug_cbdata));
4607c478bd9Sstevel@tonic-gate }
4617c478bd9Sstevel@tonic-gate 
4627c478bd9Sstevel@tonic-gate int
kgrep_subr(kgrep_cb_func * cb,void * cbdata)4637c478bd9Sstevel@tonic-gate kgrep_subr(kgrep_cb_func *cb, void *cbdata)
4647c478bd9Sstevel@tonic-gate {
4657c478bd9Sstevel@tonic-gate 	ugrep_walk_data_t ug;
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate 	prockludge_add_walkers();
4687c478bd9Sstevel@tonic-gate 
4697c478bd9Sstevel@tonic-gate 	ug.ug_cb = cb;
4707c478bd9Sstevel@tonic-gate 	ug.ug_cbdata = cbdata;
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate 	if (mdb_walk(KLUDGE_MAPWALK_NAME, ugrep_mapping_cb, &ug) == -1) {
4737c478bd9Sstevel@tonic-gate 		mdb_warn("Unable to walk "KLUDGE_MAPWALK_NAME);
4747c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
4757c478bd9Sstevel@tonic-gate 	}
4767c478bd9Sstevel@tonic-gate 
4777c478bd9Sstevel@tonic-gate 	prockludge_remove_walkers();
4787c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
4797c478bd9Sstevel@tonic-gate }
4807c478bd9Sstevel@tonic-gate 
4817c478bd9Sstevel@tonic-gate size_t
kgrep_subr_pagesize(void)4827c478bd9Sstevel@tonic-gate kgrep_subr_pagesize(void)
4837c478bd9Sstevel@tonic-gate {
4847c478bd9Sstevel@tonic-gate 	return (PAGESIZE);
4857c478bd9Sstevel@tonic-gate }
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate #endif /* !_KMDB */
4887c478bd9Sstevel@tonic-gate 
4897c478bd9Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = {
4907c478bd9Sstevel@tonic-gate 
4917c478bd9Sstevel@tonic-gate 	/* from libumem.c */
4927c478bd9Sstevel@tonic-gate 	{ "umastat", NULL, "umem allocator stats", umastat },
4937c478bd9Sstevel@tonic-gate 
4947c478bd9Sstevel@tonic-gate 	/* from misc.c */
4957c478bd9Sstevel@tonic-gate 	{ "umem_debug", NULL, "toggle umem dcmd/walk debugging", umem_debug},
4967c478bd9Sstevel@tonic-gate 
4977c478bd9Sstevel@tonic-gate 	/* from umem.c */
4987c478bd9Sstevel@tonic-gate 	{ "umem_status", NULL, "Print umem status and message buffer",
4997c478bd9Sstevel@tonic-gate 		umem_status },
5007c478bd9Sstevel@tonic-gate 	{ "allocdby", ":", "given a thread, print its allocated buffers",
5017c478bd9Sstevel@tonic-gate 		allocdby },
5027c478bd9Sstevel@tonic-gate 	{ "bufctl", ":[-vh] [-a addr] [-c caller] [-e earliest] [-l latest] "
5037c478bd9Sstevel@tonic-gate 		"[-t thd]", "print or filter a bufctl", bufctl, bufctl_help },
5047c478bd9Sstevel@tonic-gate 	{ "bufctl_audit", ":", "print a bufctl_audit", bufctl_audit },
5057c478bd9Sstevel@tonic-gate 	{ "freedby", ":", "given a thread, print its freed buffers", freedby },
5067c478bd9Sstevel@tonic-gate 	{ "umalog", "[ fail | slab ]",
5077c478bd9Sstevel@tonic-gate 	    "display umem transaction log and stack traces", umalog },
5087c478bd9Sstevel@tonic-gate 	{ "umausers", "[-ef] [cache ...]", "display current medium and large "
5097c478bd9Sstevel@tonic-gate 		"users of the umem allocator", umausers },
5107c478bd9Sstevel@tonic-gate 	{ "umem_cache", "?", "print a umem cache", umem_cache },
5117c478bd9Sstevel@tonic-gate 	{ "umem_log", "?", "dump umem transaction log", umem_log },
512789d94c2Sjwadams 	{ "umem_malloc_dist", "[-dg] [-b maxbins] [-B minbinsize]",
513789d94c2Sjwadams 		"report distribution of outstanding malloc()s",
514789d94c2Sjwadams 		umem_malloc_dist, umem_malloc_dist_help },
515789d94c2Sjwadams 	{ "umem_malloc_info", "?[-dg] [-b maxbins] [-B minbinsize]",
516789d94c2Sjwadams 		"report information about malloc()s by cache",
517789d94c2Sjwadams 		umem_malloc_info, umem_malloc_info_help },
5187c478bd9Sstevel@tonic-gate 	{ "umem_verify", "?", "check integrity of umem-managed memory",
5197c478bd9Sstevel@tonic-gate 		umem_verify },
5207c478bd9Sstevel@tonic-gate 	{ "vmem", "?", "print a vmem_t", vmem },
5217c478bd9Sstevel@tonic-gate 	{ "vmem_seg", ":[-sv] [-c caller] [-e earliest] [-l latest] "
5227c478bd9Sstevel@tonic-gate 		"[-m minsize] [-M maxsize] [-t thread] [-T type]",
5237c478bd9Sstevel@tonic-gate 		"print or filter a vmem_seg", vmem_seg, vmem_seg_help },
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate #ifndef _KMDB
5267c478bd9Sstevel@tonic-gate 	/* from ../genunix/kgrep.c + libumem.c */
5277c478bd9Sstevel@tonic-gate 	{ "ugrep", KGREP_USAGE, "search user address space for a pointer",
528154eb83fSjwadams 	    kgrep, kgrep_help },
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate 	/* from ../genunix/leaky.c + leaky_subr.c */
5317c478bd9Sstevel@tonic-gate 	{ "findleaks", FINDLEAKS_USAGE, "search for potential memory leaks",
5327c478bd9Sstevel@tonic-gate 	    findleaks, findleaks_help },
5337c478bd9Sstevel@tonic-gate #endif
5347c478bd9Sstevel@tonic-gate 
5357c478bd9Sstevel@tonic-gate 	{ NULL }
5367c478bd9Sstevel@tonic-gate };
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate static const mdb_walker_t walkers[] = {
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate 	/* from umem.c */
5417c478bd9Sstevel@tonic-gate 	{ "allocdby", "given a thread, walk its allocated bufctls",
5427c478bd9Sstevel@tonic-gate 		allocdby_walk_init, allocdby_walk_step, allocdby_walk_fini },
5437c478bd9Sstevel@tonic-gate 	{ "bufctl", "walk a umem cache's bufctls",
5447c478bd9Sstevel@tonic-gate 		bufctl_walk_init, umem_walk_step, umem_walk_fini },
5457c478bd9Sstevel@tonic-gate 	{ "bufctl_history", "walk the available history of a bufctl",
5467c478bd9Sstevel@tonic-gate 		bufctl_history_walk_init, bufctl_history_walk_step,
5477c478bd9Sstevel@tonic-gate 		bufctl_history_walk_fini },
5487c478bd9Sstevel@tonic-gate 	{ "freectl", "walk a umem cache's free bufctls",
5497c478bd9Sstevel@tonic-gate 		freectl_walk_init, umem_walk_step, umem_walk_fini },
5507c478bd9Sstevel@tonic-gate 	{ "freedby", "given a thread, walk its freed bufctls",
5517c478bd9Sstevel@tonic-gate 		freedby_walk_init, allocdby_walk_step, allocdby_walk_fini },
5527c478bd9Sstevel@tonic-gate 	{ "freemem", "walk a umem cache's free memory",
5537c478bd9Sstevel@tonic-gate 		freemem_walk_init, umem_walk_step, umem_walk_fini },
5547c478bd9Sstevel@tonic-gate 	{ "umem", "walk a umem cache",
5557c478bd9Sstevel@tonic-gate 		umem_walk_init, umem_walk_step, umem_walk_fini },
5567c478bd9Sstevel@tonic-gate 	{ "umem_cpu", "walk the umem CPU structures",
5577c478bd9Sstevel@tonic-gate 		umem_cpu_walk_init, umem_cpu_walk_step, umem_cpu_walk_fini },
5587c478bd9Sstevel@tonic-gate 	{ "umem_cpu_cache", "given a umem cache, walk its per-CPU caches",
5597c478bd9Sstevel@tonic-gate 		umem_cpu_cache_walk_init, umem_cpu_cache_walk_step, NULL },
5607c478bd9Sstevel@tonic-gate 	{ "umem_hash", "given a umem cache, walk its allocated hash table",
5617c478bd9Sstevel@tonic-gate 		umem_hash_walk_init, umem_hash_walk_step, umem_hash_walk_fini },
5627c478bd9Sstevel@tonic-gate 	{ "umem_log", "walk the umem transaction log",
5637c478bd9Sstevel@tonic-gate 		umem_log_walk_init, umem_log_walk_step, umem_log_walk_fini },
5647c478bd9Sstevel@tonic-gate 	{ "umem_slab", "given a umem cache, walk its slabs",
5657c478bd9Sstevel@tonic-gate 		umem_slab_walk_init, umem_slab_walk_step, NULL },
5667c478bd9Sstevel@tonic-gate 	{ "umem_slab_partial",
5677c478bd9Sstevel@tonic-gate 	    "given a umem cache, walk its partially allocated slabs (min 1)",
5687c478bd9Sstevel@tonic-gate 		umem_slab_walk_partial_init, umem_slab_walk_step, NULL },
5697c478bd9Sstevel@tonic-gate 	{ "vmem", "walk vmem structures in pre-fix, depth-first order",
5707c478bd9Sstevel@tonic-gate 		vmem_walk_init, vmem_walk_step, vmem_walk_fini },
5717c478bd9Sstevel@tonic-gate 	{ "vmem_alloc", "given a vmem_t, walk its allocated vmem_segs",
5727c478bd9Sstevel@tonic-gate 		vmem_alloc_walk_init, vmem_seg_walk_step, vmem_seg_walk_fini },
5737c478bd9Sstevel@tonic-gate 	{ "vmem_free", "given a vmem_t, walk its free vmem_segs",
5747c478bd9Sstevel@tonic-gate 		vmem_free_walk_init, vmem_seg_walk_step, vmem_seg_walk_fini },
5757c478bd9Sstevel@tonic-gate 	{ "vmem_postfix", "walk vmem structures in post-fix, depth-first order",
5767c478bd9Sstevel@tonic-gate 		vmem_walk_init, vmem_postfix_walk_step, vmem_walk_fini },
5777c478bd9Sstevel@tonic-gate 	{ "vmem_seg", "given a vmem_t, walk all of its vmem_segs",
5787c478bd9Sstevel@tonic-gate 		vmem_seg_walk_init, vmem_seg_walk_step, vmem_seg_walk_fini },
5797c478bd9Sstevel@tonic-gate 	{ "vmem_span", "given a vmem_t, walk its spanning vmem_segs",
5807c478bd9Sstevel@tonic-gate 		vmem_span_walk_init, vmem_seg_walk_step, vmem_seg_walk_fini },
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate #ifndef _KMDB
5837c478bd9Sstevel@tonic-gate 	/* from ../genunix/leaky.c + leaky_subr.c */
5847c478bd9Sstevel@tonic-gate 	{ "leak", "given a leak ctl, walk other leaks w/ that stacktrace",
5857c478bd9Sstevel@tonic-gate 		leaky_walk_init, leaky_walk_step, leaky_walk_fini },
5867c478bd9Sstevel@tonic-gate 	{ "leakbuf", "given a leak ctl, walk addr of leaks w/ that stacktrace",
5877c478bd9Sstevel@tonic-gate 		leaky_walk_init, leaky_buf_walk_step, leaky_walk_fini },
5887c478bd9Sstevel@tonic-gate #endif
5897c478bd9Sstevel@tonic-gate 
5907c478bd9Sstevel@tonic-gate 	{ NULL }
5917c478bd9Sstevel@tonic-gate };
5927c478bd9Sstevel@tonic-gate 
5937c478bd9Sstevel@tonic-gate static const mdb_modinfo_t modinfo = {MDB_API_VERSION, dcmds, walkers};
5947c478bd9Sstevel@tonic-gate 
5957c478bd9Sstevel@tonic-gate const mdb_modinfo_t *
_mdb_init(void)5967c478bd9Sstevel@tonic-gate _mdb_init(void)
5977c478bd9Sstevel@tonic-gate {
5987c478bd9Sstevel@tonic-gate 	if (umem_init() != 0)
5997c478bd9Sstevel@tonic-gate 		return (NULL);
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate 	return (&modinfo);
6027c478bd9Sstevel@tonic-gate }
6037c478bd9Sstevel@tonic-gate 
6047c478bd9Sstevel@tonic-gate void
_mdb_fini(void)6057c478bd9Sstevel@tonic-gate _mdb_fini(void)
6067c478bd9Sstevel@tonic-gate {
6077c478bd9Sstevel@tonic-gate #ifndef _KMDB
6087c478bd9Sstevel@tonic-gate 	leaky_cleanup(1);
6097c478bd9Sstevel@tonic-gate #endif
6107c478bd9Sstevel@tonic-gate }
611