summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/uipc_mbuf.c4
-rw-r--r--sys/sys/mbuf.h20
-rw-r--r--usr.bin/netstat/mbuf.c74
3 files changed, 64 insertions, 34 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index 763e0b4..1771137 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -58,6 +58,7 @@ SYSINIT(mbuf, SI_SUB_MBUF, SI_ORDER_FIRST, mbinit, NULL)
struct mbuf *mbutl;
char *mclrefcnt;
struct mbstat mbstat;
+u_long mbtypes[MT_NTYPES];
struct mbuf *mmbfree;
union mcluster *mclfree;
int max_linkhdr;
@@ -80,6 +81,8 @@ SYSCTL_INT(_kern_ipc, KIPC_MAX_DATALEN, max_datalen, CTLFLAG_RW,
SYSCTL_INT(_kern_ipc, OID_AUTO, mbuf_wait, CTLFLAG_RW,
&mbuf_wait, 0, "");
SYSCTL_STRUCT(_kern_ipc, KIPC_MBSTAT, mbstat, CTLFLAG_RW, &mbstat, mbstat, "");
+SYSCTL_OPAQUE(_kern_ipc, OID_AUTO, mbtypes, CTLFLAG_RD, mbtypes,
+ sizeof(mbtypes), "LU", "");
SYSCTL_INT(_kern_ipc, KIPC_NMBCLUSTERS, nmbclusters, CTLFLAG_RD,
&nmbclusters, 0, "Maximum number of mbuf clusters available");
SYSCTL_INT(_kern_ipc, OID_AUTO, nmbufs, CTLFLAG_RD, &nmbufs, 0,
@@ -184,6 +187,7 @@ m_mballoc(nmb, how)
p += MSIZE;
}
mbstat.m_mbufs += nmb;
+ mbtypes[MT_FREE] += nmb;
return (1);
}
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index 98c87fa..155e681 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -180,6 +180,8 @@ struct mbuf {
#define MT_CONTROL 14 /* extra-data protocol message */
#define MT_OOBDATA 15 /* expedited data */
+#define MT_NTYPES 16 /* number of mbuf types for mbtypes[] */
+
/*
* mbuf statistics
*/
@@ -191,7 +193,6 @@ struct mbstat {
u_long m_drops; /* times failed to find space */
u_long m_wait; /* times waited for space */
u_long m_drain; /* times drained protocols for space */
- u_short m_mtypes[256]; /* type specific mbuf allocations */
u_long m_mcfail; /* times m_copym failed */
u_long m_mpfail; /* times m_pullup failed */
u_long m_msize; /* length of an mbuf */
@@ -284,9 +285,9 @@ union mcluster {
_mm = mmbfree; \
if (_mm != NULL) { \
mmbfree = _mm->m_next; \
- mbstat.m_mtypes[MT_FREE]--; \
+ mbtypes[MT_FREE]--; \
_mm->m_type = _mtype; \
- mbstat.m_mtypes[_mtype]++; \
+ mbtypes[_mtype]++; \
_mm->m_next = NULL; \
_mm->m_nextpkt = NULL; \
_mm->m_data = _mm->m_dat; \
@@ -314,9 +315,9 @@ union mcluster {
_mm = mmbfree; \
if (_mm != NULL) { \
mmbfree = _mm->m_next; \
- mbstat.m_mtypes[MT_FREE]--; \
+ mbtypes[MT_FREE]--; \
_mm->m_type = _mtype; \
- mbstat.m_mtypes[_mtype]++; \
+ mbtypes[_mtype]++; \
_mm->m_next = NULL; \
_mm->m_nextpkt = NULL; \
_mm->m_data = _mm->m_pktdat; \
@@ -419,12 +420,12 @@ union mcluster {
struct mbuf *_mm = (m); \
\
KASSERT(_mm->m_type != MT_FREE, ("freeing free mbuf")); \
- mbstat.m_mtypes[_mm->m_type]--; \
+ mbtypes[_mm->m_type]--; \
if (_mm->m_flags & M_EXT) \
MEXTFREE1(m); \
(n) = _mm->m_next; \
_mm->m_type = MT_FREE; \
- mbstat.m_mtypes[MT_FREE]++; \
+ mbtypes[MT_FREE]++; \
_mm->m_next = mmbfree; \
mmbfree = _mm; \
MMBWAKEUP(); \
@@ -508,8 +509,8 @@ union mcluster {
int _mt = (t); \
int _ms = splimp(); \
\
- mbstat.m_mtypes[_mm->m_type]--; \
- mbstat.m_mtypes[_mt]++; \
+ mbtypes[_mm->m_type]--; \
+ mbtypes[_mt]++; \
splx(_ms); \
_mm->m_type = (_mt); \
} while (0)
@@ -536,6 +537,7 @@ extern int max_protohdr; /* largest protocol header */
extern int max_hdr; /* largest link+protocol header */
extern int max_datalen; /* MHLEN - max_hdr */
extern struct mbstat mbstat;
+extern u_long mbtypes[MT_NTYPES]; /* per-type mbuf allocations */
extern int mbuf_wait; /* mbuf sleep time */
extern struct mbuf *mbutl; /* virtual address of mclusters */
extern char *mclrefcnt; /* cluster reference counts */
diff --git a/usr.bin/netstat/mbuf.c b/usr.bin/netstat/mbuf.c
index a761c2e..6ad3fdb 100644
--- a/usr.bin/netstat/mbuf.c
+++ b/usr.bin/netstat/mbuf.c
@@ -47,6 +47,7 @@ static const char rcsid[] =
#include <err.h>
#include <stdio.h>
+#include <stdlib.h>
#include "netstat.h"
#define YES 1
@@ -54,10 +55,10 @@ typedef int bool;
struct mbstat mbstat;
-static struct mbtypes {
+static struct mbtypenames {
int mt_type;
char *mt_name;
-} mbtypes[] = {
+} mbtypenames[] = {
{ MT_DATA, "data" },
{ MT_OOBDATA, "oob data" },
{ MT_CONTROL, "ancillary data" },
@@ -91,9 +92,6 @@ static struct mbtypes {
{ 0, 0 }
};
-int nmbtypes = sizeof(mbstat.m_mtypes) / sizeof(short);
-bool seen[256]; /* "have we seen this type yet?" */
-
/*
* Print mbuf statistics.
*/
@@ -102,9 +100,14 @@ mbpr()
{
register int totmem, totfree, totmbufs;
register int i;
- register struct mbtypes *mp;
- int name[3], nmbclusters, nmbufs;
- size_t nmbclen, nmbuflen, mbstatlen;
+ struct mbtypenames *mp;
+ int name[3], nmbclusters, nmbufs, nmbtypes;
+ size_t nmbclen, nmbuflen, mbstatlen, mbtypeslen;
+ u_long *mbtypes;
+ bool *seen; /* "have we seen this type yet?" */
+
+ mbtypes = NULL;
+ seen = NULL;
name[0] = CTL_KERN;
name[1] = KERN_IPC;
@@ -112,20 +115,40 @@ mbpr()
mbstatlen = sizeof mbstat;
if (sysctl(name, 3, &mbstat, &mbstatlen, 0, 0) < 0) {
warn("sysctl: retrieving mbstat");
- return;
+ goto err;
+ }
+
+ 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;
+ }
+ if (sysctlbyname("kern.ipc.mbtypes", mbtypes, &mbtypeslen, NULL,
+ 0) < 0) {
+ warn("sysctl: retrieving mbtypes");
+ goto err;
}
+ nmbtypes = mbtypeslen / sizeof(*mbtypes);
+ if ((seen = calloc(nmbtypes, sizeof(*seen))) == NULL) {
+ warn("calloc");
+ goto err;
+ }
+
name[2] = KIPC_NMBCLUSTERS;
nmbclen = sizeof(int);
if (sysctl(name, 3, &nmbclusters, &nmbclen, 0, 0) < 0) {
warn("sysctl: retrieving nmbclusters");
- return;
+ goto err;
}
nmbuflen = sizeof(int);
if (sysctlbyname("kern.ipc.nmbufs", &nmbufs, &nmbuflen, 0, 0) < 0) {
warn("sysctl: retrieving nmbufs");
- return;
+ goto err;
}
#undef MSIZE
@@ -133,27 +156,22 @@ mbpr()
#undef MCLBYTES
#define MCLBYTES (mbstat.m_mclbytes)
- if (nmbtypes != 256) {
- warnx("unexpected change to mbstat; check source");
- return;
- }
-
totmbufs = 0;
- for (mp = mbtypes; mp->mt_name; mp++)
- totmbufs += mbstat.m_mtypes[mp->mt_type];
+ for (mp = mbtypenames; mp->mt_name; mp++)
+ totmbufs += mbtypes[mp->mt_type];
printf("%u/%lu/%u mbufs in use (current/peak/max):\n", totmbufs,
mbstat.m_mbufs, nmbufs);
- for (mp = mbtypes; mp->mt_name; mp++)
- if (mbstat.m_mtypes[mp->mt_type]) {
+ for (mp = mbtypenames; mp->mt_name; mp++)
+ if (mbtypes[mp->mt_type]) {
seen[mp->mt_type] = YES;
- printf("\t%u mbufs allocated to %s\n",
- mbstat.m_mtypes[mp->mt_type], mp->mt_name);
+ printf("\t%lu mbufs allocated to %s\n",
+ mbtypes[mp->mt_type], mp->mt_name);
}
seen[MT_FREE] = YES;
for (i = 0; i < nmbtypes; i++)
- if (!seen[i] && mbstat.m_mtypes[i]) {
- printf("\t%u mbufs allocated to <mbuf type %d>\n",
- mbstat.m_mtypes[i], i);
+ if (!seen[i] && mbtypes[i]) {
+ printf("\t%lu mbufs allocated to <mbuf type %d>\n",
+ mbtypes[i], i);
}
printf("%lu/%lu/%u mbuf clusters in use (current/peak/max)\n",
mbstat.m_clusters - mbstat.m_clfree, mbstat.m_clusters,
@@ -166,4 +184,10 @@ mbpr()
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);
}
OpenPOWER on IntegriCloud