1*66dfcc85SDavid van Moolenbroek /* $NetBSD: mbuf.c,v 1.33 2015/07/28 19:46:42 christos Exp $ */
2*66dfcc85SDavid van Moolenbroek
3*66dfcc85SDavid van Moolenbroek /*
4*66dfcc85SDavid van Moolenbroek * Copyright (c) 1983, 1988, 1993
5*66dfcc85SDavid van Moolenbroek * The Regents of the University of California. All rights reserved.
6*66dfcc85SDavid van Moolenbroek *
7*66dfcc85SDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
8*66dfcc85SDavid van Moolenbroek * modification, are permitted provided that the following conditions
9*66dfcc85SDavid van Moolenbroek * are met:
10*66dfcc85SDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
11*66dfcc85SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer.
12*66dfcc85SDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright
13*66dfcc85SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer in the
14*66dfcc85SDavid van Moolenbroek * documentation and/or other materials provided with the distribution.
15*66dfcc85SDavid van Moolenbroek * 3. Neither the name of the University nor the names of its contributors
16*66dfcc85SDavid van Moolenbroek * may be used to endorse or promote products derived from this software
17*66dfcc85SDavid van Moolenbroek * without specific prior written permission.
18*66dfcc85SDavid van Moolenbroek *
19*66dfcc85SDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20*66dfcc85SDavid van Moolenbroek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*66dfcc85SDavid van Moolenbroek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*66dfcc85SDavid van Moolenbroek * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23*66dfcc85SDavid van Moolenbroek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24*66dfcc85SDavid van Moolenbroek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25*66dfcc85SDavid van Moolenbroek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26*66dfcc85SDavid van Moolenbroek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27*66dfcc85SDavid van Moolenbroek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28*66dfcc85SDavid van Moolenbroek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29*66dfcc85SDavid van Moolenbroek * SUCH DAMAGE.
30*66dfcc85SDavid van Moolenbroek */
31*66dfcc85SDavid van Moolenbroek
32*66dfcc85SDavid van Moolenbroek #include <sys/cdefs.h>
33*66dfcc85SDavid van Moolenbroek #ifndef lint
34*66dfcc85SDavid van Moolenbroek #if 0
35*66dfcc85SDavid van Moolenbroek static char sccsid[] = "from: @(#)mbuf.c 8.1 (Berkeley) 6/6/93";
36*66dfcc85SDavid van Moolenbroek #else
37*66dfcc85SDavid van Moolenbroek __RCSID("$NetBSD: mbuf.c,v 1.33 2015/07/28 19:46:42 christos Exp $");
38*66dfcc85SDavid van Moolenbroek #endif
39*66dfcc85SDavid van Moolenbroek #endif /* not lint */
40*66dfcc85SDavid van Moolenbroek
41*66dfcc85SDavid van Moolenbroek #define __POOL_EXPOSE
42*66dfcc85SDavid van Moolenbroek
43*66dfcc85SDavid van Moolenbroek #include <sys/param.h>
44*66dfcc85SDavid van Moolenbroek #include <sys/protosw.h>
45*66dfcc85SDavid van Moolenbroek #include <sys/socket.h>
46*66dfcc85SDavid van Moolenbroek #include <sys/mbuf.h>
47*66dfcc85SDavid van Moolenbroek #include <sys/pool.h>
48*66dfcc85SDavid van Moolenbroek #include <sys/sysctl.h>
49*66dfcc85SDavid van Moolenbroek
50*66dfcc85SDavid van Moolenbroek #include <stdio.h>
51*66dfcc85SDavid van Moolenbroek #include <kvm.h>
52*66dfcc85SDavid van Moolenbroek #include <stdlib.h>
53*66dfcc85SDavid van Moolenbroek #include <limits.h>
54*66dfcc85SDavid van Moolenbroek #include <errno.h>
55*66dfcc85SDavid van Moolenbroek #include <err.h>
56*66dfcc85SDavid van Moolenbroek #include "netstat.h"
57*66dfcc85SDavid van Moolenbroek #include "prog_ops.h"
58*66dfcc85SDavid van Moolenbroek
59*66dfcc85SDavid van Moolenbroek #define YES 1
60*66dfcc85SDavid van Moolenbroek
61*66dfcc85SDavid van Moolenbroek struct mbstat mbstat;
62*66dfcc85SDavid van Moolenbroek struct pool mbpool, mclpool;
63*66dfcc85SDavid van Moolenbroek struct pool_allocator mbpa, mclpa;
64*66dfcc85SDavid van Moolenbroek
65*66dfcc85SDavid van Moolenbroek static struct mbtypes {
66*66dfcc85SDavid van Moolenbroek int mt_type;
67*66dfcc85SDavid van Moolenbroek const char *mt_name;
68*66dfcc85SDavid van Moolenbroek } mbtypes[] = {
69*66dfcc85SDavid van Moolenbroek { MT_DATA, "data" },
70*66dfcc85SDavid van Moolenbroek { MT_OOBDATA, "oob data" },
71*66dfcc85SDavid van Moolenbroek { MT_CONTROL, "ancillary data" },
72*66dfcc85SDavid van Moolenbroek { MT_HEADER, "packet headers" },
73*66dfcc85SDavid van Moolenbroek { MT_FTABLE, "fragment reassembly queue headers" }, /* XXX */
74*66dfcc85SDavid van Moolenbroek { MT_SONAME, "socket names and addresses" },
75*66dfcc85SDavid van Moolenbroek { MT_SOOPTS, "socket options" },
76*66dfcc85SDavid van Moolenbroek { 0, 0 }
77*66dfcc85SDavid van Moolenbroek };
78*66dfcc85SDavid van Moolenbroek
79*66dfcc85SDavid van Moolenbroek const int nmbtypes = sizeof(mbstat.m_mtypes) / sizeof(short);
80*66dfcc85SDavid van Moolenbroek bool seen[256]; /* "have we seen this type yet?" */
81*66dfcc85SDavid van Moolenbroek
82*66dfcc85SDavid van Moolenbroek int mbstats_ctl[] = { CTL_KERN, KERN_MBUF, MBUF_STATS };
83*66dfcc85SDavid van Moolenbroek int mowners_ctl[] = { CTL_KERN, KERN_MBUF, MBUF_MOWNERS };
84*66dfcc85SDavid van Moolenbroek
85*66dfcc85SDavid van Moolenbroek /*
86*66dfcc85SDavid van Moolenbroek * Print mbuf statistics.
87*66dfcc85SDavid van Moolenbroek */
88*66dfcc85SDavid van Moolenbroek void
mbpr(u_long mbaddr,u_long msizeaddr,u_long mclbaddr,u_long mbpooladdr,u_long mclpooladdr)89*66dfcc85SDavid van Moolenbroek mbpr(u_long mbaddr, u_long msizeaddr, u_long mclbaddr, u_long mbpooladdr,
90*66dfcc85SDavid van Moolenbroek u_long mclpooladdr)
91*66dfcc85SDavid van Moolenbroek {
92*66dfcc85SDavid van Moolenbroek u_long totmem, totused, totpct;
93*66dfcc85SDavid van Moolenbroek u_int totmbufs;
94*66dfcc85SDavid van Moolenbroek int i, lines;
95*66dfcc85SDavid van Moolenbroek struct mbtypes *mp;
96*66dfcc85SDavid van Moolenbroek size_t len;
97*66dfcc85SDavid van Moolenbroek void *data;
98*66dfcc85SDavid van Moolenbroek struct mowner_user *mo;
99*66dfcc85SDavid van Moolenbroek int mclbytes, msize;
100*66dfcc85SDavid van Moolenbroek
101*66dfcc85SDavid van Moolenbroek if (nmbtypes != 256) {
102*66dfcc85SDavid van Moolenbroek fprintf(stderr,
103*66dfcc85SDavid van Moolenbroek "%s: unexpected change to mbstat; check source\n",
104*66dfcc85SDavid van Moolenbroek getprogname());
105*66dfcc85SDavid van Moolenbroek return;
106*66dfcc85SDavid van Moolenbroek }
107*66dfcc85SDavid van Moolenbroek
108*66dfcc85SDavid van Moolenbroek if (use_sysctl) {
109*66dfcc85SDavid van Moolenbroek size_t mbstatlen = sizeof(mbstat);
110*66dfcc85SDavid van Moolenbroek if (prog_sysctl(mbstats_ctl,
111*66dfcc85SDavid van Moolenbroek sizeof(mbstats_ctl) / sizeof(mbstats_ctl[0]),
112*66dfcc85SDavid van Moolenbroek &mbstat, &mbstatlen, NULL, 0) < 0) {
113*66dfcc85SDavid van Moolenbroek warn("mbstat: sysctl failed");
114*66dfcc85SDavid van Moolenbroek return;
115*66dfcc85SDavid van Moolenbroek }
116*66dfcc85SDavid van Moolenbroek goto printit;
117*66dfcc85SDavid van Moolenbroek }
118*66dfcc85SDavid van Moolenbroek
119*66dfcc85SDavid van Moolenbroek if (mbaddr == 0) {
120*66dfcc85SDavid van Moolenbroek fprintf(stderr, "%s: mbstat: symbol not in namelist\n",
121*66dfcc85SDavid van Moolenbroek getprogname());
122*66dfcc85SDavid van Moolenbroek return;
123*66dfcc85SDavid van Moolenbroek }
124*66dfcc85SDavid van Moolenbroek /*XXX*/
125*66dfcc85SDavid van Moolenbroek if (msizeaddr != 0)
126*66dfcc85SDavid van Moolenbroek kread(msizeaddr, (char *)&msize, sizeof (msize));
127*66dfcc85SDavid van Moolenbroek else
128*66dfcc85SDavid van Moolenbroek msize = MSIZE;
129*66dfcc85SDavid van Moolenbroek if (mclbaddr != 0)
130*66dfcc85SDavid van Moolenbroek kread(mclbaddr, (char *)&mclbytes, sizeof (mclbytes));
131*66dfcc85SDavid van Moolenbroek else
132*66dfcc85SDavid van Moolenbroek mclbytes = MCLBYTES;
133*66dfcc85SDavid van Moolenbroek /*XXX*/
134*66dfcc85SDavid van Moolenbroek
135*66dfcc85SDavid van Moolenbroek if (kread(mbaddr, (char *)&mbstat, sizeof (mbstat)))
136*66dfcc85SDavid van Moolenbroek return;
137*66dfcc85SDavid van Moolenbroek
138*66dfcc85SDavid van Moolenbroek if (kread(mbpooladdr, (char *)&mbpool, sizeof (mbpool)))
139*66dfcc85SDavid van Moolenbroek return;
140*66dfcc85SDavid van Moolenbroek
141*66dfcc85SDavid van Moolenbroek if (kread(mclpooladdr, (char *)&mclpool, sizeof (mclpool)))
142*66dfcc85SDavid van Moolenbroek return;
143*66dfcc85SDavid van Moolenbroek
144*66dfcc85SDavid van Moolenbroek mbpooladdr = (u_long) mbpool.pr_alloc;
145*66dfcc85SDavid van Moolenbroek mclpooladdr = (u_long) mclpool.pr_alloc;
146*66dfcc85SDavid van Moolenbroek
147*66dfcc85SDavid van Moolenbroek if (kread(mbpooladdr, (char *)&mbpa, sizeof (mbpa)))
148*66dfcc85SDavid van Moolenbroek return;
149*66dfcc85SDavid van Moolenbroek
150*66dfcc85SDavid van Moolenbroek if (kread(mclpooladdr, (char *)&mclpa, sizeof (mclpa)))
151*66dfcc85SDavid van Moolenbroek return;
152*66dfcc85SDavid van Moolenbroek
153*66dfcc85SDavid van Moolenbroek printit:
154*66dfcc85SDavid van Moolenbroek totmbufs = 0;
155*66dfcc85SDavid van Moolenbroek for (mp = mbtypes; mp->mt_name; mp++)
156*66dfcc85SDavid van Moolenbroek totmbufs += mbstat.m_mtypes[mp->mt_type];
157*66dfcc85SDavid van Moolenbroek printf("%u mbufs in use:\n", totmbufs);
158*66dfcc85SDavid van Moolenbroek for (mp = mbtypes; mp->mt_name; mp++)
159*66dfcc85SDavid van Moolenbroek if (mbstat.m_mtypes[mp->mt_type]) {
160*66dfcc85SDavid van Moolenbroek seen[mp->mt_type] = YES;
161*66dfcc85SDavid van Moolenbroek printf("\t%u mbufs allocated to %s\n",
162*66dfcc85SDavid van Moolenbroek mbstat.m_mtypes[mp->mt_type], mp->mt_name);
163*66dfcc85SDavid van Moolenbroek }
164*66dfcc85SDavid van Moolenbroek seen[MT_FREE] = YES;
165*66dfcc85SDavid van Moolenbroek for (i = 0; i < nmbtypes; i++)
166*66dfcc85SDavid van Moolenbroek if (!seen[i] && mbstat.m_mtypes[i]) {
167*66dfcc85SDavid van Moolenbroek printf("\t%u mbufs allocated to <mbuf type %d>\n",
168*66dfcc85SDavid van Moolenbroek mbstat.m_mtypes[i], i);
169*66dfcc85SDavid van Moolenbroek }
170*66dfcc85SDavid van Moolenbroek
171*66dfcc85SDavid van Moolenbroek if (use_sysctl) /* XXX */
172*66dfcc85SDavid van Moolenbroek goto dump_drain;
173*66dfcc85SDavid van Moolenbroek
174*66dfcc85SDavid van Moolenbroek printf("%lu/%lu mapped pages in use\n",
175*66dfcc85SDavid van Moolenbroek (u_long)(mclpool.pr_nget - mclpool.pr_nput),
176*66dfcc85SDavid van Moolenbroek ((u_long)mclpool.pr_npages * mclpool.pr_itemsperpage));
177*66dfcc85SDavid van Moolenbroek totmem = (mbpool.pr_npages << mbpa.pa_pageshift) +
178*66dfcc85SDavid van Moolenbroek (mclpool.pr_npages << mclpa.pa_pageshift);
179*66dfcc85SDavid van Moolenbroek totused = (mbpool.pr_nget - mbpool.pr_nput) * mbpool.pr_size +
180*66dfcc85SDavid van Moolenbroek (mclpool.pr_nget - mclpool.pr_nput) * mclpool.pr_size;
181*66dfcc85SDavid van Moolenbroek if (totmem == 0)
182*66dfcc85SDavid van Moolenbroek totpct = 0;
183*66dfcc85SDavid van Moolenbroek else if (totused < (ULONG_MAX/100))
184*66dfcc85SDavid van Moolenbroek totpct = (totused * 100)/totmem;
185*66dfcc85SDavid van Moolenbroek else {
186*66dfcc85SDavid van Moolenbroek u_long totmem1 = totmem/100;
187*66dfcc85SDavid van Moolenbroek u_long totused1 = totused/100;
188*66dfcc85SDavid van Moolenbroek totpct = (totused1 * 100)/totmem1;
189*66dfcc85SDavid van Moolenbroek }
190*66dfcc85SDavid van Moolenbroek
191*66dfcc85SDavid van Moolenbroek printf("%lu Kbytes allocated to network (%lu%% in use)\n",
192*66dfcc85SDavid van Moolenbroek totmem / 1024, totpct);
193*66dfcc85SDavid van Moolenbroek
194*66dfcc85SDavid van Moolenbroek dump_drain:
195*66dfcc85SDavid van Moolenbroek printf("%lu calls to protocol drain routines\n", mbstat.m_drain);
196*66dfcc85SDavid van Moolenbroek
197*66dfcc85SDavid van Moolenbroek if (sflag < 2)
198*66dfcc85SDavid van Moolenbroek return;
199*66dfcc85SDavid van Moolenbroek
200*66dfcc85SDavid van Moolenbroek if (!use_sysctl)
201*66dfcc85SDavid van Moolenbroek return;
202*66dfcc85SDavid van Moolenbroek
203*66dfcc85SDavid van Moolenbroek if (prog_sysctl(mowners_ctl,
204*66dfcc85SDavid van Moolenbroek sizeof(mowners_ctl)/sizeof(mowners_ctl[0]),
205*66dfcc85SDavid van Moolenbroek NULL, &len, NULL, 0) < 0) {
206*66dfcc85SDavid van Moolenbroek if (errno == ENOENT)
207*66dfcc85SDavid van Moolenbroek return;
208*66dfcc85SDavid van Moolenbroek warn("mowners: sysctl test");
209*66dfcc85SDavid van Moolenbroek return;
210*66dfcc85SDavid van Moolenbroek }
211*66dfcc85SDavid van Moolenbroek len += 10 * sizeof(*mo); /* add some slop */
212*66dfcc85SDavid van Moolenbroek data = malloc(len);
213*66dfcc85SDavid van Moolenbroek if (data == NULL) {
214*66dfcc85SDavid van Moolenbroek warn("malloc(%lu)", (u_long)len);
215*66dfcc85SDavid van Moolenbroek return;
216*66dfcc85SDavid van Moolenbroek }
217*66dfcc85SDavid van Moolenbroek
218*66dfcc85SDavid van Moolenbroek if (prog_sysctl(mowners_ctl,
219*66dfcc85SDavid van Moolenbroek sizeof(mowners_ctl)/sizeof(mowners_ctl[0]),
220*66dfcc85SDavid van Moolenbroek data, &len, NULL, 0) < 0) {
221*66dfcc85SDavid van Moolenbroek warn("mowners: sysctl get");
222*66dfcc85SDavid van Moolenbroek free(data);
223*66dfcc85SDavid van Moolenbroek return;
224*66dfcc85SDavid van Moolenbroek }
225*66dfcc85SDavid van Moolenbroek
226*66dfcc85SDavid van Moolenbroek for (mo = (void *) data, lines = 0; len >= sizeof(*mo);
227*66dfcc85SDavid van Moolenbroek len -= sizeof(*mo), mo++) {
228*66dfcc85SDavid van Moolenbroek char buf[32];
229*66dfcc85SDavid van Moolenbroek if (vflag == 1 &&
230*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_CLAIMS] == 0 &&
231*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_EXT_CLAIMS] == 0 &&
232*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_CLUSTER_CLAIMS] == 0)
233*66dfcc85SDavid van Moolenbroek continue;
234*66dfcc85SDavid van Moolenbroek if (vflag == 0 &&
235*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_CLAIMS] ==
236*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_RELEASES] &&
237*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_EXT_CLAIMS] ==
238*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_EXT_RELEASES] &&
239*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_CLUSTER_CLAIMS] ==
240*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_CLUSTER_RELEASES])
241*66dfcc85SDavid van Moolenbroek continue;
242*66dfcc85SDavid van Moolenbroek snprintf(buf, sizeof(buf), "%16s %-13s",
243*66dfcc85SDavid van Moolenbroek mo->mo_name, mo->mo_descr);
244*66dfcc85SDavid van Moolenbroek if ((lines % 24) == 0 || lines > 24) {
245*66dfcc85SDavid van Moolenbroek printf("%30s %-8s %10s %10s %10s\n",
246*66dfcc85SDavid van Moolenbroek "", "", "small", "ext", "cluster");
247*66dfcc85SDavid van Moolenbroek lines = 1;
248*66dfcc85SDavid van Moolenbroek }
249*66dfcc85SDavid van Moolenbroek printf("%30s %-8s %10lu %10lu %10lu\n",
250*66dfcc85SDavid van Moolenbroek buf, "inuse",
251*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_CLAIMS] -
252*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_RELEASES],
253*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_EXT_CLAIMS] -
254*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_EXT_RELEASES],
255*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_CLUSTER_CLAIMS] -
256*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_CLUSTER_RELEASES]);
257*66dfcc85SDavid van Moolenbroek lines++;
258*66dfcc85SDavid van Moolenbroek if (vflag) {
259*66dfcc85SDavid van Moolenbroek printf("%30s %-8s %10lu %10lu %10lu\n",
260*66dfcc85SDavid van Moolenbroek "", "claims",
261*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_CLAIMS],
262*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_EXT_CLAIMS],
263*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_CLUSTER_CLAIMS]);
264*66dfcc85SDavid van Moolenbroek printf("%30s %-8s %10lu %10lu %10lu\n",
265*66dfcc85SDavid van Moolenbroek "", "releases",
266*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_RELEASES],
267*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_EXT_RELEASES],
268*66dfcc85SDavid van Moolenbroek mo->mo_counter[MOWNER_COUNTER_CLUSTER_RELEASES]);
269*66dfcc85SDavid van Moolenbroek lines += 2;
270*66dfcc85SDavid van Moolenbroek }
271*66dfcc85SDavid van Moolenbroek }
272*66dfcc85SDavid van Moolenbroek free(data);
273*66dfcc85SDavid van Moolenbroek }
274