From iedowse@maths.tcd.ie  Sun Jul  9 13:31:31 2000
Return-Path: <iedowse@maths.tcd.ie>
Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11])
	by hub.freebsd.org (Postfix) with SMTP id AF3CB37BE8A
	for <FreeBSD-gnats-submit@freebsd.org>; Sun,  9 Jul 2000 13:31:29 -0700 (PDT)
	(envelope-from iedowse@maths.tcd.ie)
Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP
          id <aa03594@salmon>; 9 Jul 2000 21:31:28 +0100 (BST)
Message-Id: <200007092131.aa41223@walton.maths.tcd.ie>
Date: Sun, 9 Jul 2000 21:31:26 +0100 (BST)
From: iedowse@maths.tcd.ie
Sender: iedowse@maths.tcd.ie
Reply-To: iedowse@maths.tcd.ie
To: FreeBSD-gnats-submit@freebsd.org
Cc: iedowse@maths.tcd.ie, bmilekic@dsuper.net
Subject: Make mbstat.m_mtypes[] u_long instead of u_short
X-Send-Pr-Version: 3.2

>Number:         19809
>Category:       kern
>Synopsis:       Make mbstat.m_mtypes[] u_long instead of u_short
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    dwmalone
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jul 09 13:40:01 PDT 2000
>Closed-Date:    Fri Jul 14 23:46:49 PDT 2000
>Last-Modified:  Fri Jul 14 23:47:22 PDT 2000
>Originator:     Ian Dowse
>Release:        FreeBSD 4.0-STABLE i386
>Organization:
		School of Mathematics
		Trinity College Dublin
>Environment:
	
	All versions of FreeBSD 

>Description:

	The mbstat.m_mtypes[] array, which is used to store mbuf type
	statistics, is declared with type u_short. For most people
	this is large enough, but large systems with more than 64k
	mbufs configured are becoming quite common now.

	On these systems, overflows can occur, causing meaningless
	values to appear int the output of "netstat -m".

	A related problem, which looks like it has always existed in
	FreeBSD, is that the m_mtypes[MT_FREE] counter is not incremented
	when new mbufs are allocated, so it does not reflect the number
	of free mbufs. 

>How-To-Repeat:

	Configure a system with more than 64k mbufs, and notice that
	the 'XX mbufs allocated to data' output from netstat wraps
	around at 64k.

	The m_mtypes[MT_FREE] bug can be observed by typing

		print mbstat.m_mtypes[0]

	from a kgdb session; the number printed will generally be around
	65500 on a quiet system with only a few mbufs allocated.

>Fix:

	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.

	The patch also reduces the size of the m_mtypes[] array from
	256 to 32. Currently there are only 16 mbuf types defined, and
	the definitions of 9 of these are #if 0'd out, so we are unlikely
	to reach 32 types anytime soon. This reduces the kernel bss size
	by a few hundred bytes.


Index: sys/kern/uipc_mbuf.c
===================================================================
RCS file: /home/iedowse/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/09 17:54:30
@@ -184,6 +184,7 @@
 		p += MSIZE;
 	}
 	mbstat.m_mbufs += nmb;
+	mbstat.m_mtypes[MT_FREE] += nmb;
 	return (1);
 }
 
Index: sys/sys/mbuf.h
===================================================================
RCS file: /home/iedowse/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/09 17:55:26
@@ -191,7 +191,7 @@
 	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_mtypes[32];	/* 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 */
Index: usr.bin/netstat/mbuf.c
===================================================================
RCS file: /home/iedowse/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/09 20:26:37
@@ -91,8 +91,8 @@
 	{ 0, 0 }
 };
 
-int nmbtypes = sizeof(mbstat.m_mtypes) / sizeof(short);
-bool seen[256];			/* "have we seen this type yet?" */
+#define NMBTYPES (sizeof(mbstat.m_mtypes) / sizeof(mbstat.m_mtypes[0]))
+bool seen[NMBTYPES];		/* "have we seen this type yet?" */
 
 /*
  * Print mbuf statistics.
@@ -133,11 +133,6 @@
 #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];
@@ -146,13 +141,13 @@
 	for (mp = mbtypes; mp->mt_name; mp++)
 		if (mbstat.m_mtypes[mp->mt_type]) {
 			seen[mp->mt_type] = YES;
-			printf("\t%u mbufs allocated to %s\n",
+			printf("\t%lu mbufs allocated to %s\n",
 			    mbstat.m_mtypes[mp->mt_type], mp->mt_name);
 		}
 	seen[MT_FREE] = YES;
-	for (i = 0; i < nmbtypes; i++)
+	for (i = 0; i < NMBTYPES; i++)
 		if (!seen[i] && mbstat.m_mtypes[i]) {
-			printf("\t%u mbufs allocated to <mbuf type %d>\n",
+			printf("\t%lu mbufs allocated to <mbuf type %d>\n",
 			    mbstat.m_mtypes[i], i);
 		}
 	printf("%lu/%lu/%u mbuf clusters in use (current/peak/max)\n",

>Release-Note:
>Audit-Trail:

From: Garrett Wollman <wollman@khavrinen.lcs.mit.edu>
To: iedowse@maths.tcd.ie
Cc: FreeBSD-gnats-submit@FreeBSD.ORG, bmilekic@dsuper.net
Subject: kern/19809: Make mbstat.m_mtypes[] u_long instead of u_short
Date: Mon, 10 Jul 2000 12:56:10 -0400 (EDT)

 <<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 
Responsible-Changed-By: sheldonh 
Responsible-Changed-When: Tue Jul 11 01:46:01 PDT 2000 
Responsible-Changed-Why:  
Haha!  Assigned to a committer near you. :-) 

http://www.freebsd.org/cgi/query-pr.cgi?pr=19809 

From: Ian Dowse <iedowse@maths.tcd.ie>
To: FreeBSD-gnats-submit@FreeBSD.ORG
Cc: iedowse@maths.tcd.ie,
	Garrett Wollman <wollman@khavrinen.lcs.mit.edu>, bmilekic@dsuper.net
Subject: kern/19809: Make mbstat.m_mtypes[] u_long instead of u_short
Date: Tue, 11 Jul 2000 22:12:51 +0100

 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);
  }
 

From: Bosko Milekic <bmilekic@dsuper.net>
To: Ian Dowse <iedowse@maths.tcd.ie>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG,
	Garrett Wollman <wollman@khavrinen.lcs.mit.edu>
Subject: Re: kern/19809: Make mbstat.m_mtypes[] u_long instead of u_short
Date: Tue, 11 Jul 2000 18:46:21 -0400 (EDT)

   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 
State-Changed-By: alfred 
State-Changed-When: Fri Jul 14 23:46:49 PDT 2000 
State-Changed-Why:  
Patches applied, thank you Ian! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=19809 
>Unformatted:
