Commit | Line | Data |
---|---|---|
984263bc MD |
1 | /* |
2 | * Copyright (c) 1983, 1988, 1993 | |
3 | * The Regents of the University of California. All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | |
dc71b7ab | 13 | * 3. Neither the name of the University nor the names of its contributors |
984263bc MD |
14 | * may be used to endorse or promote products derived from this software |
15 | * without specific prior written permission. | |
16 | * | |
17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
27 | * SUCH DAMAGE. | |
1de703da MD |
28 | * |
29 | * @(#)mbuf.c 8.1 (Berkeley) 6/6/93 | |
30 | * $FreeBSD: src/usr.bin/netstat/mbuf.c,v 1.17.2.3 2001/08/10 09:07:09 ru Exp $ | |
984263bc MD |
31 | */ |
32 | ||
03d6a592 | 33 | #define _KERNEL_STRUCTURES |
984263bc MD |
34 | #include <sys/param.h> |
35 | #include <sys/mbuf.h> | |
36 | #include <sys/protosw.h> | |
37 | #include <sys/socket.h> | |
38 | #include <sys/sysctl.h> | |
39 | ||
40 | #include <err.h> | |
0ee0daf9 | 41 | #include <stdbool.h> |
984263bc MD |
42 | #include <stdio.h> |
43 | #include <stdlib.h> | |
44 | #include "netstat.h" | |
45 | ||
0ee0daf9 | 46 | #define YES true |
984263bc MD |
47 | |
48 | static struct mbtypenames { | |
49 | int mt_type; | |
b82e1528 | 50 | const char *mt_name; |
984263bc MD |
51 | } mbtypenames[] = { |
52 | { MT_DATA, "data" }, | |
53 | { MT_OOBDATA, "oob data" }, | |
54 | { MT_CONTROL, "ancillary data" }, | |
55 | { MT_HEADER, "packet headers" }, | |
984263bc | 56 | { MT_SONAME, "socket names and addresses" }, |
984263bc MD |
57 | { 0, 0 } |
58 | }; | |
59 | ||
60 | /* | |
61 | * Print mbuf statistics. | |
62 | */ | |
63 | void | |
c83e573d SZ |
64 | mbpr(u_long mbaddr, u_long mbtaddr, u_long nmbcaddr, u_long nmbjcaddr, |
65 | u_long nmbufaddr, u_long ncpusaddr) | |
984263bc | 66 | { |
6bc29f65 | 67 | u_long totmem, totpossible; |
7a52e261 | 68 | struct mbstat *mbstat; |
984263bc | 69 | struct mbtypenames *mp; |
c83e573d SZ |
70 | int name[3], nmbclusters, nmbjclusters, nmbufs, nmbtypes; |
71 | size_t nmbclen, nmbjclen, nmbuflen, mbstatlen, mbtypeslen; | |
984263bc | 72 | u_long *mbtypes; |
7a52e261 MD |
73 | int ncpus; |
74 | int n; | |
75 | int i; | |
984263bc MD |
76 | bool *seen; /* "have we seen this type yet?" */ |
77 | ||
78 | mbtypes = NULL; | |
79 | seen = NULL; | |
7a52e261 | 80 | mbstat = NULL; |
984263bc MD |
81 | |
82 | /* | |
83 | * XXX | |
84 | * We can't kread() mbtypeslen from a core image so we'll | |
85 | * bogusly assume it's the same as in the running kernel. | |
86 | */ | |
87 | if (sysctlbyname("kern.ipc.mbtypes", NULL, &mbtypeslen, NULL, 0) < 0) { | |
88 | warn("sysctl: retrieving mbtypes length"); | |
89 | goto err; | |
90 | } | |
984263bc MD |
91 | nmbtypes = mbtypeslen / sizeof(*mbtypes); |
92 | if ((seen = calloc(nmbtypes, sizeof(*seen))) == NULL) { | |
93 | warn("calloc"); | |
94 | goto err; | |
95 | } | |
96 | ||
97 | if (mbaddr) { | |
7a52e261 MD |
98 | if (kread(ncpusaddr, (char *)&ncpus, sizeof ncpus)) |
99 | goto err; | |
6b019ea8 | 100 | mbstat = calloc(ncpus, sizeof(*mbstat)); |
7a52e261 | 101 | if (kread(mbaddr, (char *)mbstat, sizeof *mbstat * ncpus)) |
984263bc | 102 | goto err; |
6b019ea8 | 103 | mbtypes = calloc(ncpus, mbtypeslen); |
7a52e261 | 104 | if (kread(mbtaddr, (char *)mbtypes, mbtypeslen * ncpus)) |
984263bc MD |
105 | goto err; |
106 | if (kread(nmbcaddr, (char *)&nmbclusters, sizeof(int))) | |
107 | goto err; | |
c83e573d SZ |
108 | if (kread(nmbjcaddr, (char *)&nmbjclusters, sizeof(int))) |
109 | goto err; | |
984263bc MD |
110 | if (kread(nmbufaddr, (char *)&nmbufs, sizeof(int))) |
111 | goto err; | |
7a52e261 MD |
112 | for (n = 1; n < ncpus; ++n) { |
113 | mbstat[0].m_mbufs += mbstat[n].m_mbufs; | |
114 | mbstat[0].m_clusters += mbstat[n].m_clusters; | |
115 | mbstat[0].m_drops += mbstat[n].m_drops; | |
116 | mbstat[0].m_wait += mbstat[n].m_wait; | |
117 | mbstat[0].m_drain += mbstat[n].m_drain; | |
118 | ||
119 | for (i = 0; i < nmbtypes; ++i) { | |
120 | mbtypes[i] += mbtypes[n * nmbtypes + i]; | |
121 | } | |
122 | } | |
984263bc MD |
123 | } else { |
124 | name[0] = CTL_KERN; | |
125 | name[1] = KERN_IPC; | |
126 | name[2] = KIPC_MBSTAT; | |
7a52e261 MD |
127 | mbstat = malloc(sizeof(*mbstat)); |
128 | mbstatlen = sizeof *mbstat; | |
129 | /* fake ncpus, kernel will aggregate mbstat array for us */ | |
130 | if (sysctl(name, 3, mbstat, &mbstatlen, 0, 0) < 0) { | |
984263bc MD |
131 | warn("sysctl: retrieving mbstat"); |
132 | goto err; | |
133 | } | |
134 | ||
7a52e261 | 135 | mbtypes = malloc(mbtypeslen); |
984263bc MD |
136 | if (sysctlbyname("kern.ipc.mbtypes", mbtypes, &mbtypeslen, NULL, |
137 | 0) < 0) { | |
138 | warn("sysctl: retrieving mbtypes"); | |
139 | goto err; | |
140 | } | |
141 | ||
142 | name[2] = KIPC_NMBCLUSTERS; | |
143 | nmbclen = sizeof(int); | |
144 | if (sysctl(name, 3, &nmbclusters, &nmbclen, 0, 0) < 0) { | |
145 | warn("sysctl: retrieving nmbclusters"); | |
146 | goto err; | |
147 | } | |
148 | ||
c83e573d SZ |
149 | nmbjclen = sizeof(int); |
150 | if (sysctlbyname("kern.ipc.nmbjclusters", | |
151 | &nmbjclusters, &nmbjclen, 0, 0) < 0) { | |
152 | warn("sysctl: retrieving nmbjclusters"); | |
153 | goto err; | |
154 | } | |
155 | ||
984263bc MD |
156 | nmbuflen = sizeof(int); |
157 | if (sysctlbyname("kern.ipc.nmbufs", &nmbufs, &nmbuflen, 0, 0) < 0) { | |
158 | warn("sysctl: retrieving nmbufs"); | |
159 | goto err; | |
160 | } | |
161 | } | |
162 | ||
163 | #undef MSIZE | |
7a52e261 | 164 | #define MSIZE (mbstat->m_msize) |
984263bc | 165 | #undef MCLBYTES |
7a52e261 | 166 | #define MCLBYTES (mbstat->m_mclbytes) |
c83e573d SZ |
167 | #undef MJUMPAGESIZE |
168 | #define MJUMPAGESIZE (mbstat->m_mjumpagesize) | |
984263bc | 169 | |
7a52e261 | 170 | printf("%lu/%u mbufs in use (current/max):\n", mbstat->m_mbufs, nmbufs); |
6bc29f65 | 171 | printf("%lu/%u mbuf clusters in use (current/max)\n", |
7a52e261 | 172 | mbstat->m_clusters, nmbclusters); |
c83e573d SZ |
173 | printf("%lu/%u mbuf jumbo clusters in use (current/max)\n", |
174 | mbstat->m_jclusters, nmbjclusters); | |
984263bc MD |
175 | for (mp = mbtypenames; mp->mt_name; mp++) |
176 | if (mbtypes[mp->mt_type]) { | |
177 | seen[mp->mt_type] = YES; | |
7a52e261 MD |
178 | printf("\t%lu mbufs and mbuf clusters " |
179 | "allocated to %s\n", | |
180 | mbtypes[mp->mt_type], mp->mt_name); | |
984263bc MD |
181 | } |
182 | seen[MT_FREE] = YES; | |
183 | for (i = 0; i < nmbtypes; i++) | |
184 | if (!seen[i] && mbtypes[i]) { | |
6bc29f65 | 185 | printf("\t%lu mbufs and mbuf clusters allocated to <mbuf type %d>\n", |
984263bc MD |
186 | mbtypes[i], i); |
187 | } | |
c83e573d SZ |
188 | totmem = mbstat->m_mbufs * MSIZE + mbstat->m_clusters * MCLBYTES + |
189 | mbstat->m_jclusters * MJUMPAGESIZE; | |
190 | totpossible = MSIZE * nmbufs + nmbclusters * MCLBYTES + | |
191 | nmbjclusters * MJUMPAGESIZE; | |
984263bc MD |
192 | printf("%lu Kbytes allocated to network (%lu%% of mb_map in use)\n", |
193 | totmem / 1024, (totmem * 100) / totpossible); | |
7a52e261 MD |
194 | printf("%lu requests for memory denied\n", mbstat->m_drops); |
195 | printf("%lu requests for memory delayed\n", mbstat->m_wait); | |
196 | printf("%lu calls to protocol drain routines\n", mbstat->m_drain); | |
984263bc MD |
197 | |
198 | err: | |
7a52e261 MD |
199 | if (mbstat != NULL) |
200 | free(mbstat); | |
984263bc MD |
201 | if (mbtypes != NULL) |
202 | free(mbtypes); | |
203 | if (seen != NULL) | |
204 | free(seen); | |
205 | } |