From af0e6bcdf07c602bf2770f44779106e62078ec75 Mon Sep 17 00:00:00 2001 From: Alfred Perlstein Date: Sat, 15 Jul 2000 06:02:48 +0000 Subject: [PATCH] Make mbstat.m_mtypes seperate and viewable via sysctl, also expand the size from short to ulong Submitted by: Ian Dowse PR: kern/19809 --- sys/kern/uipc_mbuf.c | 4 +++ sys/sys/mbuf.h | 20 +++++++----- usr.bin/netstat/mbuf.c | 74 ++++++++++++++++++++++++++++-------------- 3 files changed, 64 insertions(+), 34 deletions(-) diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 763e0b4048b7..177113733dbd 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 98c87fa14e16..155e6818a25d 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 a761c2e270bd..6ad3fdbc293b 100644 --- a/usr.bin/netstat/mbuf.c +++ b/usr.bin/netstat/mbuf.c @@ -47,6 +47,7 @@ static const char rcsid[] = #include #include +#include #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 \n", - mbstat.m_mtypes[i], i); + if (!seen[i] && mbtypes[i]) { + printf("\t%lu mbufs allocated to \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); }