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