| Summary: | Make mbstat.m_mtypes[] u_long instead of u_short | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | iedowse <iedowse> | ||||
| Component: | kern | Assignee: | dwmalone | ||||
| Status: | Closed FIXED | ||||||
| Severity: | Affects Only Me | CC: | iedowse | ||||
| Priority: | Normal | ||||||
| Version: | 4.0-STABLE | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
|
Description
iedowse
2000-07-09 21:40:01 UTC
<<On Sun, 9 Jul 2000 21:31:26 +0100 (BST), iedowse@maths.tcd.ie said: > Apply the following patch. This fixes both of the above > issues, and removes some assumptions within netstat(1) about > the size of the m_mtypes[] array. Looks good to me. I'd rather have the counts exported as a separate MIB entry, though, which would avoid any dependency by netstat on the actual number of types supported in the kernel. -GAWollman Responsible Changed From-To: freebsd-bugs->dwmalone Haha! Assigned to a committer near you. :-) Garrett suggested that the m_mtypes[] array should be be available
as a separate MIB. This allows userland utilities (currently just
netstat) to function correctly without recompilation if its length
changes.
The included patch moves the mbstat.m_mtypes[] array out of struct
mbstat, and makes it available via sysctl(3) as 'kern.ipc.mbtypes'.
It also changes netstat(1) to use this interface.
Since the size of mbtypes[] is now more freely modifiable, this
patch defines it with only as many entries as are currently necessary
(16).
[Note that right now, 'sysctl -a' only displays the first entry in
the mbtypes[] array. sysctl(8) currently supports arrays of type
(u_)int, but not (u_)long. I'll submit a patch for that separately.]
Ian
Index: sys/kern/uipc_mbuf.c
===================================================================
RCS file: /FreeBSD/FreeBSD-CVS/src/sys/kern/uipc_mbuf.c,v
retrieving revision 1.52
diff -u -r1.52 uipc_mbuf.c
--- sys/kern/uipc_mbuf.c 2000/07/04 16:35:03 1.52
+++ sys/kern/uipc_mbuf.c 2000/07/11 20:38:21
@@ -58,6 +58,7 @@
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, 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 @@
p += MSIZE;
}
mbstat.m_mbufs += nmb;
+ mbtypes[MT_FREE] += nmb;
return (1);
}
Index: sys/sys/mbuf.h
===================================================================
RCS file: /FreeBSD/FreeBSD-CVS/src/sys/sys/mbuf.h,v
retrieving revision 1.51
diff -u -r1.51 mbuf.h
--- sys/sys/mbuf.h 2000/07/04 16:35:15 1.51
+++ sys/sys/mbuf.h 2000/07/11 17:54:03
@@ -180,6 +180,8 @@
#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 @@
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 @@
_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 @@
_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 @@
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 @@
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_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 */
Index: usr.bin/netstat/mbuf.c
===================================================================
RCS file: /FreeBSD/FreeBSD-CVS/src/usr.bin/netstat/mbuf.c,v
retrieving revision 1.17
diff -u -r1.17 mbuf.c
--- usr.bin/netstat/mbuf.c 1999/12/28 06:38:37 1.17
+++ usr.bin/netstat/mbuf.c 2000/07/11 19:39:16
@@ -47,6 +47,7 @@
#include <err.h>
#include <stdio.h>
+#include <stdlib.h>
#include "netstat.h"
#define YES 1
@@ -54,10 +55,10 @@
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 @@
{ 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 @@
{
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 @@
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 @@
#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 @@
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);
}
Somebody PLEASE commit this as soon as possible, and let me (or us) know. I need to roll some diffs covering this part of the tree as well, and the fact that this stuff is just sitting there is not helping consistency (it would reduce work if I merged them and then rolled the diffs after they are in the tree). Thanks in advance, --Bosko On Tue, 11 Jul 2000, Ian Dowse wrote: > > Garrett suggested that the m_mtypes[] array should be be available > as a separate MIB. This allows userland utilities (currently just > netstat) to function correctly without recompilation if its length > changes. > > The included patch moves the mbstat.m_mtypes[] array out of struct > mbstat, and makes it available via sysctl(3) as 'kern.ipc.mbtypes'. > It also changes netstat(1) to use this interface. > > Since the size of mbtypes[] is now more freely modifiable, this > patch defines it with only as many entries as are currently necessary > (16). > > [Note that right now, 'sysctl -a' only displays the first entry in > the mbtypes[] array. sysctl(8) currently supports arrays of type > (u_)int, but not (u_)long. I'll submit a patch for that separately.] > > Ian > > > Index: sys/kern/uipc_mbuf.c > =================================================================== > RCS file: /FreeBSD/FreeBSD-CVS/src/sys/kern/uipc_mbuf.c,v > retrieving revision 1.52 > diff -u -r1.52 uipc_mbuf.c > --- sys/kern/uipc_mbuf.c 2000/07/04 16:35:03 1.52 > +++ sys/kern/uipc_mbuf.c 2000/07/11 20:38:21 > @@ -58,6 +58,7 @@ > 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, 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 @@ > p += MSIZE; > } > mbstat.m_mbufs += nmb; > + mbtypes[MT_FREE] += nmb; > return (1); > } > > Index: sys/sys/mbuf.h > =================================================================== > RCS file: /FreeBSD/FreeBSD-CVS/src/sys/sys/mbuf.h,v > retrieving revision 1.51 > diff -u -r1.51 mbuf.h > --- sys/sys/mbuf.h 2000/07/04 16:35:15 1.51 > +++ sys/sys/mbuf.h 2000/07/11 17:54:03 > @@ -180,6 +180,8 @@ > #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 @@ > 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 @@ > _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 @@ > _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 @@ > 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 @@ > 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_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 */ > Index: usr.bin/netstat/mbuf.c > =================================================================== > RCS file: /FreeBSD/FreeBSD-CVS/src/usr.bin/netstat/mbuf.c,v > retrieving revision 1.17 > diff -u -r1.17 mbuf.c > --- usr.bin/netstat/mbuf.c 1999/12/28 06:38:37 1.17 > +++ usr.bin/netstat/mbuf.c 2000/07/11 19:39:16 > @@ -47,6 +47,7 @@ > > #include <err.h> > #include <stdio.h> > +#include <stdlib.h> > #include "netstat.h" > > #define YES 1 > @@ -54,10 +55,10 @@ > > 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 @@ > { 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 @@ > { > 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 @@ > 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 @@ > #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 @@ > 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); > } > > -- Bosko Milekic * Voice/Mobile: 514.865.7738 * Pager: 514.921.0237 bmilekic@technokratis.com * http://www.technokratis.com/ State Changed From-To: open->closed Patches applied, thank you Ian! |