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> 52d4426f28SRobert Watson #include <kvm.h> 53c8e6b689SRobert Watson #include <memstat.h> 547b95a1ebSYaroslav Tykhiy #include <stdint.h> 559b50d902SRodney W. Grimes #include <stdio.h> 56af0e6bcdSAlfred Perlstein #include <stdlib.h> 5708442f8aSBosko Milekic #include <string.h> 589b50d902SRodney W. Grimes #include "netstat.h" 599b50d902SRodney W. Grimes 609b50d902SRodney W. Grimes /* 61d4426f28SRobert Watson * Print mbuf statistics. 629b50d902SRodney W. Grimes */ 639b50d902SRodney W. Grimes void 64d4426f28SRobert Watson mbpr(void *kvmd, u_long mbaddr) 65c8e6b689SRobert Watson { 66c8e6b689SRobert Watson struct memory_type_list *mtlp; 67c8e6b689SRobert Watson struct memory_type *mtp; 687b95a1ebSYaroslav Tykhiy uintmax_t mbuf_count, mbuf_bytes, mbuf_free, mbuf_failures, mbuf_size; 697b95a1ebSYaroslav Tykhiy uintmax_t cluster_count, cluster_bytes, cluster_limit, cluster_free; 707b95a1ebSYaroslav Tykhiy uintmax_t cluster_failures, cluster_size; 717b95a1ebSYaroslav Tykhiy uintmax_t packet_count, packet_bytes, packet_free, packet_failures; 727b95a1ebSYaroslav Tykhiy uintmax_t tag_count, tag_bytes; 737b95a1ebSYaroslav Tykhiy uintmax_t jumbop_count, jumbop_bytes, jumbop_limit, jumbop_free; 747b95a1ebSYaroslav Tykhiy uintmax_t jumbop_failures, jumbop_size; 757b95a1ebSYaroslav Tykhiy uintmax_t jumbo9_count, jumbo9_bytes, jumbo9_limit, jumbo9_free; 767b95a1ebSYaroslav Tykhiy uintmax_t jumbo9_failures, jumbo9_size; 777b95a1ebSYaroslav Tykhiy uintmax_t jumbo16_count, jumbo16_bytes, jumbo16_limit, jumbo16_free; 787b95a1ebSYaroslav Tykhiy uintmax_t jumbo16_failures, jumbo16_size; 797b95a1ebSYaroslav Tykhiy uintmax_t bytes_inuse, bytes_incache, bytes_total; 80c8e6b689SRobert Watson int nsfbufs, nsfbufspeak, nsfbufsused; 81c8e6b689SRobert Watson struct mbstat mbstat; 82c8e6b689SRobert Watson size_t mlen; 83d4426f28SRobert Watson int error, live; 84c8e6b689SRobert Watson 85d4426f28SRobert Watson live = (kvmd == NULL); 86c8e6b689SRobert Watson mtlp = memstat_mtl_alloc(); 87c8e6b689SRobert Watson if (mtlp == NULL) { 88c8e6b689SRobert Watson warn("memstat_mtl_alloc"); 89c8e6b689SRobert Watson return; 90c8e6b689SRobert Watson } 91c8e6b689SRobert Watson 92c8e6b689SRobert Watson /* 93d4426f28SRobert Watson * Use memstat_*_all() because some mbuf-related memory is in uma(9), 94d4426f28SRobert Watson * and some malloc(9). 95c8e6b689SRobert Watson */ 96d4426f28SRobert Watson if (live) { 97c8e6b689SRobert Watson if (memstat_sysctl_all(mtlp, 0) < 0) { 984f7ac59bSRobert Watson warnx("memstat_sysctl_all: %s", 994f7ac59bSRobert Watson memstat_strerror(memstat_mtl_geterror(mtlp))); 100c8e6b689SRobert Watson goto out; 101c8e6b689SRobert Watson } 102d4426f28SRobert Watson } else { 103d4426f28SRobert Watson if (memstat_kvm_all(mtlp, kvmd) < 0) { 104d4426f28SRobert Watson error = memstat_mtl_geterror(mtlp); 105d4426f28SRobert Watson if (error == MEMSTAT_ERROR_KVM) 106d4426f28SRobert Watson warnx("memstat_kvm_all: %s", 107d4426f28SRobert Watson kvm_geterr(kvmd)); 108d4426f28SRobert Watson else 109d4426f28SRobert Watson warnx("memstat_kvm_all: %s", 110d4426f28SRobert Watson memstat_strerror(error)); 111d4426f28SRobert Watson goto out; 112d4426f28SRobert Watson } 113d4426f28SRobert Watson } 114c8e6b689SRobert Watson 115c8e6b689SRobert Watson mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_MEM_NAME); 116c8e6b689SRobert Watson if (mtp == NULL) { 117c8e6b689SRobert Watson warnx("memstat_mtl_find: zone %s not found", MBUF_MEM_NAME); 118c8e6b689SRobert Watson goto out; 119c8e6b689SRobert Watson } 120c8e6b689SRobert Watson mbuf_count = memstat_get_count(mtp); 121c8e6b689SRobert Watson mbuf_bytes = memstat_get_bytes(mtp); 122c8e6b689SRobert Watson mbuf_free = memstat_get_free(mtp); 123c8e6b689SRobert Watson mbuf_failures = memstat_get_failures(mtp); 124c8e6b689SRobert Watson mbuf_size = memstat_get_size(mtp); 125c8e6b689SRobert Watson 126c8e6b689SRobert Watson mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_PACKET_MEM_NAME); 127c8e6b689SRobert Watson if (mtp == NULL) { 128c8e6b689SRobert Watson warnx("memstat_mtl_find: zone %s not found", 129c8e6b689SRobert Watson MBUF_PACKET_MEM_NAME); 130c8e6b689SRobert Watson goto out; 131c8e6b689SRobert Watson } 132c8e6b689SRobert Watson packet_count = memstat_get_count(mtp); 133c8e6b689SRobert Watson packet_bytes = memstat_get_bytes(mtp); 134c8e6b689SRobert Watson packet_free = memstat_get_free(mtp); 135c8e6b689SRobert Watson packet_failures = memstat_get_failures(mtp); 136c8e6b689SRobert Watson 137c8e6b689SRobert Watson mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_CLUSTER_MEM_NAME); 138c8e6b689SRobert Watson if (mtp == NULL) { 139c8e6b689SRobert Watson warnx("memstat_mtl_find: zone %s not found", 140c8e6b689SRobert Watson MBUF_CLUSTER_MEM_NAME); 141c8e6b689SRobert Watson goto out; 142c8e6b689SRobert Watson } 143c8e6b689SRobert Watson cluster_count = memstat_get_count(mtp); 144c8e6b689SRobert Watson cluster_bytes = memstat_get_bytes(mtp); 145c8e6b689SRobert Watson cluster_limit = memstat_get_countlimit(mtp); 146c8e6b689SRobert Watson cluster_free = memstat_get_free(mtp); 147c8e6b689SRobert Watson cluster_failures = memstat_get_failures(mtp); 148c8e6b689SRobert Watson cluster_size = memstat_get_size(mtp); 149c8e6b689SRobert Watson 150c8e6b689SRobert Watson mtp = memstat_mtl_find(mtlp, ALLOCATOR_MALLOC, MBUF_TAG_MEM_NAME); 151c8e6b689SRobert Watson if (mtp == NULL) { 152c8e6b689SRobert Watson warnx("memstat_mtl_find: malloc type %s not found", 153c8e6b689SRobert Watson MBUF_TAG_MEM_NAME); 154c8e6b689SRobert Watson goto out; 155c8e6b689SRobert Watson } 156c8e6b689SRobert Watson tag_count = memstat_get_count(mtp); 157c8e6b689SRobert Watson tag_bytes = memstat_get_bytes(mtp); 158c8e6b689SRobert Watson 1592b22cf9cSAndre Oppermann mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_JUMBOP_MEM_NAME); 1602b22cf9cSAndre Oppermann if (mtp == NULL) { 1612b22cf9cSAndre Oppermann warnx("memstat_mtl_find: zone %s not found", 1622b22cf9cSAndre Oppermann MBUF_JUMBOP_MEM_NAME); 1632b22cf9cSAndre Oppermann goto out; 1642b22cf9cSAndre Oppermann } 1652b22cf9cSAndre Oppermann jumbop_count = memstat_get_count(mtp); 1662b22cf9cSAndre Oppermann jumbop_bytes = memstat_get_bytes(mtp); 1672b22cf9cSAndre Oppermann jumbop_limit = memstat_get_countlimit(mtp); 1682b22cf9cSAndre Oppermann jumbop_free = memstat_get_free(mtp); 1692b22cf9cSAndre Oppermann jumbop_failures = memstat_get_failures(mtp); 1702b22cf9cSAndre Oppermann jumbop_size = memstat_get_size(mtp); 1712b22cf9cSAndre Oppermann 1722b22cf9cSAndre Oppermann mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_JUMBO9_MEM_NAME); 1732b22cf9cSAndre Oppermann if (mtp == NULL) { 1742b22cf9cSAndre Oppermann warnx("memstat_mtl_find: zone %s not found", 1752b22cf9cSAndre Oppermann MBUF_JUMBO9_MEM_NAME); 1762b22cf9cSAndre Oppermann goto out; 1772b22cf9cSAndre Oppermann } 1782b22cf9cSAndre Oppermann jumbo9_count = memstat_get_count(mtp); 1792b22cf9cSAndre Oppermann jumbo9_bytes = memstat_get_bytes(mtp); 1802b22cf9cSAndre Oppermann jumbo9_limit = memstat_get_countlimit(mtp); 1812b22cf9cSAndre Oppermann jumbo9_free = memstat_get_free(mtp); 1822b22cf9cSAndre Oppermann jumbo9_failures = memstat_get_failures(mtp); 1832b22cf9cSAndre Oppermann jumbo9_size = memstat_get_size(mtp); 1842b22cf9cSAndre Oppermann 1852b22cf9cSAndre Oppermann mtp = memstat_mtl_find(mtlp, ALLOCATOR_UMA, MBUF_JUMBO16_MEM_NAME); 1862b22cf9cSAndre Oppermann if (mtp == NULL) { 1872b22cf9cSAndre Oppermann warnx("memstat_mtl_find: zone %s not found", 1882b22cf9cSAndre Oppermann MBUF_JUMBO16_MEM_NAME); 1892b22cf9cSAndre Oppermann goto out; 1902b22cf9cSAndre Oppermann } 1912b22cf9cSAndre Oppermann jumbo16_count = memstat_get_count(mtp); 1922b22cf9cSAndre Oppermann jumbo16_bytes = memstat_get_bytes(mtp); 1932b22cf9cSAndre Oppermann jumbo16_limit = memstat_get_countlimit(mtp); 1942b22cf9cSAndre Oppermann jumbo16_free = memstat_get_free(mtp); 1952b22cf9cSAndre Oppermann jumbo16_failures = memstat_get_failures(mtp); 1962b22cf9cSAndre Oppermann jumbo16_size = memstat_get_size(mtp); 1972b22cf9cSAndre Oppermann 1987b95a1ebSYaroslav Tykhiy printf("%ju/%ju/%ju mbufs in use (current/cache/total)\n", 199c8e6b689SRobert Watson mbuf_count + packet_count, mbuf_free + packet_free, 200c8e6b689SRobert Watson mbuf_count + packet_count + mbuf_free + packet_free); 201c8e6b689SRobert Watson 2027b95a1ebSYaroslav Tykhiy printf("%ju/%ju/%ju/%ju mbuf clusters in use " 203c8e6b689SRobert Watson "(current/cache/total/max)\n", 204c8e6b689SRobert Watson cluster_count - packet_free, cluster_free + packet_free, 205c8e6b689SRobert Watson cluster_count + cluster_free, cluster_limit); 206c8e6b689SRobert Watson 2077b95a1ebSYaroslav Tykhiy printf("%ju/%ju mbuf+clusters out of packet secondary zone in use " 2081434cbd6SAndre Oppermann "(current/cache)\n", 2091434cbd6SAndre Oppermann packet_count, packet_free); 2101434cbd6SAndre Oppermann 2117b95a1ebSYaroslav Tykhiy printf("%ju/%ju/%ju/%ju %juk (page size) jumbo clusters in use " 2122b22cf9cSAndre Oppermann "(current/cache/total/max)\n", 2132b22cf9cSAndre Oppermann jumbop_count, jumbop_free, jumbop_count + jumbop_free, 2142b22cf9cSAndre Oppermann jumbop_limit, jumbop_size / 1024); 2152b22cf9cSAndre Oppermann 2167b95a1ebSYaroslav Tykhiy printf("%ju/%ju/%ju/%ju 9k jumbo clusters in use " 2172b22cf9cSAndre Oppermann "(current/cache/total/max)\n", 2182b22cf9cSAndre Oppermann jumbo9_count, jumbo9_free, jumbo9_count + jumbo9_free, 2192b22cf9cSAndre Oppermann jumbo9_limit); 2202b22cf9cSAndre Oppermann 2217b95a1ebSYaroslav Tykhiy printf("%ju/%ju/%ju/%ju 16k jumbo clusters in use " 2222b22cf9cSAndre Oppermann "(current/cache/total/max)\n", 2232b22cf9cSAndre Oppermann jumbo16_count, jumbo16_free, jumbo16_count + jumbo16_free, 2242b22cf9cSAndre Oppermann jumbo16_limit); 2252b22cf9cSAndre Oppermann 226c8e6b689SRobert Watson #if 0 2277b95a1ebSYaroslav Tykhiy printf("%ju mbuf tags in use\n", tag_count); 228c8e6b689SRobert Watson #endif 229c8e6b689SRobert Watson 230c8e6b689SRobert Watson /*- 231c8e6b689SRobert Watson * Calculate in-use bytes as: 232c8e6b689SRobert Watson * - straight mbuf memory 233c8e6b689SRobert Watson * - mbuf memory in packets 234c8e6b689SRobert Watson * - the clusters attached to packets 235c8e6b689SRobert Watson * - and the rest of the non-packet-attached clusters. 236c8e6b689SRobert Watson * - m_tag memory 237c8e6b689SRobert Watson * This avoids counting the clusters attached to packets in the cache. 238c8e6b689SRobert Watson * This currently excludes sf_buf space. 239c8e6b689SRobert Watson */ 240c8e6b689SRobert Watson bytes_inuse = 241c8e6b689SRobert Watson mbuf_bytes + /* straight mbuf memory */ 242c8e6b689SRobert Watson packet_bytes + /* mbufs in packets */ 243c8e6b689SRobert Watson (packet_count * cluster_size) + /* clusters in packets */ 244c8e6b689SRobert Watson /* other clusters */ 245c8e6b689SRobert Watson ((cluster_count - packet_count - packet_free) * cluster_size) + 2462b22cf9cSAndre Oppermann tag_bytes + 2472b22cf9cSAndre Oppermann (jumbop_count * jumbop_size) + /* jumbo clusters */ 2482b22cf9cSAndre Oppermann (jumbo9_count * jumbo9_size) + 2492b22cf9cSAndre Oppermann (jumbo16_count * jumbo16_size); 250c8e6b689SRobert Watson 251c8e6b689SRobert Watson /* 252c8e6b689SRobert Watson * Calculate in-cache bytes as: 253c8e6b689SRobert Watson * - cached straught mbufs 254c8e6b689SRobert Watson * - cached packet mbufs 255c8e6b689SRobert Watson * - cached packet clusters 256c8e6b689SRobert Watson * - cached straight clusters 257c8e6b689SRobert Watson * This currently excludes sf_buf space. 258c8e6b689SRobert Watson */ 259c8e6b689SRobert Watson bytes_incache = 260c8e6b689SRobert Watson (mbuf_free * mbuf_size) + /* straight free mbufs */ 261c8e6b689SRobert Watson (packet_free * mbuf_size) + /* mbufs in free packets */ 262c8e6b689SRobert Watson (packet_free * cluster_size) + /* clusters in free packets */ 2632b22cf9cSAndre Oppermann (cluster_free * cluster_size) + /* free clusters */ 2642b22cf9cSAndre Oppermann (jumbop_free * jumbop_size) + /* jumbo clusters */ 2652b22cf9cSAndre Oppermann (jumbo9_free * jumbo9_size) + 2662b22cf9cSAndre Oppermann (jumbo16_free * jumbo16_size); 267c8e6b689SRobert Watson 268c8e6b689SRobert Watson /* 269c8e6b689SRobert Watson * Total is bytes in use + bytes in cache. This doesn't take into 270c8e6b689SRobert Watson * account various other misc data structures, overhead, etc, but 271c8e6b689SRobert Watson * gives the user something useful despite that. 272c8e6b689SRobert Watson */ 273c8e6b689SRobert Watson bytes_total = bytes_inuse + bytes_incache; 274c8e6b689SRobert Watson 2757b95a1ebSYaroslav Tykhiy printf("%juK/%juK/%juK bytes allocated to network " 276c8e6b689SRobert Watson "(current/cache/total)\n", bytes_inuse / 1024, 277c8e6b689SRobert Watson bytes_incache / 1024, bytes_total / 1024); 278c8e6b689SRobert Watson 2797b95a1ebSYaroslav Tykhiy printf("%ju/%ju/%ju requests for mbufs denied (mbufs/clusters/" 280c8e6b689SRobert Watson "mbuf+clusters)\n", mbuf_failures, cluster_failures, 281c8e6b689SRobert Watson packet_failures); 282c8e6b689SRobert Watson 2837b95a1ebSYaroslav Tykhiy printf("%ju/%ju/%ju requests for jumbo clusters denied " 2847b95a1ebSYaroslav Tykhiy "(%juk/9k/16k)\n", jumbop_failures, jumbo9_failures, 2852b22cf9cSAndre Oppermann jumbo16_failures, jumbop_size / 1024); 2862b22cf9cSAndre Oppermann 287d4426f28SRobert Watson if (live) { 288dd8dfa82SRobert Watson mlen = sizeof(nsfbufs); 289dd8dfa82SRobert Watson if (!sysctlbyname("kern.ipc.nsfbufs", &nsfbufs, &mlen, NULL, 290dd8dfa82SRobert Watson 0) && 291dd8dfa82SRobert Watson !sysctlbyname("kern.ipc.nsfbufsused", &nsfbufsused, 292dd8dfa82SRobert Watson &mlen, NULL, 0) && 293dd8dfa82SRobert Watson !sysctlbyname("kern.ipc.nsfbufspeak", &nsfbufspeak, 294dd8dfa82SRobert Watson &mlen, NULL, 0)) 295dd8dfa82SRobert Watson printf("%d/%d/%d sfbufs in use (current/peak/max)\n", 296dd8dfa82SRobert Watson nsfbufsused, nsfbufspeak, nsfbufs); 297c8e6b689SRobert Watson mlen = sizeof(mbstat); 298d4426f28SRobert Watson if (sysctlbyname("kern.ipc.mbstat", &mbstat, &mlen, NULL, 0)) { 299d4426f28SRobert Watson warn("kern.ipc.mbstat"); 300d4426f28SRobert Watson goto out; 301d4426f28SRobert Watson } 302d4426f28SRobert Watson } else { 303d4426f28SRobert Watson if (kread(mbaddr, (char *)&mbstat, sizeof mbstat)) 304d4426f28SRobert Watson goto out; 305d4426f28SRobert Watson } 306d4426f28SRobert Watson printf("%lu requests for sfbufs denied\n", mbstat.sf_allocfail); 307d4426f28SRobert Watson printf("%lu requests for sfbufs delayed\n", mbstat.sf_allocwait); 308c8e6b689SRobert Watson printf("%lu requests for I/O initiated by sendfile\n", 309c8e6b689SRobert Watson mbstat.sf_iocnt); 310d4426f28SRobert Watson printf("%lu calls to protocol drain routines\n", mbstat.m_drain); 311c8e6b689SRobert Watson out: 312c8e6b689SRobert Watson memstat_mtl_free(mtlp); 313c8e6b689SRobert Watson } 314