19b50d902SRodney W. Grimes /* 29b50d902SRodney W. Grimes * Copyright (c) 1983, 1988, 1993 3c8e6b689SRobert Watson * The Regents of the University of California. 4c8e6b689SRobert Watson * Copyright (c) 2005 Robert N. M. Watson 5c8e6b689SRobert Watson * All rights reserved. 69b50d902SRodney W. Grimes * 79b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 89b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 99b50d902SRodney W. Grimes * are met: 109b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 119b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 129b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 139b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 149b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 159b50d902SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 169b50d902SRodney W. Grimes * must display the following acknowledgement: 179b50d902SRodney W. Grimes * This product includes software developed by the University of 189b50d902SRodney W. Grimes * California, Berkeley and its contributors. 199b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 209b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 219b50d902SRodney W. Grimes * without specific prior written permission. 229b50d902SRodney W. Grimes * 239b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 249b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 259b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 269b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 279b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 289b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 299b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 309b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 319b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 329b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 339b50d902SRodney W. Grimes * SUCH DAMAGE. 349b50d902SRodney W. Grimes */ 359b50d902SRodney W. Grimes 365d422d6aSPhilippe Charnier #if 0 376cc6f122SPhilippe Charnier #ifndef lint 389b50d902SRodney W. Grimes static char sccsid[] = "@(#)mbuf.c 8.1 (Berkeley) 6/6/93"; 399b50d902SRodney W. Grimes #endif /* not lint */ 406cc6f122SPhilippe Charnier #endif 416cc6f122SPhilippe Charnier 426cc6f122SPhilippe Charnier #include <sys/cdefs.h> 436cc6f122SPhilippe Charnier __FBSDID("$FreeBSD$"); 449b50d902SRodney W. Grimes 459b50d902SRodney W. Grimes #include <sys/param.h> 4613ae2e2dSGarrett Wollman #include <sys/mbuf.h> 479b50d902SRodney W. Grimes #include <sys/protosw.h> 489b50d902SRodney W. Grimes #include <sys/socket.h> 4913ae2e2dSGarrett Wollman #include <sys/sysctl.h> 509b50d902SRodney W. Grimes 515d422d6aSPhilippe Charnier #include <err.h> 52c8e6b689SRobert Watson #include <memstat.h> 539b50d902SRodney W. Grimes #include <stdio.h> 54af0e6bcdSAlfred Perlstein #include <stdlib.h> 5508442f8aSBosko Milekic #include <string.h> 569b50d902SRodney W. Grimes #include "netstat.h" 579b50d902SRodney W. Grimes 589b50d902SRodney W. Grimes #define YES 1 599b50d902SRodney W. Grimes typedef int bool; 609b50d902SRodney W. Grimes 61af0e6bcdSAlfred Perlstein static struct mbtypenames { 6270a61707SBosko Milekic short mt_type; 63a01e3379SDavid Malone const char *mt_name; 64af0e6bcdSAlfred Perlstein } mbtypenames[] = { 659b50d902SRodney W. Grimes { MT_DATA, "data" }, 669b50d902SRodney W. Grimes { MT_OOBDATA, "oob data" }, 679b50d902SRodney W. Grimes { MT_CONTROL, "ancillary data" }, 689b50d902SRodney W. Grimes { MT_HEADER, "packet headers" }, 695cc5ba1dSPeter Wemm #ifdef MT_SOCKET 709b50d902SRodney W. Grimes { MT_SOCKET, "socket structures" }, /* XXX */ 715cc5ba1dSPeter Wemm #endif 725cc5ba1dSPeter Wemm #ifdef MT_PCB 739b50d902SRodney W. Grimes { MT_PCB, "protocol control blocks" }, /* XXX */ 745cc5ba1dSPeter Wemm #endif 75bca92d96SOllivier Robert #ifdef MT_RTABLE 769b50d902SRodney W. Grimes { MT_RTABLE, "routing table entries" }, /* XXX */ 77bca92d96SOllivier Robert #endif 785cc5ba1dSPeter Wemm #ifdef MT_HTABLE 799b50d902SRodney W. Grimes { MT_HTABLE, "IMP host table entries" }, /* XXX */ 805cc5ba1dSPeter Wemm #endif 815cc5ba1dSPeter Wemm #ifdef MT_ATABLE 829b50d902SRodney W. Grimes { MT_ATABLE, "address resolution tables" }, 835cc5ba1dSPeter Wemm #endif 849b50d902SRodney W. Grimes { MT_FTABLE, "fragment reassembly queue headers" }, /* XXX */ 859b50d902SRodney W. Grimes { MT_SONAME, "socket names and addresses" }, 86ed9ff6ddSGary Palmer #ifdef MT_SOOPTS 879b50d902SRodney W. Grimes { MT_SOOPTS, "socket options" }, 88ed9ff6ddSGary Palmer #endif 895cc5ba1dSPeter Wemm #ifdef MT_RIGHTS 909b50d902SRodney W. Grimes { MT_RIGHTS, "access rights" }, 915cc5ba1dSPeter Wemm #endif 925cc5ba1dSPeter Wemm #ifdef MT_IFADDR 939b50d902SRodney W. Grimes { MT_IFADDR, "interface addresses" }, /* XXX */ 945cc5ba1dSPeter Wemm #endif 959b50d902SRodney W. Grimes { 0, 0 } 969b50d902SRodney W. Grimes }; 979b50d902SRodney W. Grimes 989b50d902SRodney W. Grimes /* 99c8e6b689SRobert Watson * Print mbuf statistics extracted from kmem. 1009b50d902SRodney W. Grimes */ 1019b50d902SRodney W. Grimes void 102c8e6b689SRobert Watson mbpr_kmem(u_long mbaddr, u_long nmbcaddr, u_long nmbufaddr, u_long mbhiaddr, 103c8e6b689SRobert Watson u_long clhiaddr, u_long mbloaddr, u_long clloaddr, u_long pgsaddr, 104c8e6b689SRobert Watson u_long mbpaddr) 1059b50d902SRodney W. Grimes { 106099a0e58SBosko Milekic int i, nmbclusters; 10770a61707SBosko Milekic short nmbtypes; 10808442f8aSBosko Milekic size_t mlen; 10970a61707SBosko Milekic long *mbtypes = NULL; 11008442f8aSBosko Milekic struct mbstat *mbstat = NULL; 11108442f8aSBosko Milekic struct mbtypenames *mp; 11208442f8aSBosko Milekic bool *seen = NULL; 11313ae2e2dSGarrett Wollman 114f70f5dd3SBosko Milekic mlen = sizeof *mbstat; 11508442f8aSBosko Milekic if ((mbstat = malloc(mlen)) == NULL) { 11608442f8aSBosko Milekic warn("malloc: cannot allocate memory for mbstat"); 11708442f8aSBosko Milekic goto err; 11808442f8aSBosko Milekic } 11908442f8aSBosko Milekic 12008442f8aSBosko Milekic if (kread(mbaddr, (char *)mbstat, sizeof mbstat)) 12108442f8aSBosko Milekic goto err; 122d15c5f56SRuslan Ermilov if (kread(nmbcaddr, (char *)&nmbclusters, sizeof(int))) 123d15c5f56SRuslan Ermilov goto err; 124c8e6b689SRobert Watson 125099a0e58SBosko Milekic if (mbstat->m_mbufs < 0) mbstat->m_mbufs = 0; /* XXX */ 126099a0e58SBosko Milekic if (mbstat->m_mclusts < 0) mbstat->m_mclusts = 0; /* XXX */ 12708442f8aSBosko Milekic 12870a61707SBosko Milekic nmbtypes = mbstat->m_numtypes; 12970a61707SBosko Milekic if ((seen = calloc(nmbtypes, sizeof(*seen))) == NULL) { 13070a61707SBosko Milekic warn("calloc: cannot allocate memory for mbtypes seen flag"); 13170a61707SBosko Milekic goto err; 13270a61707SBosko Milekic } 13370a61707SBosko Milekic if ((mbtypes = calloc(nmbtypes, sizeof(long *))) == NULL) { 13470a61707SBosko Milekic warn("calloc: cannot allocate memory for mbtypes"); 13570a61707SBosko Milekic goto err; 13670a61707SBosko Milekic } 13770a61707SBosko Milekic 13813ae2e2dSGarrett Wollman #undef MSIZE 13908442f8aSBosko Milekic #define MSIZE (mbstat->m_msize) 14013ae2e2dSGarrett Wollman #undef MCLBYTES 14108442f8aSBosko Milekic #define MCLBYTES (mbstat->m_mclbytes) 1429b50d902SRodney W. Grimes 143099a0e58SBosko Milekic printf("%lu mbufs in use\n", mbstat->m_mbufs); 144dbe0253aSAlfred Perlstein 14570a61707SBosko Milekic for (mp = mbtypenames; mp->mt_name; mp++) { 14670a61707SBosko Milekic if (mbtypes[mp->mt_type]) { 14770a61707SBosko Milekic seen[mp->mt_type] = YES; 14870a61707SBosko Milekic printf("\t %lu mbufs allocated to %s\n", 14970a61707SBosko Milekic mbtypes[mp->mt_type], mp->mt_name); 15070a61707SBosko Milekic } 15170a61707SBosko Milekic } 15270a61707SBosko Milekic for (i = 1; i < nmbtypes; i++) { 15370a61707SBosko Milekic if (!seen[i] && mbtypes[i]) 15470a61707SBosko Milekic printf("\t %lu mbufs allocated to <mbuf type: %d>\n", 15570a61707SBosko Milekic mbtypes[i], i); 15670a61707SBosko Milekic } 15708442f8aSBosko Milekic 158099a0e58SBosko Milekic printf("%lu/%d mbuf clusters in use (current/max)\n", 159099a0e58SBosko Milekic mbstat->m_mclusts, nmbclusters); 160099a0e58SBosko Milekic 161099a0e58SBosko Milekic printf("%lu KBytes allocated to network\n", (mbstat->m_mbufs * MSIZE + 162099a0e58SBosko Milekic mbstat->m_mclusts * MCLBYTES) / 1024); 1636171a280SMike Silbersack printf("%lu requests for sfbufs denied\n", mbstat->sf_allocfail); 1646171a280SMike Silbersack printf("%lu requests for sfbufs delayed\n", mbstat->sf_allocwait); 1656171a280SMike Silbersack printf("%lu requests for I/O initiated by sendfile\n", 1666171a280SMike Silbersack mbstat->sf_iocnt); 16708442f8aSBosko Milekic printf("%lu calls to protocol drain routines\n", mbstat->m_drain); 168af0e6bcdSAlfred Perlstein 169af0e6bcdSAlfred Perlstein err: 170af0e6bcdSAlfred Perlstein if (mbtypes != NULL) 171af0e6bcdSAlfred Perlstein free(mbtypes); 172af0e6bcdSAlfred Perlstein if (seen != NULL) 173af0e6bcdSAlfred Perlstein free(seen); 17408442f8aSBosko Milekic if (mbstat != NULL) 17508442f8aSBosko Milekic free(mbstat); 1769b50d902SRodney W. Grimes } 177c8e6b689SRobert Watson 178c8e6b689SRobert Watson /* 179c8e6b689SRobert Watson * If running on a live kernel, directly query the zone allocator for stats 180c8e6b689SRobert Watson * from the four mbuf-related zones/types. 181c8e6b689SRobert Watson */ 182c8e6b689SRobert Watson static void 183c8e6b689SRobert Watson mbpr_sysctl(void) 184c8e6b689SRobert Watson { 185c8e6b689SRobert Watson struct memory_type_list *mtlp; 186c8e6b689SRobert Watson struct memory_type *mtp; 187c8e6b689SRobert Watson u_int64_t mbuf_count, mbuf_bytes, mbuf_free, mbuf_failures, mbuf_size; 188c8e6b689SRobert Watson u_int64_t cluster_count, cluster_bytes, cluster_limit, cluster_free; 189c8e6b689SRobert Watson u_int64_t cluster_failures, cluster_size; 190c8e6b689SRobert Watson u_int64_t packet_count, packet_bytes, packet_free, packet_failures; 191c8e6b689SRobert Watson u_int64_t tag_count, tag_bytes; 192c8e6b689SRobert Watson u_int64_t bytes_inuse, bytes_incache, bytes_total; 193c8e6b689SRobert Watson int nsfbufs, nsfbufspeak, nsfbufsused; 194c8e6b689SRobert Watson struct mbstat mbstat; 195c8e6b689SRobert Watson size_t mlen; 196c8e6b689SRobert Watson 197c8e6b689SRobert Watson mtlp = memstat_mtl_alloc(); 198c8e6b689SRobert Watson if (mtlp == NULL) { 199c8e6b689SRobert Watson warn("memstat_mtl_alloc"); 200c8e6b689SRobert Watson return; 201c8e6b689SRobert Watson } 202c8e6b689SRobert Watson 203c8e6b689SRobert Watson /* 204c8e6b689SRobert Watson * Use memstat_sysctl_all() because some mbuf-related memory is in 205c8e6b689SRobert Watson * uma(9), and some malloc(9). 206c8e6b689SRobert Watson */ 207c8e6b689SRobert Watson if (memstat_sysctl_all(mtlp, 0) < 0) { 2084f7ac59bSRobert Watson warnx("memstat_sysctl_all: %s", 2094f7ac59bSRobert Watson memstat_strerror(memstat_mtl_geterror(mtlp))); 210c8e6b689SRobert Watson goto out; 211c8e6b689SRobert Watson } 212c8e6b689SRobert Watson 213c8e6b689SRobert Watson mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_MEM_NAME); 214c8e6b689SRobert Watson if (mtp == NULL) { 215c8e6b689SRobert Watson warnx("memstat_mtl_find: zone %s not found", MBUF_MEM_NAME); 216c8e6b689SRobert Watson goto out; 217c8e6b689SRobert Watson } 218c8e6b689SRobert Watson mbuf_count = memstat_get_count(mtp); 219c8e6b689SRobert Watson mbuf_bytes = memstat_get_bytes(mtp); 220c8e6b689SRobert Watson mbuf_free = memstat_get_free(mtp); 221c8e6b689SRobert Watson mbuf_failures = memstat_get_failures(mtp); 222c8e6b689SRobert Watson mbuf_size = memstat_get_size(mtp); 223c8e6b689SRobert Watson 224c8e6b689SRobert Watson mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_PACKET_MEM_NAME); 225c8e6b689SRobert Watson if (mtp == NULL) { 226c8e6b689SRobert Watson warnx("memstat_mtl_find: zone %s not found", 227c8e6b689SRobert Watson MBUF_PACKET_MEM_NAME); 228c8e6b689SRobert Watson goto out; 229c8e6b689SRobert Watson } 230c8e6b689SRobert Watson packet_count = memstat_get_count(mtp); 231c8e6b689SRobert Watson packet_bytes = memstat_get_bytes(mtp); 232c8e6b689SRobert Watson packet_free = memstat_get_free(mtp); 233c8e6b689SRobert Watson packet_failures = memstat_get_failures(mtp); 234c8e6b689SRobert Watson 235c8e6b689SRobert Watson mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_CLUSTER_MEM_NAME); 236c8e6b689SRobert Watson if (mtp == NULL) { 237c8e6b689SRobert Watson warnx("memstat_mtl_find: zone %s not found", 238c8e6b689SRobert Watson MBUF_CLUSTER_MEM_NAME); 239c8e6b689SRobert Watson goto out; 240c8e6b689SRobert Watson } 241c8e6b689SRobert Watson cluster_count = memstat_get_count(mtp); 242c8e6b689SRobert Watson cluster_bytes = memstat_get_bytes(mtp); 243c8e6b689SRobert Watson cluster_limit = memstat_get_countlimit(mtp); 244c8e6b689SRobert Watson cluster_free = memstat_get_free(mtp); 245c8e6b689SRobert Watson cluster_failures = memstat_get_failures(mtp); 246c8e6b689SRobert Watson cluster_size = memstat_get_size(mtp); 247c8e6b689SRobert Watson 248c8e6b689SRobert Watson mtp = memstat_mtl_find(mtlp, ALLOCATOR_MALLOC, MBUF_TAG_MEM_NAME); 249c8e6b689SRobert Watson if (mtp == NULL) { 250c8e6b689SRobert Watson warnx("memstat_mtl_find: malloc type %s not found", 251c8e6b689SRobert Watson MBUF_TAG_MEM_NAME); 252c8e6b689SRobert Watson goto out; 253c8e6b689SRobert Watson } 254c8e6b689SRobert Watson tag_count = memstat_get_count(mtp); 255c8e6b689SRobert Watson tag_bytes = memstat_get_bytes(mtp); 256c8e6b689SRobert Watson 257c8e6b689SRobert Watson printf("%llu/%llu/%llu mbufs in use (current/cache/total)\n", 258c8e6b689SRobert Watson mbuf_count + packet_count, mbuf_free + packet_free, 259c8e6b689SRobert Watson mbuf_count + packet_count + mbuf_free + packet_free); 260c8e6b689SRobert Watson 261c8e6b689SRobert Watson printf("%llu/%llu/%llu/%llu mbuf clusters in use " 262c8e6b689SRobert Watson "(current/cache/total/max)\n", 263c8e6b689SRobert Watson cluster_count - packet_free, cluster_free + packet_free, 264c8e6b689SRobert Watson cluster_count + cluster_free, cluster_limit); 265c8e6b689SRobert Watson 266c8e6b689SRobert Watson #if 0 267c8e6b689SRobert Watson printf("%llu mbuf tags in use\n", tag_count); 268c8e6b689SRobert Watson #endif 269c8e6b689SRobert Watson 270c8e6b689SRobert Watson mlen = sizeof(nsfbufs); 271c8e6b689SRobert Watson if (!sysctlbyname("kern.ipc.nsfbufs", &nsfbufs, &mlen, NULL, 0) && 272c8e6b689SRobert Watson !sysctlbyname("kern.ipc.nsfbufsused", &nsfbufsused, &mlen, NULL, 273c8e6b689SRobert Watson 0) && 274c8e6b689SRobert Watson !sysctlbyname("kern.ipc.nsfbufspeak", &nsfbufspeak, &mlen, NULL, 275c8e6b689SRobert Watson 0)) { 276c8e6b689SRobert Watson printf("%d/%d/%d sfbufs in use (current/peak/max)\n", 277c8e6b689SRobert Watson nsfbufsused, nsfbufspeak, nsfbufs); 278c8e6b689SRobert Watson } 279c8e6b689SRobert Watson 280c8e6b689SRobert Watson /*- 281c8e6b689SRobert Watson * Calculate in-use bytes as: 282c8e6b689SRobert Watson * - straight mbuf memory 283c8e6b689SRobert Watson * - mbuf memory in packets 284c8e6b689SRobert Watson * - the clusters attached to packets 285c8e6b689SRobert Watson * - and the rest of the non-packet-attached clusters. 286c8e6b689SRobert Watson * - m_tag memory 287c8e6b689SRobert Watson * This avoids counting the clusters attached to packets in the cache. 288c8e6b689SRobert Watson * This currently excludes sf_buf space. 289c8e6b689SRobert Watson */ 290c8e6b689SRobert Watson bytes_inuse = 291c8e6b689SRobert Watson mbuf_bytes + /* straight mbuf memory */ 292c8e6b689SRobert Watson packet_bytes + /* mbufs in packets */ 293c8e6b689SRobert Watson (packet_count * cluster_size) + /* clusters in packets */ 294c8e6b689SRobert Watson /* other clusters */ 295c8e6b689SRobert Watson ((cluster_count - packet_count - packet_free) * cluster_size) + 296c8e6b689SRobert Watson tag_bytes; 297c8e6b689SRobert Watson 298c8e6b689SRobert Watson /* 299c8e6b689SRobert Watson * Calculate in-cache bytes as: 300c8e6b689SRobert Watson * - cached straught mbufs 301c8e6b689SRobert Watson * - cached packet mbufs 302c8e6b689SRobert Watson * - cached packet clusters 303c8e6b689SRobert Watson * - cached straight clusters 304c8e6b689SRobert Watson * This currently excludes sf_buf space. 305c8e6b689SRobert Watson */ 306c8e6b689SRobert Watson bytes_incache = 307c8e6b689SRobert Watson (mbuf_free * mbuf_size) + /* straight free mbufs */ 308c8e6b689SRobert Watson (packet_free * mbuf_size) + /* mbufs in free packets */ 309c8e6b689SRobert Watson (packet_free * cluster_size) + /* clusters in free packets */ 310c8e6b689SRobert Watson (cluster_free * cluster_size); /* free clusters */ 311c8e6b689SRobert Watson 312c8e6b689SRobert Watson /* 313c8e6b689SRobert Watson * Total is bytes in use + bytes in cache. This doesn't take into 314c8e6b689SRobert Watson * account various other misc data structures, overhead, etc, but 315c8e6b689SRobert Watson * gives the user something useful despite that. 316c8e6b689SRobert Watson */ 317c8e6b689SRobert Watson bytes_total = bytes_inuse + bytes_incache; 318c8e6b689SRobert Watson 319c8e6b689SRobert Watson printf("%lluK/%lluK/%lluK bytes allocated to network " 320c8e6b689SRobert Watson "(current/cache/total)\n", bytes_inuse / 1024, 321c8e6b689SRobert Watson bytes_incache / 1024, bytes_total / 1024); 322c8e6b689SRobert Watson 323c8e6b689SRobert Watson #if 0 324c8e6b689SRobert Watson printf("%llu/%llu/%llu requests for mbufs denied (mbufs/clusters/" 325c8e6b689SRobert Watson "mbuf+clusters)\n", mbuf_failures, cluster_failures, 326c8e6b689SRobert Watson packet_failures); 327c8e6b689SRobert Watson #endif 328c8e6b689SRobert Watson 329c8e6b689SRobert Watson mlen = sizeof(mbstat); 330c8e6b689SRobert Watson if (!sysctlbyname("kern.ipc.mbstat", &mbstat, &mlen, NULL, 0)) { 331c8e6b689SRobert Watson printf("%lu requests for sfbufs denied\n", 332c8e6b689SRobert Watson mbstat.sf_allocfail); 333c8e6b689SRobert Watson printf("%lu requests for sfbufs delayed\n", 334c8e6b689SRobert Watson mbstat.sf_allocwait); 335c8e6b689SRobert Watson printf("%lu requests for I/O initiated by sendfile\n", 336c8e6b689SRobert Watson mbstat.sf_iocnt); 337c8e6b689SRobert Watson printf("%lu calls to protocol drain routines\n", 338c8e6b689SRobert Watson mbstat.m_drain); 339c8e6b689SRobert Watson } 340c8e6b689SRobert Watson 341c8e6b689SRobert Watson out: 342c8e6b689SRobert Watson memstat_mtl_free(mtlp); 343c8e6b689SRobert Watson } 344c8e6b689SRobert Watson 345c8e6b689SRobert Watson /* 346c8e6b689SRobert Watson * Print mbuf statistics. 347c8e6b689SRobert Watson */ 348c8e6b689SRobert Watson void 349c8e6b689SRobert Watson mbpr(u_long mbaddr, u_long mbtaddr __unused, u_long nmbcaddr, u_long nmbufaddr, 350c8e6b689SRobert Watson u_long mbhiaddr, u_long clhiaddr, u_long mbloaddr, u_long clloaddr, 351c8e6b689SRobert Watson u_long cpusaddr __unused, u_long pgsaddr, u_long mbpaddr) 352c8e6b689SRobert Watson { 353c8e6b689SRobert Watson 354c8e6b689SRobert Watson if (mbaddr != 0) 355c8e6b689SRobert Watson mbpr_kmem(mbaddr, nmbcaddr, nmbufaddr, mbhiaddr, clhiaddr, 356c8e6b689SRobert Watson mbloaddr, clloaddr, pgsaddr, mbpaddr); 357c8e6b689SRobert Watson else 358c8e6b689SRobert Watson mbpr_sysctl(); 359c8e6b689SRobert Watson } 360