freebsd-skq/usr.bin/netstat/mbuf.c

219 lines
6.5 KiB
C
Raw Normal View History

1994-05-27 12:33:43 +00:00
/*
* Copyright (c) 1983, 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
#if 0
1994-05-27 12:33:43 +00:00
static char sccsid[] = "@(#)mbuf.c 8.1 (Berkeley) 6/6/93";
#endif
static const char rcsid[] =
1999-08-28 01:08:13 +00:00
"$FreeBSD$";
1994-05-27 12:33:43 +00:00
#endif /* not lint */
#include <sys/param.h>
#include <sys/mbuf.h>
1994-05-27 12:33:43 +00:00
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
1994-05-27 12:33:43 +00:00
#include <err.h>
1994-05-27 12:33:43 +00:00
#include <stdio.h>
#include <stdlib.h>
1994-05-27 12:33:43 +00:00
#include "netstat.h"
#define YES 1
typedef int bool;
static struct mbtypenames {
1994-05-27 12:33:43 +00:00
int mt_type;
char *mt_name;
} mbtypenames[] = {
1994-05-27 12:33:43 +00:00
{ MT_DATA, "data" },
{ MT_OOBDATA, "oob data" },
{ MT_CONTROL, "ancillary data" },
{ MT_HEADER, "packet headers" },
#ifdef MT_SOCKET
1994-05-27 12:33:43 +00:00
{ MT_SOCKET, "socket structures" }, /* XXX */
#endif
#ifdef MT_PCB
1994-05-27 12:33:43 +00:00
{ MT_PCB, "protocol control blocks" }, /* XXX */
#endif
#ifdef MT_RTABLE
1994-05-27 12:33:43 +00:00
{ MT_RTABLE, "routing table entries" }, /* XXX */
#endif
#ifdef MT_HTABLE
1994-05-27 12:33:43 +00:00
{ MT_HTABLE, "IMP host table entries" }, /* XXX */
#endif
#ifdef MT_ATABLE
1994-05-27 12:33:43 +00:00
{ MT_ATABLE, "address resolution tables" },
#endif
1994-05-27 12:33:43 +00:00
{ MT_FTABLE, "fragment reassembly queue headers" }, /* XXX */
{ MT_SONAME, "socket names and addresses" },
#ifdef MT_SOOPTS
1994-05-27 12:33:43 +00:00
{ MT_SOOPTS, "socket options" },
#endif
#ifdef MT_RIGHTS
1994-05-27 12:33:43 +00:00
{ MT_RIGHTS, "access rights" },
#endif
#ifdef MT_IFADDR
1994-05-27 12:33:43 +00:00
{ MT_IFADDR, "interface addresses" }, /* XXX */
#endif
1994-05-27 12:33:43 +00:00
{ 0, 0 }
};
/*
* Print mbuf statistics.
*/
void
2001-06-15 23:35:13 +00:00
mbpr(u_long mbaddr, u_long mbtaddr, u_long nmbcaddr, u_long nmbufaddr)
1994-05-27 12:33:43 +00:00
{
u_long totmem, totpossible, totmbufs;
1994-05-27 12:33:43 +00:00
register int i;
struct mbstat mbstat;
struct mbtypenames *mp;
int name[3], nmbclusters, nmbufs, nmbcnt, nmbtypes;
size_t nmbclen, nmbuflen, nmbcntlen, mbstatlen, mbtypeslen;
u_long *mbtypes;
bool *seen; /* "have we seen this type yet?" */
mbtypes = NULL;
seen = NULL;
1994-05-27 12:33:43 +00:00
/*
* XXX
* We can't kread() mbtypeslen from a core image so we'll
* bogusly assume it's the same as in the running kernel.
*/
if (sysctlbyname("kern.ipc.mbtypes", NULL, &mbtypeslen, NULL, 0) < 0) {
warn("sysctl: retrieving mbtypes length");
goto err;
}
if ((mbtypes = malloc(mbtypeslen)) == NULL) {
warn("malloc: %lu bytes for mbtypes", (u_long)mbtypeslen);
goto err;
}
nmbtypes = mbtypeslen / sizeof(*mbtypes);
if ((seen = calloc(nmbtypes, sizeof(*seen))) == NULL) {
warn("calloc");
goto err;
}
if (mbaddr) {
if (kread(mbaddr, (char *)&mbstat, sizeof mbstat))
goto err;
if (kread(mbtaddr, (char *)mbtypes, mbtypeslen))
goto err;
if (kread(nmbcaddr, (char *)&nmbclusters, sizeof(int)))
goto err;
if (kread(nmbufaddr, (char *)&nmbufs, sizeof(int)))
goto err;
} else {
name[0] = CTL_KERN;
name[1] = KERN_IPC;
name[2] = KIPC_MBSTAT;
mbstatlen = sizeof mbstat;
if (sysctl(name, 3, &mbstat, &mbstatlen, 0, 0) < 0) {
warn("sysctl: retrieving mbstat");
goto err;
}
if (sysctlbyname("kern.ipc.mbtypes", mbtypes, &mbtypeslen, NULL,
0) < 0) {
warn("sysctl: retrieving mbtypes");
goto err;
}
name[2] = KIPC_NMBCLUSTERS;
nmbclen = sizeof(int);
if (sysctl(name, 3, &nmbclusters, &nmbclen, 0, 0) < 0) {
warn("sysctl: retrieving nmbclusters");
goto err;
}
nmbuflen = sizeof(int);
if (sysctlbyname("kern.ipc.nmbufs", &nmbufs, &nmbuflen, 0, 0) < 0) {
warn("sysctl: retrieving nmbufs");
goto err;
}
}
nmbcntlen = sizeof(int);
if (sysctlbyname("kern.ipc.nmbcnt", &nmbcnt, &nmbcntlen, 0, 0) < 0) {
warn("sysctl: retrieving nmbcnt");
goto err;
}
#undef MSIZE
#define MSIZE (mbstat.m_msize)
#undef MCLBYTES
#define MCLBYTES (mbstat.m_mclbytes)
1994-05-27 12:33:43 +00:00
totmbufs = 0;
for (mp = mbtypenames; mp->mt_name; mp++)
totmbufs += mbtypes[mp->mt_type];
printf("%lu/%lu/%u mbufs in use (current/peak/max):\n", totmbufs,
mbstat.m_mbufs, nmbufs);
for (mp = mbtypenames; mp->mt_name; mp++)
if (mbtypes[mp->mt_type]) {
1994-05-27 12:33:43 +00:00
seen[mp->mt_type] = YES;
printf("\t%lu mbufs allocated to %s\n",
mbtypes[mp->mt_type], mp->mt_name);
1994-05-27 12:33:43 +00:00
}
seen[MT_FREE] = YES;
for (i = 0; i < nmbtypes; i++)
if (!seen[i] && mbtypes[i]) {
printf("\t%lu mbufs allocated to <mbuf type %d>\n",
mbtypes[i], i);
1994-05-27 12:33:43 +00:00
}
1998-07-06 21:01:54 +00:00
printf("%lu/%lu/%u mbuf clusters in use (current/peak/max)\n",
mbstat.m_clusters - mbstat.m_clfree, mbstat.m_clusters,
nmbclusters);
Replace the mbuf external reference counting code with something that should be better. The old code counted references to mbuf clusters by using the offset of the cluster from the start of memory allocated for mbufs and clusters as an index into an array of chars, which did the reference counting. If the external storage was not a cluster then reference counting had to be done by the code using that external storage. NetBSD's system of linked lists of mbufs was cosidered, but Alfred felt it would have locking issues when the kernel was made more SMP friendly. The system implimented uses a pool of unions to track external storage. The union contains an int for counting the references and a pointer for forming a free list. The reference counts are incremented and decremented atomically and so should be SMP friendly. This system can track reference counts for any sort of external storage. Access to the reference counting stuff is now through macros defined in mbuf.h, so it should be easier to make changes to the system in the future. The possibility of storing the reference count in one of the referencing mbufs was considered, but was rejected 'cos it would often leave extra mbufs allocated. Storing the reference count in the cluster was also considered, but because the external storage may not be a cluster this isn't an option. The size of the pool of reference counters is available in the stats provided by "netstat -m". PR: 19866 Submitted by: Bosko Milekic <bmilekic@dsuper.net> Reviewed by: alfred (glanced at by others on -net)
2000-08-19 08:32:59 +00:00
printf("%lu/%lu m_ext reference counters (in use/allocated)\n",
mbstat.m_refcnt - mbstat.m_refree, mbstat.m_refcnt);
totmem = mbstat.m_mbufs * MSIZE + mbstat.m_clusters * MCLBYTES +
mbstat.m_refcnt * sizeof(union mext_refcnt);
totpossible = nmbclusters * MCLBYTES + nmbufs * MSIZE +
nmbcnt * sizeof(union mext_refcnt);
printf("%lu Kbytes allocated to network (%lu%% of mb_map in use)\n",
totmem / 1024, (totmem * 100) / totpossible);
printf("%lu requests for memory denied\n", mbstat.m_drops);
printf("%lu requests for memory delayed\n", mbstat.m_wait);
printf("%lu calls to protocol drain routines\n", mbstat.m_drain);
err:
if (mbtypes != NULL)
free(mbtypes);
if (seen != NULL)
free(seen);
1994-05-27 12:33:43 +00:00
}