| @@ -1,1570 +1,1546 @@ | | | @@ -1,1570 +1,1546 @@ |
1 | /* $NetBSD: vmstat.c,v 1.245 2021/04/01 06:23:14 simonb Exp $ */ | | 1 | /* $NetBSD: vmstat.c,v 1.246 2021/04/02 06:28:55 simonb Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1998, 2000, 2001, 2007, 2019, 2020 | | 4 | * Copyright (c) 1998, 2000, 2001, 2007, 2019, 2020 |
5 | * The NetBSD Foundation, Inc. | | 5 | * The NetBSD Foundation, Inc. |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * This code is derived from software contributed to The NetBSD Foundation by: | | 8 | * This code is derived from software contributed to The NetBSD Foundation by: |
9 | * - Jason R. Thorpe of the Numerical Aerospace Simulation Facility, | | 9 | * - Jason R. Thorpe of the Numerical Aerospace Simulation Facility, |
10 | * NASA Ames Research Center. | | 10 | * NASA Ames Research Center. |
11 | * - Simon Burge and Luke Mewburn of Wasabi Systems, Inc. | | 11 | * - Simon Burge and Luke Mewburn of Wasabi Systems, Inc. |
12 | * | | 12 | * |
13 | * Redistribution and use in source and binary forms, with or without | | 13 | * Redistribution and use in source and binary forms, with or without |
14 | * modification, are permitted provided that the following conditions | | 14 | * modification, are permitted provided that the following conditions |
15 | * are met: | | 15 | * are met: |
16 | * 1. Redistributions of source code must retain the above copyright | | 16 | * 1. Redistributions of source code must retain the above copyright |
17 | * notice, this list of conditions and the following disclaimer. | | 17 | * notice, this list of conditions and the following disclaimer. |
18 | * 2. Redistributions in binary form must reproduce the above copyright | | 18 | * 2. Redistributions in binary form must reproduce the above copyright |
19 | * notice, this list of conditions and the following disclaimer in the | | 19 | * notice, this list of conditions and the following disclaimer in the |
20 | * documentation and/or other materials provided with the distribution. | | 20 | * documentation and/or other materials provided with the distribution. |
21 | * | | 21 | * |
22 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 22 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
23 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 23 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
24 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 24 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
25 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 25 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
26 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 26 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
29 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 29 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
32 | * POSSIBILITY OF SUCH DAMAGE. | | 32 | * POSSIBILITY OF SUCH DAMAGE. |
33 | */ | | 33 | */ |
34 | | | 34 | |
35 | /* | | 35 | /* |
36 | * Copyright (c) 1980, 1986, 1991, 1993 | | 36 | * Copyright (c) 1980, 1986, 1991, 1993 |
37 | * The Regents of the University of California. All rights reserved. | | 37 | * The Regents of the University of California. All rights reserved. |
38 | * | | 38 | * |
39 | * Redistribution and use in source and binary forms, with or without | | 39 | * Redistribution and use in source and binary forms, with or without |
40 | * modification, are permitted provided that the following conditions | | 40 | * modification, are permitted provided that the following conditions |
41 | * are met: | | 41 | * are met: |
42 | * 1. Redistributions of source code must retain the above copyright | | 42 | * 1. Redistributions of source code must retain the above copyright |
43 | * notice, this list of conditions and the following disclaimer. | | 43 | * notice, this list of conditions and the following disclaimer. |
44 | * 2. Redistributions in binary form must reproduce the above copyright | | 44 | * 2. Redistributions in binary form must reproduce the above copyright |
45 | * notice, this list of conditions and the following disclaimer in the | | 45 | * notice, this list of conditions and the following disclaimer in the |
46 | * documentation and/or other materials provided with the distribution. | | 46 | * documentation and/or other materials provided with the distribution. |
47 | * 3. Neither the name of the University nor the names of its contributors | | 47 | * 3. Neither the name of the University nor the names of its contributors |
48 | * may be used to endorse or promote products derived from this software | | 48 | * may be used to endorse or promote products derived from this software |
49 | * without specific prior written permission. | | 49 | * without specific prior written permission. |
50 | * | | 50 | * |
51 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | | 51 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
52 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 52 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
53 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 53 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
54 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 54 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
55 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 55 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
56 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 56 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
57 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 57 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
58 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 58 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
59 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 59 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
60 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 60 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
61 | * SUCH DAMAGE. | | 61 | * SUCH DAMAGE. |
62 | */ | | 62 | */ |
63 | | | 63 | |
64 | #include <sys/cdefs.h> | | 64 | #include <sys/cdefs.h> |
65 | #ifndef lint | | 65 | #ifndef lint |
66 | __COPYRIGHT("@(#) Copyright (c) 1980, 1986, 1991, 1993\ | | 66 | __COPYRIGHT("@(#) Copyright (c) 1980, 1986, 1991, 1993\ |
67 | The Regents of the University of California. All rights reserved."); | | 67 | The Regents of the University of California. All rights reserved."); |
68 | #endif /* not lint */ | | 68 | #endif /* not lint */ |
69 | | | 69 | |
70 | #ifndef lint | | 70 | #ifndef lint |
71 | #if 0 | | 71 | #if 0 |
72 | static char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 3/1/95"; | | 72 | static char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 3/1/95"; |
73 | #else | | 73 | #else |
74 | __RCSID("$NetBSD: vmstat.c,v 1.245 2021/04/01 06:23:14 simonb Exp $"); | | 74 | __RCSID("$NetBSD: vmstat.c,v 1.246 2021/04/02 06:28:55 simonb Exp $"); |
75 | #endif | | 75 | #endif |
76 | #endif /* not lint */ | | 76 | #endif /* not lint */ |
77 | | | 77 | |
78 | #define __POOL_EXPOSE | | 78 | #define __POOL_EXPOSE |
79 | #define __NAMECACHE_PRIVATE | | 79 | #define __NAMECACHE_PRIVATE |
80 | | | 80 | |
81 | #include <sys/param.h> | | 81 | #include <sys/param.h> |
82 | #include <sys/types.h> | | 82 | #include <sys/types.h> |
83 | #include <sys/mount.h> | | 83 | #include <sys/mount.h> |
84 | #include <sys/uio.h> | | 84 | #include <sys/uio.h> |
85 | | | 85 | |
86 | #include <sys/buf.h> | | 86 | #include <sys/buf.h> |
87 | #include <sys/evcnt.h> | | 87 | #include <sys/evcnt.h> |
88 | #include <sys/ioctl.h> | | 88 | #include <sys/ioctl.h> |
89 | #include <sys/malloc.h> | | 89 | #include <sys/malloc.h> |
90 | #include <sys/mallocvar.h> | | 90 | #include <sys/mallocvar.h> |
91 | #include <sys/namei.h> | | 91 | #include <sys/namei.h> |
92 | #include <sys/pool.h> | | 92 | #include <sys/pool.h> |
93 | #include <sys/proc.h> | | 93 | #include <sys/proc.h> |
94 | #include <sys/sched.h> | | 94 | #include <sys/sched.h> |
95 | #include <sys/socket.h> | | 95 | #include <sys/socket.h> |
96 | #include <sys/sysctl.h> | | 96 | #include <sys/sysctl.h> |
97 | #include <sys/time.h> | | 97 | #include <sys/time.h> |
98 | #include <sys/queue.h> | | 98 | #include <sys/queue.h> |
99 | #include <sys/kernhist.h> | | 99 | #include <sys/kernhist.h> |
100 | #include <sys/vnode.h> | | 100 | #include <sys/vnode.h> |
101 | #include <sys/vnode_impl.h> | | 101 | #include <sys/vnode_impl.h> |
102 | | | 102 | |
103 | #include <uvm/uvm_extern.h> | | 103 | #include <uvm/uvm_extern.h> |
104 | #include <uvm/uvm_stat.h> | | 104 | #include <uvm/uvm_stat.h> |
105 | | | 105 | |
106 | #include <net/if.h> | | 106 | #include <net/if.h> |
107 | #include <netinet/in.h> | | 107 | #include <netinet/in.h> |
108 | #include <netinet/in_var.h> | | 108 | #include <netinet/in_var.h> |
109 | | | 109 | |
110 | #include <ufs/ufs/inode.h> | | 110 | #include <ufs/ufs/inode.h> |
111 | | | 111 | |
112 | #include <nfs/rpcv2.h> | | 112 | #include <nfs/rpcv2.h> |
113 | #include <nfs/nfsproto.h> | | 113 | #include <nfs/nfsproto.h> |
114 | #include <nfs/nfsnode.h> | | 114 | #include <nfs/nfsnode.h> |
115 | | | 115 | |
116 | #include <assert.h> | | 116 | #include <assert.h> |
117 | #include <ctype.h> | | 117 | #include <ctype.h> |
118 | #include <err.h> | | 118 | #include <err.h> |
119 | #include <errno.h> | | 119 | #include <errno.h> |
120 | #include <fcntl.h> | | 120 | #include <fcntl.h> |
121 | #include <kvm.h> | | 121 | #include <kvm.h> |
122 | #include <limits.h> | | 122 | #include <limits.h> |
123 | #include <nlist.h> | | 123 | #include <nlist.h> |
124 | #undef n_hash | | 124 | #undef n_hash |
125 | #include <paths.h> | | 125 | #include <paths.h> |
126 | #include <signal.h> | | 126 | #include <signal.h> |
127 | #include <stdio.h> | | 127 | #include <stdio.h> |
128 | #include <stddef.h> | | 128 | #include <stddef.h> |
129 | #include <stdlib.h> | | 129 | #include <stdlib.h> |
130 | #include <string.h> | | 130 | #include <string.h> |
131 | #include <time.h> | | 131 | #include <time.h> |
132 | #include <unistd.h> | | 132 | #include <unistd.h> |
133 | #include <util.h> | | 133 | #include <util.h> |
134 | | | 134 | |
135 | #include "drvstats.h" | | 135 | #include "drvstats.h" |
136 | | | 136 | |
137 | /* | | 137 | /* |
138 | * All this mess will go away once everything is converted. | | 138 | * All this mess will go away once everything is converted. |
139 | */ | | 139 | */ |
140 | #ifdef __HAVE_CPU_DATA_FIRST | | 140 | #ifdef __HAVE_CPU_DATA_FIRST |
141 | | | 141 | |
142 | # include <sys/cpu_data.h> | | 142 | # include <sys/cpu_data.h> |
143 | struct cpu_info { | | 143 | struct cpu_info { |
144 | struct cpu_data ci_data; | | 144 | struct cpu_data ci_data; |
145 | }; | | 145 | }; |
146 | #else | | 146 | #else |
147 | # include <sys/cpu.h> | | 147 | # include <sys/cpu.h> |
148 | #endif | | 148 | #endif |
149 | | | 149 | |
150 | /* | | 150 | /* |
151 | * General namelist | | 151 | * General namelist |
152 | */ | | 152 | */ |
153 | struct nlist namelist[] = | | 153 | struct nlist namelist[] = |
154 | { | | 154 | { |
155 | #define X_HZ 0 | | 155 | #define X_HZ 0 |
156 | { .n_name = "_hz" }, | | 156 | { .n_name = "_hz" }, |
157 | #define X_STATHZ 1 | | 157 | #define X_STATHZ 1 |
158 | { .n_name = "_stathz" }, | | 158 | { .n_name = "_stathz" }, |
159 | #define X_NCHSTATS 2 | | 159 | #define X_NCHSTATS 2 |
160 | { .n_name = "_nchstats" }, | | 160 | { .n_name = "_nchstats" }, |
161 | #define X_ALLEVENTS 3 | | 161 | #define X_ALLEVENTS 3 |
162 | { .n_name = "_allevents" }, | | 162 | { .n_name = "_allevents" }, |
163 | #define X_POOLHEAD 4 | | 163 | #define X_POOLHEAD 4 |
164 | { .n_name = "_pool_head" }, | | 164 | { .n_name = "_pool_head" }, |
165 | #define X_UVMEXP 5 | | 165 | #define X_UVMEXP 5 |
166 | { .n_name = "_uvmexp" }, | | 166 | { .n_name = "_uvmexp" }, |
167 | #define X_CPU_INFOS 6 | | 167 | #define X_CPU_INFOS 6 |
168 | { .n_name = "_cpu_infos" }, | | 168 | { .n_name = "_cpu_infos" }, |
169 | #define X_NL_SIZE 7 | | 169 | #define X_NL_SIZE 7 |
170 | { .n_name = NULL }, | | 170 | { .n_name = NULL }, |
171 | }; | | 171 | }; |
172 | | | 172 | |
173 | /* | | 173 | /* |
174 | * Namelist for time data. | | 174 | * Namelist for time data. |
175 | */ | | 175 | */ |
176 | struct nlist timenl[] = | | 176 | struct nlist timenl[] = |
177 | { | | 177 | { |
178 | #define X_TIMEBASEBIN 0 | | 178 | #define X_TIMEBASEBIN 0 |
179 | { .n_name = "_timebasebin" }, | | 179 | { .n_name = "_timebasebin" }, |
180 | #define X_TIME_SECOND 1 | | 180 | #define X_TIME_SECOND 1 |
181 | { .n_name = "_time_second" }, | | 181 | { .n_name = "_time_second" }, |
182 | #define X_TIME 2 | | 182 | #define X_TIME 2 |
183 | { .n_name = "_time" }, | | 183 | { .n_name = "_time" }, |
184 | #define X_TIMENL_SIZE 3 | | 184 | #define X_TIMENL_SIZE 3 |
185 | { .n_name = NULL }, | | 185 | { .n_name = NULL }, |
186 | }; | | 186 | }; |
187 | | | 187 | |
188 | /* | | 188 | /* |
189 | * Namelist for pre-evcnt interrupt counters. | | 189 | * Namelist for pre-evcnt interrupt counters. |
190 | */ | | 190 | */ |
191 | struct nlist intrnl[] = | | 191 | struct nlist intrnl[] = |
192 | { | | 192 | { |
193 | #define X_INTRNAMES 0 | | 193 | #define X_INTRNAMES 0 |
194 | { .n_name = "_intrnames" }, | | 194 | { .n_name = "_intrnames" }, |
195 | #define X_EINTRNAMES 1 | | 195 | #define X_EINTRNAMES 1 |
196 | { .n_name = "_eintrnames" }, | | 196 | { .n_name = "_eintrnames" }, |
197 | #define X_INTRCNT 2 | | 197 | #define X_INTRCNT 2 |
198 | { .n_name = "_intrcnt" }, | | 198 | { .n_name = "_intrcnt" }, |
199 | #define X_EINTRCNT 3 | | 199 | #define X_EINTRCNT 3 |
200 | { .n_name = "_eintrcnt" }, | | 200 | { .n_name = "_eintrcnt" }, |
201 | #define X_INTRNL_SIZE 4 | | 201 | #define X_INTRNL_SIZE 4 |
202 | { .n_name = NULL }, | | 202 | { .n_name = NULL }, |
203 | }; | | 203 | }; |
204 | | | 204 | |
205 | | | 205 | |
206 | /* | | 206 | /* |
207 | * Namelist for hash statistics | | 207 | * Namelist for hash statistics |
208 | */ | | 208 | */ |
209 | struct nlist hashnl[] = | | 209 | struct nlist hashnl[] = |
210 | { | | 210 | { |
211 | #define X_BUFHASH 0 | | 211 | #define X_BUFHASH 0 |
212 | { .n_name = "_bufhash" }, | | 212 | { .n_name = "_bufhash" }, |
213 | #define X_BUFHASHTBL 1 | | 213 | #define X_BUFHASHTBL 1 |
214 | { .n_name = "_bufhashtbl" }, | | 214 | { .n_name = "_bufhashtbl" }, |
215 | #define X_UIHASH 2 | | 215 | #define X_UIHASH 2 |
216 | { .n_name = "_uihash" }, | | 216 | { .n_name = "_uihash" }, |
217 | #define X_UIHASHTBL 3 | | 217 | #define X_UIHASHTBL 3 |
218 | { .n_name = "_uihashtbl" }, | | 218 | { .n_name = "_uihashtbl" }, |
219 | #define X_IFADDRHASH 4 | | 219 | #define X_IFADDRHASH 4 |
220 | { .n_name = "_in_ifaddrhash" }, | | 220 | { .n_name = "_in_ifaddrhash" }, |
221 | #define X_IFADDRHASHTBL 5 | | 221 | #define X_IFADDRHASHTBL 5 |
222 | { .n_name = "_in_ifaddrhashtbl" }, | | 222 | { .n_name = "_in_ifaddrhashtbl" }, |
223 | #define X_VCACHEHASH 6 | | 223 | #define X_VCACHEHASH 6 |
224 | { .n_name = "_vcache_hashmask" }, | | 224 | { .n_name = "_vcache_hashmask" }, |
225 | #define X_VCACHETBL 7 | | 225 | #define X_VCACHETBL 7 |
226 | { .n_name = "_vcache_hashtab" }, | | 226 | { .n_name = "_vcache_hashtab" }, |
227 | #define X_HASHNL_SIZE 8 /* must be last */ | | 227 | #define X_HASHNL_SIZE 8 /* must be last */ |
228 | { .n_name = NULL }, | | 228 | { .n_name = NULL }, |
229 | }; | | 229 | }; |
230 | | | 230 | |
231 | /* | | 231 | /* |
232 | * Namelist for kernel histories | | 232 | * Namelist for kernel histories |
233 | */ | | 233 | */ |
234 | struct nlist histnl[] = | | 234 | struct nlist histnl[] = |
235 | { | | 235 | { |
236 | { .n_name = "_kern_histories" }, | | 236 | { .n_name = "_kern_histories" }, |
237 | #define X_KERN_HISTORIES 0 | | 237 | #define X_KERN_HISTORIES 0 |
238 | { .n_name = NULL }, | | 238 | { .n_name = NULL }, |
239 | }; | | 239 | }; |
240 | | | 240 | |
241 | | | 241 | |
242 | #define KILO 1024 | | 242 | #define KILO 1024 |
243 | | | 243 | |
244 | struct cpu_counter { | | 244 | struct cpu_counter { |
245 | uint64_t nintr; | | 245 | uint64_t nintr; |
246 | uint64_t nsyscall; | | 246 | uint64_t nsyscall; |
247 | uint64_t nswtch; | | 247 | uint64_t nswtch; |
248 | uint64_t nfault; | | 248 | uint64_t nfault; |
249 | uint64_t ntrap; | | 249 | uint64_t ntrap; |
250 | uint64_t nsoft; | | 250 | uint64_t nsoft; |
251 | } cpucounter, ocpucounter; | | 251 | } cpucounter, ocpucounter; |
252 | | | 252 | |
253 | struct uvmexp_sysctl uvmexp, ouvmexp; | | 253 | struct uvmexp_sysctl uvmexp, ouvmexp; |
254 | int ndrives; | | 254 | int ndrives; |
255 | | | 255 | |
256 | int winlines = 20; | | 256 | int winlines = 20; |
257 | | | 257 | |
258 | kvm_t *kd; | | 258 | kvm_t *kd; |
259 | | | 259 | |
260 | | | 260 | |
261 | #define FORKSTAT 0x001 | | 261 | #define FORKSTAT 0x001 |
262 | #define INTRSTAT 0x002 | | 262 | #define INTRSTAT 0x002 |
263 | #define MEMSTAT 0x004 | | 263 | #define MEMSTAT 0x004 |
264 | #define SUMSTAT 0x008 | | 264 | #define SUMSTAT 0x008 |
265 | #define EVCNTSTAT 0x010 | | 265 | #define EVCNTSTAT 0x010 |
266 | #define VMSTAT 0x020 | | 266 | #define VMSTAT 0x020 |
267 | #define HISTLIST 0x040 | | 267 | #define HISTLIST 0x040 |
268 | #define HISTDUMP 0x080 | | 268 | #define HISTDUMP 0x080 |
269 | #define HASHSTAT 0x100 | | 269 | #define HASHSTAT 0x100 |
270 | #define HASHLIST 0x200 | | 270 | #define HASHLIST 0x200 |
271 | #define VMTOTAL 0x400 | | 271 | #define VMTOTAL 0x400 |
272 | #define POOLCACHESTAT 0x800 | | 272 | #define POOLCACHESTAT 0x800 |
273 | | | 273 | |
274 | /* | | 274 | /* |
275 | * Print single word. `ovflow' is number of characters didn't fit | | 275 | * Print single word. `ovflow' is number of characters didn't fit |
276 | * on the last word. `fmt' is a format string to print this word. | | 276 | * on the last word. `fmt' is a format string to print this word. |
277 | * It must contain asterisk for field width. `width' is a width | | 277 | * It must contain asterisk for field width. `width' is a width |
278 | * occupied by this word. `fixed' is a number of constant chars in | | 278 | * occupied by this word. `fixed' is a number of constant chars in |
279 | * `fmt'. `val' is a value to be printed using format string `fmt'. | | 279 | * `fmt'. `val' is a value to be printed using format string `fmt'. |
280 | */ | | 280 | */ |
281 | #define PRWORD(ovflw, fmt, width, fixed, val) do { \ | | 281 | #define PRWORD(ovflw, fmt, width, fixed, val) do { \ |
282 | (ovflw) += printf((fmt), \ | | 282 | (ovflw) += printf((fmt), \ |
283 | (width) - (fixed) - (ovflw) > 0 ? \ | | 283 | (width) - (fixed) - (ovflw) > 0 ? \ |
284 | (width) - (fixed) - (ovflw) : 0, \ | | 284 | (width) - (fixed) - (ovflw) : 0, \ |
285 | (val)) - (width); \ | | 285 | (val)) - (width); \ |
286 | if ((ovflw) < 0) \ | | 286 | if ((ovflw) < 0) \ |
287 | (ovflw) = 0; \ | | 287 | (ovflw) = 0; \ |
288 | } while (/* CONSTCOND */0) | | 288 | } while (/* CONSTCOND */0) |
289 | | | 289 | |
290 | void cpustats(int *); | | 290 | void cpustats(int *); |
291 | void cpucounters(struct cpu_counter *); | | 291 | void cpucounters(struct cpu_counter *); |
292 | void deref_kptr(const void *, void *, size_t, const char *); | | 292 | void deref_kptr(const void *, void *, size_t, const char *); |
293 | void drvstats(int *); | | 293 | void drvstats(int *); |
294 | void doevcnt(int verbose, int type); | | 294 | void doevcnt(int verbose, int type); |
295 | void dohashstat(int, int, const char *); | | 295 | void dohashstat(int, int, const char *); |
296 | void dohashstat_sysctl(int, int, const char *); | | 296 | void dohashstat_sysctl(int, int, const char *); |
297 | void dointr(int verbose); | | 297 | void dointr(int verbose); |
298 | void dopool(int, int); | | 298 | void dopool(int, int); |
299 | void dopoolcache(int); | | 299 | void dopoolcache(int); |
300 | void dosum(void); | | 300 | void dosum(void); |
301 | void dovmstat(struct timespec *, int); | | 301 | void dovmstat(struct timespec *, int); |
302 | void print_total_hdr(void); | | 302 | void print_total_hdr(void); |
303 | void dovmtotal(struct timespec *, int); | | 303 | void dovmtotal(struct timespec *, int); |
304 | void kread(struct nlist *, int, void *, size_t); | | 304 | void kread(struct nlist *, int, void *, size_t); |
305 | int kreadc(struct nlist *, int, void *, size_t); | | 305 | int kreadc(struct nlist *, int, void *, size_t); |
306 | void needhdr(int); | | 306 | void needhdr(int); |
307 | void getnlist(int); | | 307 | void getnlist(int); |
308 | long getuptime(void); | | 308 | long getuptime(void); |
309 | void printhdr(void); | | 309 | void printhdr(void); |
310 | long pct(u_long, u_long); | | 310 | long pct(u_long, u_long); |
311 | __dead static void usage(void); | | 311 | __dead static void usage(void); |
312 | void doforkst(void); | | 312 | void doforkst(void); |
313 | | | 313 | |
314 | void hist_traverse(int, const char *); | | 314 | void hist_traverse(int, const char *); |
315 | void hist_dodump(struct kern_history *); | | 315 | void hist_dodump(struct kern_history *); |
316 | void hist_traverse_sysctl(int, const char *); | | 316 | void hist_traverse_sysctl(int, const char *); |
317 | void hist_dodump_sysctl(int[], unsigned int); | | 317 | void hist_dodump_sysctl(int[], unsigned int); |
318 | | | 318 | |
319 | char **choosedrives(char **); | | 319 | char **choosedrives(char **); |
320 | | | 320 | |
321 | /* Namelist and memory file names. */ | | 321 | /* Namelist and memory file names. */ |
322 | char *nlistf, *memf; | | 322 | char *nlistf, *memf; |
323 | | | 323 | |
324 | /* allow old usage [vmstat 1] */ | | 324 | /* allow old usage [vmstat 1] */ |
325 | #define BACKWARD_COMPATIBILITY | | 325 | #define BACKWARD_COMPATIBILITY |
326 | | | 326 | |
327 | static const int clockrate_mib[] = { CTL_KERN, KERN_CLOCKRATE }; | | 327 | static const int clockrate_mib[] = { CTL_KERN, KERN_CLOCKRATE }; |
328 | static const int vmmeter_mib[] = { CTL_VM, VM_METER }; | | 328 | static const int vmmeter_mib[] = { CTL_VM, VM_METER }; |
329 | static const int uvmexp2_mib[] = { CTL_VM, VM_UVMEXP2 }; | | 329 | static const int uvmexp2_mib[] = { CTL_VM, VM_UVMEXP2 }; |
330 | static const int boottime_mib[] = { CTL_KERN, KERN_BOOTTIME }; | | 330 | static const int boottime_mib[] = { CTL_KERN, KERN_BOOTTIME }; |
331 | static char kvm_errbuf[_POSIX2_LINE_MAX]; | | | |
332 | | | 331 | |
333 | int | | 332 | int |
334 | main(int argc, char *argv[]) | | 333 | main(int argc, char *argv[]) |
335 | { | | 334 | { |
336 | int c, todo, verbose, wide; | | 335 | int c, todo, verbose, wide; |
337 | struct timespec interval; | | 336 | struct timespec interval; |
338 | int reps; | | 337 | int reps; |
339 | gid_t egid = getegid(); | | | |
340 | const char *histname, *hashname; | | 338 | const char *histname, *hashname; |
| | | 339 | char errbuf[_POSIX2_LINE_MAX]; |
341 | | | 340 | |
342 | histname = hashname = NULL; | | 341 | histname = hashname = NULL; |
343 | (void)setegid(getgid()); | | | |
344 | memf = nlistf = NULL; | | 342 | memf = nlistf = NULL; |
345 | reps = todo = verbose = wide = 0; | | 343 | reps = todo = verbose = wide = 0; |
346 | interval.tv_sec = 0; | | 344 | interval.tv_sec = 0; |
347 | interval.tv_nsec = 0; | | 345 | interval.tv_nsec = 0; |
348 | while ((c = getopt(argc, argv, "Cc:efh:HilLM:mN:stu:UvWw:")) != -1) { | | 346 | while ((c = getopt(argc, argv, "Cc:efh:HilLM:mN:stu:UvWw:")) != -1) { |
349 | switch (c) { | | 347 | switch (c) { |
350 | case 'c': | | 348 | case 'c': |
351 | reps = atoi(optarg); | | 349 | reps = atoi(optarg); |
352 | break; | | 350 | break; |
353 | case 'C': | | 351 | case 'C': |
354 | todo |= POOLCACHESTAT; | | 352 | todo |= POOLCACHESTAT; |
355 | break; | | 353 | break; |
356 | case 'e': | | 354 | case 'e': |
357 | todo |= EVCNTSTAT; | | 355 | todo |= EVCNTSTAT; |
358 | break; | | 356 | break; |
359 | case 'f': | | 357 | case 'f': |
360 | todo |= FORKSTAT; | | 358 | todo |= FORKSTAT; |
361 | break; | | 359 | break; |
362 | case 'h': | | 360 | case 'h': |
363 | hashname = optarg; | | 361 | hashname = optarg; |
364 | /* FALLTHROUGH */ | | 362 | /* FALLTHROUGH */ |
365 | case 'H': | | 363 | case 'H': |
366 | todo |= HASHSTAT; | | 364 | todo |= HASHSTAT; |
367 | break; | | 365 | break; |
368 | case 'i': | | 366 | case 'i': |
369 | todo |= INTRSTAT; | | 367 | todo |= INTRSTAT; |
370 | break; | | 368 | break; |
371 | case 'l': | | 369 | case 'l': |
372 | todo |= HISTLIST; | | 370 | todo |= HISTLIST; |
373 | break; | | 371 | break; |
374 | case 'L': | | 372 | case 'L': |
375 | todo |= HASHLIST; | | 373 | todo |= HASHLIST; |
376 | break; | | 374 | break; |
377 | case 'M': | | 375 | case 'M': |
378 | memf = optarg; | | 376 | memf = optarg; |
379 | break; | | 377 | break; |
380 | case 'm': | | 378 | case 'm': |
381 | todo |= MEMSTAT; | | 379 | todo |= MEMSTAT; |
382 | break; | | 380 | break; |
383 | case 'N': | | 381 | case 'N': |
384 | nlistf = optarg; | | 382 | nlistf = optarg; |
385 | break; | | 383 | break; |
386 | case 's': | | 384 | case 's': |
387 | todo |= SUMSTAT; | | 385 | todo |= SUMSTAT; |
388 | break; | | 386 | break; |
389 | case 't': | | 387 | case 't': |
390 | todo |= VMTOTAL; | | 388 | todo |= VMTOTAL; |
391 | break; | | 389 | break; |
392 | case 'u': | | 390 | case 'u': |
393 | histname = optarg; | | 391 | histname = optarg; |
394 | /* FALLTHROUGH */ | | 392 | /* FALLTHROUGH */ |
395 | case 'U': | | 393 | case 'U': |
396 | todo |= HISTDUMP; | | 394 | todo |= HISTDUMP; |
397 | break; | | 395 | break; |
398 | case 'v': | | 396 | case 'v': |
399 | verbose++; | | 397 | verbose++; |
400 | break; | | 398 | break; |
401 | case 'W': | | 399 | case 'W': |
402 | wide++; | | 400 | wide++; |
403 | break; | | 401 | break; |
404 | case 'w': | | 402 | case 'w': |
405 | interval.tv_sec = atol(optarg); | | 403 | interval.tv_sec = atol(optarg); |
406 | break; | | 404 | break; |
407 | case '?': | | 405 | case '?': |
408 | default: | | 406 | default: |
409 | usage(); | | 407 | usage(); |
410 | } | | 408 | } |
411 | } | | 409 | } |
412 | argc -= optind; | | 410 | argc -= optind; |
413 | argv += optind; | | 411 | argv += optind; |
414 | | | 412 | |
415 | if (todo == 0) | | 413 | if (todo == 0) |
416 | todo = VMSTAT; | | 414 | todo = VMSTAT; |
417 | | | 415 | |
418 | /* | | 416 | if (memf == NULL) { |
419 | * Discard setgid privileges. If not the running kernel, we toss | | 417 | kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); |
420 | * them away totally so that bad guys can't print interesting stuff | | 418 | } else { |
421 | * from kernel memory, otherwise switch back to kmem for the | | 419 | kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); |
422 | * duration of the kvm_openfiles() call. | | 420 | getnlist(todo); |
423 | */ | | | |
424 | if (nlistf != NULL || memf != NULL) | | | |
425 | (void)setgid(getgid()); | | | |
426 | else | | | |
427 | (void)setegid(egid); | | | |
428 | | | | |
429 | kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, kvm_errbuf); | | | |
430 | if (kd == NULL) { | | | |
431 | if (nlistf != NULL || memf != NULL) { | | | |
432 | errx(1, "kvm_openfiles: %s", kvm_errbuf); | | | |
433 | } | | | |
434 | } | | 421 | } |
435 | | | 422 | |
436 | if (nlistf == NULL && memf == NULL) | | 423 | if (kd == NULL) |
437 | (void)setgid(getgid()); | | 424 | errx(EXIT_FAILURE, "%s", errbuf); |
438 | | | | |
439 | | | 425 | |
440 | if (todo & VMSTAT) { | | 426 | if (todo & VMSTAT) { |
441 | struct winsize winsize; | | 427 | struct winsize winsize; |
442 | | | 428 | |
443 | (void)drvinit(0);/* Initialize disk stats, no disks selected. */ | | 429 | (void)drvinit(0);/* Initialize disk stats, no disks selected. */ |
444 | | | 430 | |
445 | (void)setgid(getgid()); /* don't need privs anymore */ | | | |
446 | | | | |
447 | argv = choosedrives(argv); /* Select disks. */ | | 431 | argv = choosedrives(argv); /* Select disks. */ |
448 | winsize.ws_row = 0; | | 432 | winsize.ws_row = 0; |
449 | (void)ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize); | | 433 | (void)ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize); |
450 | if (winsize.ws_row > 0) | | 434 | if (winsize.ws_row > 0) |
451 | winlines = winsize.ws_row; | | 435 | winlines = winsize.ws_row; |
452 | | | 436 | |
453 | } | | 437 | } |
454 | | | 438 | |
455 | #ifdef BACKWARD_COMPATIBILITY | | 439 | #ifdef BACKWARD_COMPATIBILITY |
456 | if (*argv) { | | 440 | if (*argv) { |
457 | interval.tv_sec = atol(*argv); | | 441 | interval.tv_sec = atol(*argv); |
458 | if (*++argv) | | 442 | if (*++argv) |
459 | reps = atoi(*argv); | | 443 | reps = atoi(*argv); |
460 | } | | 444 | } |
461 | #endif | | 445 | #endif |
462 | | | 446 | |
463 | if (interval.tv_sec) { | | 447 | if (interval.tv_sec) { |
464 | if (!reps) | | 448 | if (!reps) |
465 | reps = -1; | | 449 | reps = -1; |
466 | } else if (reps) | | 450 | } else if (reps) |
467 | interval.tv_sec = 1; | | 451 | interval.tv_sec = 1; |
468 | | | 452 | |
469 | | | | |
470 | getnlist(todo); | | | |
471 | /* | | 453 | /* |
472 | * Statistics dumping is incompatible with the default | | 454 | * Statistics dumping is incompatible with the default |
473 | * VMSTAT/dovmstat() output. So perform the interval/reps handling | | 455 | * VMSTAT/dovmstat() output. So perform the interval/reps handling |
474 | * for it here. | | 456 | * for it here. |
475 | */ | | 457 | */ |
476 | if ((todo & (VMSTAT|VMTOTAL)) == 0) { | | 458 | if ((todo & (VMSTAT|VMTOTAL)) == 0) { |
477 | for (;;) { | | 459 | for (;;) { |
478 | if (todo & (HISTLIST|HISTDUMP)) { | | 460 | if (todo & (HISTLIST|HISTDUMP)) { |
479 | if ((todo & (HISTLIST|HISTDUMP)) == | | 461 | if ((todo & (HISTLIST|HISTDUMP)) == |
480 | (HISTLIST|HISTDUMP)) | | 462 | (HISTLIST|HISTDUMP)) |
481 | errx(1, "you may list or dump," | | 463 | errx(1, "you may list or dump," |
482 | " but not both!"); | | 464 | " but not both!"); |
483 | if (memf != NULL) | | 465 | if (memf != NULL) |
484 | hist_traverse(todo, histname); | | 466 | hist_traverse(todo, histname); |
485 | else | | 467 | else |
486 | hist_traverse_sysctl(todo, histname); | | 468 | hist_traverse_sysctl(todo, histname); |
487 | (void)putchar('\n'); | | 469 | (void)putchar('\n'); |
488 | } | | 470 | } |
489 | if (todo & FORKSTAT) { | | 471 | if (todo & FORKSTAT) { |
490 | doforkst(); | | 472 | doforkst(); |
491 | (void)putchar('\n'); | | 473 | (void)putchar('\n'); |
492 | } | | 474 | } |
493 | if (todo & MEMSTAT) { | | 475 | if (todo & MEMSTAT) { |
494 | dopool(verbose, wide); | | 476 | dopool(verbose, wide); |
495 | (void)putchar('\n'); | | 477 | (void)putchar('\n'); |
496 | } | | 478 | } |
497 | if (todo & POOLCACHESTAT) { | | 479 | if (todo & POOLCACHESTAT) { |
498 | dopoolcache(verbose); | | 480 | dopoolcache(verbose); |
499 | (void)putchar('\n'); | | 481 | (void)putchar('\n'); |
500 | } | | 482 | } |
501 | if (todo & SUMSTAT) { | | 483 | if (todo & SUMSTAT) { |
502 | dosum(); | | 484 | dosum(); |
503 | (void)putchar('\n'); | | 485 | (void)putchar('\n'); |
504 | } | | 486 | } |
505 | if (todo & INTRSTAT) { | | 487 | if (todo & INTRSTAT) { |
506 | dointr(verbose); | | 488 | dointr(verbose); |
507 | (void)putchar('\n'); | | 489 | (void)putchar('\n'); |
508 | } | | 490 | } |
509 | if (todo & EVCNTSTAT) { | | 491 | if (todo & EVCNTSTAT) { |
510 | doevcnt(verbose, EVCNT_TYPE_ANY); | | 492 | doevcnt(verbose, EVCNT_TYPE_ANY); |
511 | (void)putchar('\n'); | | 493 | (void)putchar('\n'); |
512 | } | | 494 | } |
513 | if (todo & (HASHLIST|HASHSTAT)) { | | 495 | if (todo & (HASHLIST|HASHSTAT)) { |
514 | if ((todo & (HASHLIST|HASHSTAT)) == | | 496 | if ((todo & (HASHLIST|HASHSTAT)) == |
515 | (HASHLIST|HASHSTAT)) | | 497 | (HASHLIST|HASHSTAT)) |
516 | errx(1, "you may list or display," | | 498 | errx(1, "you may list or display," |
517 | " but not both!"); | | 499 | " but not both!"); |
518 | dohashstat(verbose, todo, hashname); | | 500 | dohashstat(verbose, todo, hashname); |
519 | (void)putchar('\n'); | | 501 | (void)putchar('\n'); |
520 | } | | 502 | } |
521 | | | 503 | |
522 | fflush(stdout); | | 504 | fflush(stdout); |
523 | if (reps >= 0 && --reps <=0) | | 505 | if (reps >= 0 && --reps <=0) |
524 | break; | | 506 | break; |
525 | (void)nanosleep(&interval, NULL); | | 507 | (void)nanosleep(&interval, NULL); |
526 | } | | 508 | } |
527 | } else { | | 509 | } else { |
528 | if ((todo & (VMSTAT|VMTOTAL)) == (VMSTAT|VMTOTAL)) { | | 510 | if ((todo & (VMSTAT|VMTOTAL)) == (VMSTAT|VMTOTAL)) { |
529 | errx(1, "you may not both do vmstat and vmtotal"); | | 511 | errx(1, "you may not both do vmstat and vmtotal"); |
530 | } | | 512 | } |
531 | if (todo & VMSTAT) | | 513 | if (todo & VMSTAT) |
532 | dovmstat(&interval, reps); | | 514 | dovmstat(&interval, reps); |
533 | if (todo & VMTOTAL) | | 515 | if (todo & VMTOTAL) |
534 | dovmtotal(&interval, reps); | | 516 | dovmtotal(&interval, reps); |
535 | } | | 517 | } |
536 | return 0; | | 518 | return 0; |
537 | } | | 519 | } |
538 | | | 520 | |
539 | void | | 521 | void |
540 | getnlist(int todo) | | 522 | getnlist(int todo) |
541 | { | | 523 | { |
542 | static int namelist_done = 0; | | | |
543 | static int done = 0; | | 524 | static int done = 0; |
544 | int c; | | 525 | int c; |
545 | size_t i; | | 526 | size_t i; |
546 | | | 527 | |
547 | if (kd == NULL) | | 528 | if ((c = kvm_nlist(kd, namelist)) != 0) { |
548 | errx(1, "kvm_openfiles: %s", kvm_errbuf); | | 529 | int doexit = 0; |
549 | | | 530 | if (c == -1) |
550 | if (!namelist_done) { | | 531 | errx(1, "kvm_nlist: %s %s", |
551 | namelist_done = 1; | | 532 | "namelist", kvm_geterr(kd)); |
552 | if ((c = kvm_nlist(kd, namelist)) != 0) { | | 533 | for (i = 0; i < __arraycount(namelist)-1; i++) |
553 | int doexit = 0; | | 534 | if (namelist[i].n_type == 0) { |
554 | if (c == -1) | | 535 | if (doexit++ == 0) |
555 | errx(1, "kvm_nlist: %s %s", | | 536 | (void)fprintf(stderr, |
556 | "namelist", kvm_geterr(kd)); | | 537 | "%s: undefined symbols:", |
557 | for (i = 0; i < __arraycount(namelist)-1; i++) | | 538 | getprogname()); |
558 | if (namelist[i].n_type == 0) { | | 539 | (void)fprintf(stderr, " %s", |
559 | if (doexit++ == 0) | | 540 | namelist[i].n_name); |
560 | (void)fprintf(stderr, | | | |
561 | "%s: undefined symbols:", | | | |
562 | getprogname()); | | | |
563 | (void)fprintf(stderr, " %s", | | | |
564 | namelist[i].n_name); | | | |
565 | } | | | |
566 | if (doexit) { | | | |
567 | (void)fputc('\n', stderr); | | | |
568 | exit(1); | | | |
569 | } | | 541 | } |
| | | 542 | if (doexit) { |
| | | 543 | (void)fputc('\n', stderr); |
| | | 544 | exit(1); |
570 | } | | 545 | } |
571 | } | | 546 | } |
| | | 547 | |
572 | if ((todo & (VMSTAT|INTRSTAT)) && !(done & (VMSTAT))) { | | 548 | if ((todo & (VMSTAT|INTRSTAT)) && !(done & (VMSTAT))) { |
573 | done |= VMSTAT; | | 549 | done |= VMSTAT; |
574 | if ((c = kvm_nlist(kd, timenl)) == -1 || c == X_TIMENL_SIZE) | | 550 | if ((c = kvm_nlist(kd, timenl)) == -1 || c == X_TIMENL_SIZE) |
575 | errx(1, "kvm_nlist: %s %s", "timenl", kvm_geterr(kd)); | | 551 | errx(1, "kvm_nlist: %s %s", "timenl", kvm_geterr(kd)); |
576 | } | | 552 | } |
577 | if ((todo & (SUMSTAT|INTRSTAT)) && !(done & (SUMSTAT|INTRSTAT))) { | | 553 | if ((todo & (SUMSTAT|INTRSTAT)) && !(done & (SUMSTAT|INTRSTAT))) { |
578 | done |= SUMSTAT|INTRSTAT; | | 554 | done |= SUMSTAT|INTRSTAT; |
579 | (void) kvm_nlist(kd, intrnl); | | 555 | (void) kvm_nlist(kd, intrnl); |
580 | } | | 556 | } |
581 | if ((todo & (HASHLIST|HASHSTAT)) && !(done & (HASHLIST|HASHSTAT))) { | | 557 | if ((todo & (HASHLIST|HASHSTAT)) && !(done & (HASHLIST|HASHSTAT))) { |
582 | done |= HASHLIST|HASHSTAT; | | 558 | done |= HASHLIST|HASHSTAT; |
583 | if ((c = kvm_nlist(kd, hashnl)) == -1 || c == X_HASHNL_SIZE) | | 559 | if ((c = kvm_nlist(kd, hashnl)) == -1 || c == X_HASHNL_SIZE) |
584 | errx(1, "kvm_nlist: %s %s", "hashnl", kvm_geterr(kd)); | | 560 | errx(1, "kvm_nlist: %s %s", "hashnl", kvm_geterr(kd)); |
585 | } | | 561 | } |
586 | if ((todo & (HISTLIST|HISTDUMP)) && !(done & (HISTLIST|HISTDUMP))) { | | 562 | if ((todo & (HISTLIST|HISTDUMP)) && !(done & (HISTLIST|HISTDUMP))) { |
587 | done |= HISTLIST|HISTDUMP; | | 563 | done |= HISTLIST|HISTDUMP; |
588 | if (kvm_nlist(kd, histnl) == -1) | | 564 | if (kvm_nlist(kd, histnl) == -1) |
589 | errx(1, "kvm_nlist: %s %s", "histnl", kvm_geterr(kd)); | | 565 | errx(1, "kvm_nlist: %s %s", "histnl", kvm_geterr(kd)); |
590 | } | | 566 | } |
591 | } | | 567 | } |
592 | | | 568 | |
593 | char ** | | 569 | char ** |
594 | choosedrives(char **argv) | | 570 | choosedrives(char **argv) |
595 | { | | 571 | { |
596 | size_t i; | | 572 | size_t i; |
597 | | | 573 | |
598 | /* | | 574 | /* |
599 | * Choose drives to be displayed. Priority goes to (in order) drives | | 575 | * Choose drives to be displayed. Priority goes to (in order) drives |
600 | * supplied as arguments, default drives. If everything isn't filled | | 576 | * supplied as arguments, default drives. If everything isn't filled |
601 | * in and there are drives not taken care of, display the first few | | 577 | * in and there are drives not taken care of, display the first few |
602 | * that fit. | | 578 | * that fit. |
603 | */ | | 579 | */ |
604 | #define BACKWARD_COMPATIBILITY | | 580 | #define BACKWARD_COMPATIBILITY |
605 | for (ndrives = 0; *argv; ++argv) { | | 581 | for (ndrives = 0; *argv; ++argv) { |
606 | #ifdef BACKWARD_COMPATIBILITY | | 582 | #ifdef BACKWARD_COMPATIBILITY |
607 | if (isdigit((unsigned char)**argv)) | | 583 | if (isdigit((unsigned char)**argv)) |
608 | break; | | 584 | break; |
609 | #endif | | 585 | #endif |
610 | for (i = 0; i < ndrive; i++) { | | 586 | for (i = 0; i < ndrive; i++) { |
611 | if (strcmp(dr_name[i], *argv)) | | 587 | if (strcmp(dr_name[i], *argv)) |
612 | continue; | | 588 | continue; |
613 | drv_select[i] = 1; | | 589 | drv_select[i] = 1; |
614 | ++ndrives; | | 590 | ++ndrives; |
615 | break; | | 591 | break; |
616 | } | | 592 | } |
617 | } | | 593 | } |
618 | for (i = 0; i < ndrive && ndrives < 2; i++) { | | 594 | for (i = 0; i < ndrive && ndrives < 2; i++) { |
619 | if (drv_select[i]) | | 595 | if (drv_select[i]) |
620 | continue; | | 596 | continue; |
621 | drv_select[i] = 1; | | 597 | drv_select[i] = 1; |
622 | ++ndrives; | | 598 | ++ndrives; |
623 | } | | 599 | } |
624 | | | 600 | |
625 | return (argv); | | 601 | return (argv); |
626 | } | | 602 | } |
627 | | | 603 | |
628 | long | | 604 | long |
629 | getuptime(void) | | 605 | getuptime(void) |
630 | { | | 606 | { |
631 | static struct timespec boottime; | | 607 | static struct timespec boottime; |
632 | struct timespec now; | | 608 | struct timespec now; |
633 | time_t uptime, nowsec; | | 609 | time_t uptime, nowsec; |
634 | | | 610 | |
635 | if (memf == NULL) { | | 611 | if (memf == NULL) { |
636 | if (boottime.tv_sec == 0) { | | 612 | if (boottime.tv_sec == 0) { |
637 | size_t buflen = sizeof(boottime); | | 613 | size_t buflen = sizeof(boottime); |
638 | if (sysctl(boottime_mib, __arraycount(boottime_mib), | | 614 | if (sysctl(boottime_mib, __arraycount(boottime_mib), |
639 | &boottime, &buflen, NULL, 0) == -1) | | 615 | &boottime, &buflen, NULL, 0) == -1) |
640 | warn("Can't get boottime"); | | 616 | warn("Can't get boottime"); |
641 | } | | 617 | } |
642 | clock_gettime(CLOCK_REALTIME, &now); | | 618 | clock_gettime(CLOCK_REALTIME, &now); |
643 | } else { | | 619 | } else { |
644 | if (boottime.tv_sec == 0) { | | 620 | if (boottime.tv_sec == 0) { |
645 | struct bintime bt; | | 621 | struct bintime bt; |
646 | | | 622 | |
647 | kread(timenl, X_TIMEBASEBIN, &bt, sizeof(bt)); | | 623 | kread(timenl, X_TIMEBASEBIN, &bt, sizeof(bt)); |
648 | bintime2timespec(&bt, &boottime); | | 624 | bintime2timespec(&bt, &boottime); |
649 | } | | 625 | } |
650 | if (kreadc(timenl, X_TIME_SECOND, &nowsec, sizeof(nowsec))) { | | 626 | if (kreadc(timenl, X_TIME_SECOND, &nowsec, sizeof(nowsec))) { |
651 | /* | | 627 | /* |
652 | * XXX this assignment dance can be removed once | | 628 | * XXX this assignment dance can be removed once |
653 | * timeval tv_sec is SUS mandated time_t | | 629 | * timeval tv_sec is SUS mandated time_t |
654 | */ | | 630 | */ |
655 | now.tv_sec = nowsec; | | 631 | now.tv_sec = nowsec; |
656 | now.tv_nsec = 0; | | 632 | now.tv_nsec = 0; |
657 | } else { | | 633 | } else { |
658 | kread(timenl, X_TIME, &now, sizeof(now)); | | 634 | kread(timenl, X_TIME, &now, sizeof(now)); |
659 | } | | 635 | } |
660 | } | | 636 | } |
661 | uptime = now.tv_sec - boottime.tv_sec; | | 637 | uptime = now.tv_sec - boottime.tv_sec; |
662 | if (uptime <= 0 || uptime > 60*60*24*365*10) | | 638 | if (uptime <= 0 || uptime > 60*60*24*365*10) |
663 | errx(1, "time makes no sense; namelist must be wrong."); | | 639 | errx(1, "time makes no sense; namelist must be wrong."); |
664 | return (uptime); | | 640 | return (uptime); |
665 | } | | 641 | } |
666 | | | 642 | |
667 | int hz, hdrcnt; | | 643 | int hz, hdrcnt; |
668 | | | 644 | |
669 | void | | 645 | void |
670 | print_total_hdr(void) | | 646 | print_total_hdr(void) |
671 | { | | 647 | { |
672 | | | 648 | |
673 | (void)printf("procs memory\n"); | | 649 | (void)printf("procs memory\n"); |
674 | (void)printf("ru dw pw sl"); | | 650 | (void)printf("ru dw pw sl"); |
675 | (void)printf(" total-v active-v active-r"); | | 651 | (void)printf(" total-v active-v active-r"); |
676 | (void)printf(" vm-sh avm-sh rm-sh arm-sh free\n"); | | 652 | (void)printf(" vm-sh avm-sh rm-sh arm-sh free\n"); |
677 | hdrcnt = winlines - 2; | | 653 | hdrcnt = winlines - 2; |
678 | } | | 654 | } |
679 | | | 655 | |
680 | void | | 656 | void |
681 | dovmtotal(struct timespec *interval, int reps) | | 657 | dovmtotal(struct timespec *interval, int reps) |
682 | { | | 658 | { |
683 | struct vmtotal total; | | 659 | struct vmtotal total; |
684 | size_t size; | | 660 | size_t size; |
685 | | | 661 | |
686 | (void)signal(SIGCONT, needhdr); | | 662 | (void)signal(SIGCONT, needhdr); |
687 | | | 663 | |
688 | for (hdrcnt = 1;;) { | | 664 | for (hdrcnt = 1;;) { |
689 | if (!--hdrcnt) | | 665 | if (!--hdrcnt) |
690 | print_total_hdr(); | | 666 | print_total_hdr(); |
691 | if (memf != NULL) { | | 667 | if (memf != NULL) { |
692 | warnx("Unable to get vmtotals from crash dump."); | | 668 | warnx("Unable to get vmtotals from crash dump."); |
693 | (void)memset(&total, 0, sizeof(total)); | | 669 | (void)memset(&total, 0, sizeof(total)); |
694 | } else { | | 670 | } else { |
695 | size = sizeof(total); | | 671 | size = sizeof(total); |
696 | if (sysctl(vmmeter_mib, __arraycount(vmmeter_mib), | | 672 | if (sysctl(vmmeter_mib, __arraycount(vmmeter_mib), |
697 | &total, &size, NULL, 0) == -1) { | | 673 | &total, &size, NULL, 0) == -1) { |
698 | warn("Can't get vmtotals"); | | 674 | warn("Can't get vmtotals"); |
699 | (void)memset(&total, 0, sizeof(total)); | | 675 | (void)memset(&total, 0, sizeof(total)); |
700 | } | | 676 | } |
701 | } | | 677 | } |
702 | (void)printf("%2d ", total.t_rq); | | 678 | (void)printf("%2d ", total.t_rq); |
703 | (void)printf("%2d ", total.t_dw); | | 679 | (void)printf("%2d ", total.t_dw); |
704 | (void)printf("%2d ", total.t_pw); | | 680 | (void)printf("%2d ", total.t_pw); |
705 | (void)printf("%2d ", total.t_sl); | | 681 | (void)printf("%2d ", total.t_sl); |
706 | | | 682 | |
707 | (void)printf("%9d ", total.t_vm); | | 683 | (void)printf("%9d ", total.t_vm); |
708 | (void)printf("%9d ", total.t_avm); | | 684 | (void)printf("%9d ", total.t_avm); |
709 | (void)printf("%9d ", total.t_arm); | | 685 | (void)printf("%9d ", total.t_arm); |
710 | (void)printf("%5d ", total.t_vmshr); | | 686 | (void)printf("%5d ", total.t_vmshr); |
711 | (void)printf("%6d ", total.t_avmshr); | | 687 | (void)printf("%6d ", total.t_avmshr); |
712 | (void)printf("%5d ", total.t_rmshr); | | 688 | (void)printf("%5d ", total.t_rmshr); |
713 | (void)printf("%6d ", total.t_armshr); | | 689 | (void)printf("%6d ", total.t_armshr); |
714 | (void)printf("%5d", total.t_free); | | 690 | (void)printf("%5d", total.t_free); |
715 | | | 691 | |
716 | (void)putchar('\n'); | | 692 | (void)putchar('\n'); |
717 | | | 693 | |
718 | (void)fflush(stdout); | | 694 | (void)fflush(stdout); |
719 | if (reps >= 0 && --reps <= 0) | | 695 | if (reps >= 0 && --reps <= 0) |
720 | break; | | 696 | break; |
721 | | | 697 | |
722 | (void)nanosleep(interval, NULL); | | 698 | (void)nanosleep(interval, NULL); |
723 | } | | 699 | } |
724 | } | | 700 | } |
725 | | | 701 | |
726 | void | | 702 | void |
727 | dovmstat(struct timespec *interval, int reps) | | 703 | dovmstat(struct timespec *interval, int reps) |
728 | { | | 704 | { |
729 | struct vmtotal total; | | 705 | struct vmtotal total; |
730 | time_t uptime, halfuptime; | | 706 | time_t uptime, halfuptime; |
731 | size_t size; | | 707 | size_t size; |
732 | int pagesize = getpagesize(); | | 708 | int pagesize = getpagesize(); |
733 | int ovflw; | | 709 | int ovflw; |
734 | | | 710 | |
735 | uptime = getuptime(); | | 711 | uptime = getuptime(); |
736 | halfuptime = uptime / 2; | | 712 | halfuptime = uptime / 2; |
737 | (void)signal(SIGCONT, needhdr); | | 713 | (void)signal(SIGCONT, needhdr); |
738 | | | 714 | |
739 | if (memf != NULL) { | | 715 | if (memf != NULL) { |
740 | if (namelist[X_STATHZ].n_type != 0 && namelist[X_STATHZ].n_value != 0) | | 716 | if (namelist[X_STATHZ].n_type != 0 && namelist[X_STATHZ].n_value != 0) |
741 | kread(namelist, X_STATHZ, &hz, sizeof(hz)); | | 717 | kread(namelist, X_STATHZ, &hz, sizeof(hz)); |
742 | if (!hz) | | 718 | if (!hz) |
743 | kread(namelist, X_HZ, &hz, sizeof(hz)); | | 719 | kread(namelist, X_HZ, &hz, sizeof(hz)); |
744 | } else { | | 720 | } else { |
745 | struct clockinfo clockinfo; | | 721 | struct clockinfo clockinfo; |
746 | size = sizeof(clockinfo); | | 722 | size = sizeof(clockinfo); |
747 | if (sysctl(clockrate_mib, 2, &clockinfo, &size, NULL, 0) == -1) | | 723 | if (sysctl(clockrate_mib, 2, &clockinfo, &size, NULL, 0) == -1) |
748 | err(1, "sysctl kern.clockrate failed"); | | 724 | err(1, "sysctl kern.clockrate failed"); |
749 | hz = clockinfo.stathz; | | 725 | hz = clockinfo.stathz; |
750 | if (!hz) | | 726 | if (!hz) |
751 | hz = clockinfo.hz; | | 727 | hz = clockinfo.hz; |
752 | } | | 728 | } |
753 | | | 729 | |
754 | for (hdrcnt = 1;;) { | | 730 | for (hdrcnt = 1;;) { |
755 | if (!--hdrcnt) | | 731 | if (!--hdrcnt) |
756 | printhdr(); | | 732 | printhdr(); |
757 | /* Read new disk statistics */ | | 733 | /* Read new disk statistics */ |
758 | cpureadstats(); | | 734 | cpureadstats(); |
759 | drvreadstats(); | | 735 | drvreadstats(); |
760 | tkreadstats(); | | 736 | tkreadstats(); |
761 | if (memf != NULL) { | | 737 | if (memf != NULL) { |
762 | struct uvmexp uvmexp_kernel; | | 738 | struct uvmexp uvmexp_kernel; |
763 | /* | | 739 | /* |
764 | * XXX Can't do this if we're reading a crash | | 740 | * XXX Can't do this if we're reading a crash |
765 | * XXX dump because they're lazily-calculated. | | 741 | * XXX dump because they're lazily-calculated. |
766 | */ | | 742 | */ |
767 | warnx("Unable to get vmtotals from crash dump."); | | 743 | warnx("Unable to get vmtotals from crash dump."); |
768 | (void)memset(&total, 0, sizeof(total)); | | 744 | (void)memset(&total, 0, sizeof(total)); |
769 | kread(namelist, X_UVMEXP, &uvmexp_kernel, sizeof(uvmexp_kernel)); | | 745 | kread(namelist, X_UVMEXP, &uvmexp_kernel, sizeof(uvmexp_kernel)); |
770 | #define COPY(field) uvmexp.field = uvmexp_kernel.field | | 746 | #define COPY(field) uvmexp.field = uvmexp_kernel.field |
771 | COPY(pdreact); | | 747 | COPY(pdreact); |
772 | COPY(pageins); | | 748 | COPY(pageins); |
773 | COPY(pgswapout); | | 749 | COPY(pgswapout); |
774 | COPY(pdfreed); | | 750 | COPY(pdfreed); |
775 | COPY(pdscans); | | 751 | COPY(pdscans); |
776 | #undef COPY | | 752 | #undef COPY |
777 | } else { | | 753 | } else { |
778 | size = sizeof(total); | | 754 | size = sizeof(total); |
779 | if (sysctl(vmmeter_mib, __arraycount(vmmeter_mib), | | 755 | if (sysctl(vmmeter_mib, __arraycount(vmmeter_mib), |
780 | &total, &size, NULL, 0) == -1) { | | 756 | &total, &size, NULL, 0) == -1) { |
781 | warn("Can't get vmtotals"); | | 757 | warn("Can't get vmtotals"); |
782 | (void)memset(&total, 0, sizeof(total)); | | 758 | (void)memset(&total, 0, sizeof(total)); |
783 | } | | 759 | } |
784 | size = sizeof(uvmexp); | | 760 | size = sizeof(uvmexp); |
785 | if (sysctl(uvmexp2_mib, __arraycount(uvmexp2_mib), &uvmexp, | | 761 | if (sysctl(uvmexp2_mib, __arraycount(uvmexp2_mib), &uvmexp, |
786 | &size, NULL, 0) == -1) | | 762 | &size, NULL, 0) == -1) |
787 | warn("sysctl vm.uvmexp2 failed"); | | 763 | warn("sysctl vm.uvmexp2 failed"); |
788 | } | | 764 | } |
789 | cpucounters(&cpucounter); | | 765 | cpucounters(&cpucounter); |
790 | ovflw = 0; | | 766 | ovflw = 0; |
791 | PRWORD(ovflw, " %*d", 2, 1, total.t_rq - 1); | | 767 | PRWORD(ovflw, " %*d", 2, 1, total.t_rq - 1); |
792 | PRWORD(ovflw, " %*d", 2, 1, total.t_dw + total.t_pw); | | 768 | PRWORD(ovflw, " %*d", 2, 1, total.t_dw + total.t_pw); |
793 | #define pgtok(a) (long)((a) * ((uint32_t)pagesize >> 10)) | | 769 | #define pgtok(a) (long)((a) * ((uint32_t)pagesize >> 10)) |
794 | #define rate(x) (u_long)(((x) + halfuptime) / uptime) /* round */ | | 770 | #define rate(x) (u_long)(((x) + halfuptime) / uptime) /* round */ |
795 | PRWORD(ovflw, " %*ld", 9, 1, pgtok(total.t_avm)); | | 771 | PRWORD(ovflw, " %*ld", 9, 1, pgtok(total.t_avm)); |
796 | PRWORD(ovflw, " %*ld", 7, 1, pgtok(total.t_free)); | | 772 | PRWORD(ovflw, " %*ld", 7, 1, pgtok(total.t_free)); |
797 | PRWORD(ovflw, " %*ld", 5, 1, | | 773 | PRWORD(ovflw, " %*ld", 5, 1, |
798 | rate(cpucounter.nfault - ocpucounter.nfault)); | | 774 | rate(cpucounter.nfault - ocpucounter.nfault)); |
799 | PRWORD(ovflw, " %*ld", 4, 1, | | 775 | PRWORD(ovflw, " %*ld", 4, 1, |
800 | rate(uvmexp.pdreact - ouvmexp.pdreact)); | | 776 | rate(uvmexp.pdreact - ouvmexp.pdreact)); |
801 | PRWORD(ovflw, " %*ld", 4, 1, | | 777 | PRWORD(ovflw, " %*ld", 4, 1, |
802 | rate(uvmexp.pageins - ouvmexp.pageins)); | | 778 | rate(uvmexp.pageins - ouvmexp.pageins)); |
803 | PRWORD(ovflw, " %*ld", 5, 1, | | 779 | PRWORD(ovflw, " %*ld", 5, 1, |
804 | rate(uvmexp.pgswapout - ouvmexp.pgswapout)); | | 780 | rate(uvmexp.pgswapout - ouvmexp.pgswapout)); |
805 | PRWORD(ovflw, " %*ld", 5, 1, | | 781 | PRWORD(ovflw, " %*ld", 5, 1, |
806 | rate(uvmexp.pdfreed - ouvmexp.pdfreed)); | | 782 | rate(uvmexp.pdfreed - ouvmexp.pdfreed)); |
807 | PRWORD(ovflw, " %*ld", 6, 2, | | 783 | PRWORD(ovflw, " %*ld", 6, 2, |
808 | rate(uvmexp.pdscans - ouvmexp.pdscans)); | | 784 | rate(uvmexp.pdscans - ouvmexp.pdscans)); |
809 | drvstats(&ovflw); | | 785 | drvstats(&ovflw); |
810 | PRWORD(ovflw, " %*ld", 5, 1, | | 786 | PRWORD(ovflw, " %*ld", 5, 1, |
811 | rate(cpucounter.nintr - ocpucounter.nintr)); | | 787 | rate(cpucounter.nintr - ocpucounter.nintr)); |
812 | PRWORD(ovflw, " %*ld", 5, 1, | | 788 | PRWORD(ovflw, " %*ld", 5, 1, |
813 | rate(cpucounter.nsyscall - ocpucounter.nsyscall)); | | 789 | rate(cpucounter.nsyscall - ocpucounter.nsyscall)); |
814 | PRWORD(ovflw, " %*ld", 4, 1, | | 790 | PRWORD(ovflw, " %*ld", 4, 1, |
815 | rate(cpucounter.nswtch - ocpucounter.nswtch)); | | 791 | rate(cpucounter.nswtch - ocpucounter.nswtch)); |
816 | cpustats(&ovflw); | | 792 | cpustats(&ovflw); |
817 | (void)putchar('\n'); | | 793 | (void)putchar('\n'); |
818 | (void)fflush(stdout); | | 794 | (void)fflush(stdout); |
819 | if (reps >= 0 && --reps <= 0) | | 795 | if (reps >= 0 && --reps <= 0) |
820 | break; | | 796 | break; |
821 | ouvmexp = uvmexp; | | 797 | ouvmexp = uvmexp; |
822 | ocpucounter = cpucounter; | | 798 | ocpucounter = cpucounter; |
823 | uptime = interval->tv_sec; | | 799 | uptime = interval->tv_sec; |
824 | /* | | 800 | /* |
825 | * We round upward to avoid losing low-frequency events | | 801 | * We round upward to avoid losing low-frequency events |
826 | * (i.e., >= 1 per interval but < 1 per second). | | 802 | * (i.e., >= 1 per interval but < 1 per second). |
827 | */ | | 803 | */ |
828 | halfuptime = uptime == 1 ? 0 : (uptime + 1) / 2; | | 804 | halfuptime = uptime == 1 ? 0 : (uptime + 1) / 2; |
829 | (void)nanosleep(interval, NULL); | | 805 | (void)nanosleep(interval, NULL); |
830 | } | | 806 | } |
831 | } | | 807 | } |
832 | | | 808 | |
833 | void | | 809 | void |
834 | printhdr(void) | | 810 | printhdr(void) |
835 | { | | 811 | { |
836 | size_t i; | | 812 | size_t i; |
837 | | | 813 | |
838 | (void)printf(" procs memory page%*s", 23, ""); | | 814 | (void)printf(" procs memory page%*s", 23, ""); |
839 | if (ndrives > 0) | | 815 | if (ndrives > 0) |
840 | (void)printf("%s %*sfaults cpu\n", | | 816 | (void)printf("%s %*sfaults cpu\n", |
841 | ((ndrives > 1) ? "disks" : "disk"), | | 817 | ((ndrives > 1) ? "disks" : "disk"), |
842 | ((ndrives > 1) ? ndrives * 3 - 4 : 0), ""); | | 818 | ((ndrives > 1) ? ndrives * 3 - 4 : 0), ""); |
843 | else | | 819 | else |
844 | (void)printf("%*s faults cpu\n", | | 820 | (void)printf("%*s faults cpu\n", |
845 | ndrives * 3, ""); | | 821 | ndrives * 3, ""); |
846 | | | 822 | |
847 | (void)printf(" r b avm fre flt re pi po fr sr "); | | 823 | (void)printf(" r b avm fre flt re pi po fr sr "); |
848 | for (i = 0; i < ndrive; i++) | | 824 | for (i = 0; i < ndrive; i++) |
849 | if (drv_select[i]) | | 825 | if (drv_select[i]) |
850 | (void)printf("%c%c ", dr_name[i][0], | | 826 | (void)printf("%c%c ", dr_name[i][0], |
851 | dr_name[i][strlen(dr_name[i]) - 1]); | | 827 | dr_name[i][strlen(dr_name[i]) - 1]); |
852 | (void)printf(" in sy cs us sy id\n"); | | 828 | (void)printf(" in sy cs us sy id\n"); |
853 | hdrcnt = winlines - 2; | | 829 | hdrcnt = winlines - 2; |
854 | } | | 830 | } |
855 | | | 831 | |
856 | /* | | 832 | /* |
857 | * Force a header to be prepended to the next output. | | 833 | * Force a header to be prepended to the next output. |
858 | */ | | 834 | */ |
859 | void | | 835 | void |
860 | /*ARGSUSED*/ | | 836 | /*ARGSUSED*/ |
861 | needhdr(int dummy) | | 837 | needhdr(int dummy) |
862 | { | | 838 | { |
863 | | | 839 | |
864 | hdrcnt = 1; | | 840 | hdrcnt = 1; |
865 | } | | 841 | } |
866 | | | 842 | |
867 | long | | 843 | long |
868 | pct(u_long top, u_long bot) | | 844 | pct(u_long top, u_long bot) |
869 | { | | 845 | { |
870 | long ans; | | 846 | long ans; |
871 | | | 847 | |
872 | if (bot == 0) | | 848 | if (bot == 0) |
873 | return (0); | | 849 | return (0); |
874 | ans = (long)((quad_t)top * 100 / bot); | | 850 | ans = (long)((quad_t)top * 100 / bot); |
875 | return (ans); | | 851 | return (ans); |
876 | } | | 852 | } |
877 | | | 853 | |
878 | #define PCT(top, bot) (int)pct((u_long)(top), (u_long)(bot)) | | 854 | #define PCT(top, bot) (int)pct((u_long)(top), (u_long)(bot)) |
879 | | | 855 | |
880 | void | | 856 | void |
881 | dosum(void) | | 857 | dosum(void) |
882 | { | | 858 | { |
883 | struct nchstats nch_stats; | | 859 | struct nchstats nch_stats; |
884 | uint64_t nchtotal; | | 860 | uint64_t nchtotal; |
885 | size_t ssize; | | 861 | size_t ssize; |
886 | int active_kernel; | | 862 | int active_kernel; |
887 | struct cpu_counter cc; | | 863 | struct cpu_counter cc; |
888 | | | 864 | |
889 | /* | | 865 | /* |
890 | * The "active" and "inactive" variables | | 866 | * The "active" and "inactive" variables |
891 | * are now estimated by the kernel and sadly | | 867 | * are now estimated by the kernel and sadly |
892 | * can not easily be dug out of a crash dump. | | 868 | * can not easily be dug out of a crash dump. |
893 | */ | | 869 | */ |
894 | ssize = sizeof(uvmexp); | | 870 | ssize = sizeof(uvmexp); |
895 | memset(&uvmexp, 0, ssize); | | 871 | memset(&uvmexp, 0, ssize); |
896 | active_kernel = (memf == NULL); | | 872 | active_kernel = (memf == NULL); |
897 | if (active_kernel) { | | 873 | if (active_kernel) { |
898 | /* only on active kernel */ | | 874 | /* only on active kernel */ |
899 | if (sysctl(uvmexp2_mib, __arraycount(uvmexp2_mib), &uvmexp, | | 875 | if (sysctl(uvmexp2_mib, __arraycount(uvmexp2_mib), &uvmexp, |
900 | &ssize, NULL, 0) == -1) | | 876 | &ssize, NULL, 0) == -1) |
901 | warn("sysctl vm.uvmexp2 failed"); | | 877 | warn("sysctl vm.uvmexp2 failed"); |
902 | } else { | | 878 | } else { |
903 | struct uvmexp uvmexp_kernel; | | 879 | struct uvmexp uvmexp_kernel; |
904 | struct pool pool, *pp = &pool; | | 880 | struct pool pool, *pp = &pool; |
905 | struct pool_allocator pa; | | 881 | struct pool_allocator pa; |
906 | TAILQ_HEAD(,pool) pool_head; | | 882 | TAILQ_HEAD(,pool) pool_head; |
907 | void *addr; | | 883 | void *addr; |
908 | uint64_t bytes; | | 884 | uint64_t bytes; |
909 | | | 885 | |
910 | kread(namelist, X_UVMEXP, &uvmexp_kernel, sizeof(uvmexp_kernel)); | | 886 | kread(namelist, X_UVMEXP, &uvmexp_kernel, sizeof(uvmexp_kernel)); |
911 | #define COPY(field) uvmexp.field = uvmexp_kernel.field | | 887 | #define COPY(field) uvmexp.field = uvmexp_kernel.field |
912 | COPY(pagesize); | | 888 | COPY(pagesize); |
913 | COPY(ncolors); | | 889 | COPY(ncolors); |
914 | COPY(npages); | | 890 | COPY(npages); |
915 | COPY(free); | | 891 | COPY(free); |
916 | COPY(paging); | | 892 | COPY(paging); |
917 | COPY(wired); | | 893 | COPY(wired); |
918 | COPY(reserve_pagedaemon); | | 894 | COPY(reserve_pagedaemon); |
919 | COPY(reserve_kernel); | | 895 | COPY(reserve_kernel); |
920 | COPY(anonpages); | | 896 | COPY(anonpages); |
921 | COPY(filepages); | | 897 | COPY(filepages); |
922 | COPY(execpages); | | 898 | COPY(execpages); |
923 | COPY(freemin); | | 899 | COPY(freemin); |
924 | COPY(freetarg); | | 900 | COPY(freetarg); |
925 | COPY(wiredmax); | | 901 | COPY(wiredmax); |
926 | COPY(nswapdev); | | 902 | COPY(nswapdev); |
927 | COPY(swpages); | | 903 | COPY(swpages); |
928 | COPY(swpginuse); | | 904 | COPY(swpginuse); |
929 | COPY(nswget); | | 905 | COPY(nswget); |
930 | COPY(pageins); | | 906 | COPY(pageins); |
931 | COPY(pdpageouts); | | 907 | COPY(pdpageouts); |
932 | COPY(pgswapin); | | 908 | COPY(pgswapin); |
933 | COPY(pgswapout); | | 909 | COPY(pgswapout); |
934 | COPY(forks); | | 910 | COPY(forks); |
935 | COPY(forks_ppwait); | | 911 | COPY(forks_ppwait); |
936 | COPY(forks_sharevm); | | 912 | COPY(forks_sharevm); |
937 | COPY(colorhit); | | 913 | COPY(colorhit); |
938 | COPY(colormiss); | | 914 | COPY(colormiss); |
939 | COPY(cpuhit); | | 915 | COPY(cpuhit); |
940 | COPY(cpumiss); | | 916 | COPY(cpumiss); |
941 | COPY(fltnoram); | | 917 | COPY(fltnoram); |
942 | COPY(fltnoanon); | | 918 | COPY(fltnoanon); |
943 | COPY(fltpgwait); | | 919 | COPY(fltpgwait); |
944 | COPY(fltpgrele); | | 920 | COPY(fltpgrele); |
945 | COPY(fltrelck); | | 921 | COPY(fltrelck); |
946 | COPY(fltrelckok); | | 922 | COPY(fltrelckok); |
947 | COPY(fltanget); | | 923 | COPY(fltanget); |
948 | COPY(fltanretry); | | 924 | COPY(fltanretry); |
949 | COPY(fltamcopy); | | 925 | COPY(fltamcopy); |
950 | COPY(fltamcopy); | | 926 | COPY(fltamcopy); |
951 | COPY(fltnomap); | | 927 | COPY(fltnomap); |
952 | COPY(fltlget); | | 928 | COPY(fltlget); |
953 | COPY(fltget); | | 929 | COPY(fltget); |
954 | COPY(flt_anon); | | 930 | COPY(flt_anon); |
955 | COPY(flt_acow); | | 931 | COPY(flt_acow); |
956 | COPY(flt_obj); | | 932 | COPY(flt_obj); |
957 | COPY(flt_prcopy); | | 933 | COPY(flt_prcopy); |
958 | COPY(flt_przero); | | 934 | COPY(flt_przero); |
959 | COPY(pdwoke); | | 935 | COPY(pdwoke); |
960 | COPY(pdrevs); | | 936 | COPY(pdrevs); |
961 | COPY(pdfreed); | | 937 | COPY(pdfreed); |
962 | COPY(pdscans); | | 938 | COPY(pdscans); |
963 | COPY(pdanscan); | | 939 | COPY(pdanscan); |
964 | COPY(pdobscan); | | 940 | COPY(pdobscan); |
965 | COPY(pdreact); | | 941 | COPY(pdreact); |
966 | COPY(pdbusy); | | 942 | COPY(pdbusy); |
967 | COPY(pdpending); | | 943 | COPY(pdpending); |
968 | COPY(pddeact); | | 944 | COPY(pddeact); |
969 | COPY(bootpages); | | 945 | COPY(bootpages); |
970 | #undef COPY | | 946 | #undef COPY |
971 | kread(namelist, X_POOLHEAD, &pool_head, sizeof(pool_head)); | | 947 | kread(namelist, X_POOLHEAD, &pool_head, sizeof(pool_head)); |
972 | addr = TAILQ_FIRST(&pool_head); | | 948 | addr = TAILQ_FIRST(&pool_head); |
973 | uvmexp.poolpages = 0; | | 949 | uvmexp.poolpages = 0; |
974 | for (; addr != NULL; addr = TAILQ_NEXT(pp, pr_poollist)) { | | 950 | for (; addr != NULL; addr = TAILQ_NEXT(pp, pr_poollist)) { |
975 | deref_kptr(addr, pp, sizeof(*pp), "pool chain trashed"); | | 951 | deref_kptr(addr, pp, sizeof(*pp), "pool chain trashed"); |
976 | deref_kptr(pp->pr_alloc, &pa, sizeof(pa), | | 952 | deref_kptr(pp->pr_alloc, &pa, sizeof(pa), |
977 | "pool allocator trashed"); | | 953 | "pool allocator trashed"); |
978 | bytes = pp->pr_npages * pa.pa_pagesz; | | 954 | bytes = pp->pr_npages * pa.pa_pagesz; |
979 | if ((pp->pr_roflags & PR_RECURSIVE) != 0) | | 955 | if ((pp->pr_roflags & PR_RECURSIVE) != 0) |
980 | bytes -= (pp->pr_nout * pp->pr_size); | | 956 | bytes -= (pp->pr_nout * pp->pr_size); |
981 | uvmexp.poolpages += bytes / uvmexp.pagesize; | | 957 | uvmexp.poolpages += bytes / uvmexp.pagesize; |
982 | } | | 958 | } |
983 | } | | 959 | } |
984 | | | 960 | |
985 | | | 961 | |
986 | (void)printf("%9" PRIu64 " bytes per page\n", uvmexp.pagesize); | | 962 | (void)printf("%9" PRIu64 " bytes per page\n", uvmexp.pagesize); |
987 | | | 963 | |
988 | (void)printf("%9" PRIu64 " page color%s\n", | | 964 | (void)printf("%9" PRIu64 " page color%s\n", |
989 | uvmexp.ncolors, uvmexp.ncolors == 1 ? "" : "s"); | | 965 | uvmexp.ncolors, uvmexp.ncolors == 1 ? "" : "s"); |
990 | | | 966 | |
991 | (void)printf("%9" PRIu64 " pages managed\n", uvmexp.npages); | | 967 | (void)printf("%9" PRIu64 " pages managed\n", uvmexp.npages); |
992 | (void)printf("%9" PRIu64 " pages free\n", uvmexp.free); | | 968 | (void)printf("%9" PRIu64 " pages free\n", uvmexp.free); |
993 | if (active_kernel) { | | 969 | if (active_kernel) { |
994 | (void)printf("%9" PRIu64 " pages active\n", uvmexp.active); | | 970 | (void)printf("%9" PRIu64 " pages active\n", uvmexp.active); |
995 | (void)printf("%9" PRIu64 " pages inactive\n", uvmexp.inactive); | | 971 | (void)printf("%9" PRIu64 " pages inactive\n", uvmexp.inactive); |
996 | } | | 972 | } |
997 | (void)printf("%9" PRIu64 " pages paging\n", uvmexp.paging); | | 973 | (void)printf("%9" PRIu64 " pages paging\n", uvmexp.paging); |
998 | (void)printf("%9" PRIu64 " pages wired\n", uvmexp.wired); | | 974 | (void)printf("%9" PRIu64 " pages wired\n", uvmexp.wired); |
999 | (void)printf("%9" PRIu64 " reserve pagedaemon pages\n", | | 975 | (void)printf("%9" PRIu64 " reserve pagedaemon pages\n", |
1000 | uvmexp.reserve_pagedaemon); | | 976 | uvmexp.reserve_pagedaemon); |
1001 | (void)printf("%9" PRIu64 " reserve kernel pages\n", uvmexp.reserve_kernel); | | 977 | (void)printf("%9" PRIu64 " reserve kernel pages\n", uvmexp.reserve_kernel); |
1002 | (void)printf("%9" PRIu64 " boot kernel pages\n", uvmexp.bootpages); | | 978 | (void)printf("%9" PRIu64 " boot kernel pages\n", uvmexp.bootpages); |
1003 | (void)printf("%9" PRIu64 " kernel pool pages\n", uvmexp.poolpages); | | 979 | (void)printf("%9" PRIu64 " kernel pool pages\n", uvmexp.poolpages); |
1004 | (void)printf("%9" PRIu64 " anonymous pages\n", uvmexp.anonpages); | | 980 | (void)printf("%9" PRIu64 " anonymous pages\n", uvmexp.anonpages); |
1005 | (void)printf("%9" PRIu64 " cached file pages\n", uvmexp.filepages); | | 981 | (void)printf("%9" PRIu64 " cached file pages\n", uvmexp.filepages); |
1006 | (void)printf("%9" PRIu64 " cached executable pages\n", uvmexp.execpages); | | 982 | (void)printf("%9" PRIu64 " cached executable pages\n", uvmexp.execpages); |
1007 | | | 983 | |
1008 | (void)printf("%9" PRIu64 " minimum free pages\n", uvmexp.freemin); | | 984 | (void)printf("%9" PRIu64 " minimum free pages\n", uvmexp.freemin); |
1009 | (void)printf("%9" PRIu64 " target free pages\n", uvmexp.freetarg); | | 985 | (void)printf("%9" PRIu64 " target free pages\n", uvmexp.freetarg); |
1010 | (void)printf("%9" PRIu64 " maximum wired pages\n", uvmexp.wiredmax); | | 986 | (void)printf("%9" PRIu64 " maximum wired pages\n", uvmexp.wiredmax); |
1011 | | | 987 | |
1012 | (void)printf("%9" PRIu64 " swap devices\n", uvmexp.nswapdev); | | 988 | (void)printf("%9" PRIu64 " swap devices\n", uvmexp.nswapdev); |
1013 | (void)printf("%9" PRIu64 " swap pages\n", uvmexp.swpages); | | 989 | (void)printf("%9" PRIu64 " swap pages\n", uvmexp.swpages); |
1014 | (void)printf("%9" PRIu64 " swap pages in use\n", uvmexp.swpginuse); | | 990 | (void)printf("%9" PRIu64 " swap pages in use\n", uvmexp.swpginuse); |
1015 | (void)printf("%9" PRIu64 " swap allocations\n", uvmexp.nswget); | | 991 | (void)printf("%9" PRIu64 " swap allocations\n", uvmexp.nswget); |
1016 | | | 992 | |
1017 | cpucounters(&cc); | | 993 | cpucounters(&cc); |
1018 | | | 994 | |
1019 | (void)printf("%9" PRIu64 " total faults taken\n", cc.nfault); | | 995 | (void)printf("%9" PRIu64 " total faults taken\n", cc.nfault); |
1020 | (void)printf("%9" PRIu64 " traps\n", cc.ntrap); | | 996 | (void)printf("%9" PRIu64 " traps\n", cc.ntrap); |
1021 | (void)printf("%9" PRIu64 " device interrupts\n", cc.nintr); | | 997 | (void)printf("%9" PRIu64 " device interrupts\n", cc.nintr); |
1022 | (void)printf("%9" PRIu64 " CPU context switches\n", cc.nswtch); | | 998 | (void)printf("%9" PRIu64 " CPU context switches\n", cc.nswtch); |
1023 | (void)printf("%9" PRIu64 " software interrupts\n", cc.nsoft); | | 999 | (void)printf("%9" PRIu64 " software interrupts\n", cc.nsoft); |
1024 | (void)printf("%9" PRIu64 " system calls\n", cc.nsyscall); | | 1000 | (void)printf("%9" PRIu64 " system calls\n", cc.nsyscall); |
1025 | (void)printf("%9" PRIu64 " pagein requests\n", uvmexp.pageins); | | 1001 | (void)printf("%9" PRIu64 " pagein requests\n", uvmexp.pageins); |
1026 | (void)printf("%9" PRIu64 " pageout requests\n", uvmexp.pdpageouts); | | 1002 | (void)printf("%9" PRIu64 " pageout requests\n", uvmexp.pdpageouts); |
1027 | (void)printf("%9" PRIu64 " pages swapped in\n", uvmexp.pgswapin); | | 1003 | (void)printf("%9" PRIu64 " pages swapped in\n", uvmexp.pgswapin); |
1028 | (void)printf("%9" PRIu64 " pages swapped out\n", uvmexp.pgswapout); | | 1004 | (void)printf("%9" PRIu64 " pages swapped out\n", uvmexp.pgswapout); |
1029 | (void)printf("%9" PRIu64 " forks total\n", uvmexp.forks); | | 1005 | (void)printf("%9" PRIu64 " forks total\n", uvmexp.forks); |
1030 | (void)printf("%9" PRIu64 " forks blocked parent\n", uvmexp.forks_ppwait); | | 1006 | (void)printf("%9" PRIu64 " forks blocked parent\n", uvmexp.forks_ppwait); |
1031 | (void)printf("%9" PRIu64 " forks shared address space with parent\n", | | 1007 | (void)printf("%9" PRIu64 " forks shared address space with parent\n", |
1032 | uvmexp.forks_sharevm); | | 1008 | uvmexp.forks_sharevm); |
1033 | (void)printf("%9" PRIu64 " pagealloc desired color avail\n", | | 1009 | (void)printf("%9" PRIu64 " pagealloc desired color avail\n", |
1034 | uvmexp.colorhit); | | 1010 | uvmexp.colorhit); |
1035 | (void)printf("%9" PRIu64 " pagealloc desired color not avail\n", | | 1011 | (void)printf("%9" PRIu64 " pagealloc desired color not avail\n", |
1036 | uvmexp.colormiss); | | 1012 | uvmexp.colormiss); |
1037 | (void)printf("%9" PRIu64 " pagealloc local cpu avail\n", | | 1013 | (void)printf("%9" PRIu64 " pagealloc local cpu avail\n", |
1038 | uvmexp.cpuhit); | | 1014 | uvmexp.cpuhit); |
1039 | (void)printf("%9" PRIu64 " pagealloc local cpu not avail\n", | | 1015 | (void)printf("%9" PRIu64 " pagealloc local cpu not avail\n", |
1040 | uvmexp.cpumiss); | | 1016 | uvmexp.cpumiss); |
1041 | | | 1017 | |
1042 | (void)printf("%9" PRIu64 " faults with no memory\n", uvmexp.fltnoram); | | 1018 | (void)printf("%9" PRIu64 " faults with no memory\n", uvmexp.fltnoram); |
1043 | (void)printf("%9" PRIu64 " faults with no anons\n", uvmexp.fltnoanon); | | 1019 | (void)printf("%9" PRIu64 " faults with no anons\n", uvmexp.fltnoanon); |
1044 | (void)printf("%9" PRIu64 " faults had to wait on pages\n", uvmexp.fltpgwait); | | 1020 | (void)printf("%9" PRIu64 " faults had to wait on pages\n", uvmexp.fltpgwait); |
1045 | (void)printf("%9" PRIu64 " faults found released page\n", uvmexp.fltpgrele); | | 1021 | (void)printf("%9" PRIu64 " faults found released page\n", uvmexp.fltpgrele); |
1046 | (void)printf("%9" PRIu64 " faults relock (%" PRIu64 " ok)\n", uvmexp.fltrelck, | | 1022 | (void)printf("%9" PRIu64 " faults relock (%" PRIu64 " ok)\n", uvmexp.fltrelck, |
1047 | uvmexp.fltrelckok); | | 1023 | uvmexp.fltrelckok); |
1048 | (void)printf("%9" PRIu64 " anon page faults\n", uvmexp.fltanget); | | 1024 | (void)printf("%9" PRIu64 " anon page faults\n", uvmexp.fltanget); |
1049 | (void)printf("%9" PRIu64 " anon retry faults\n", uvmexp.fltanretry); | | 1025 | (void)printf("%9" PRIu64 " anon retry faults\n", uvmexp.fltanretry); |
1050 | (void)printf("%9" PRIu64 " amap copy faults\n", uvmexp.fltamcopy); | | 1026 | (void)printf("%9" PRIu64 " amap copy faults\n", uvmexp.fltamcopy); |
1051 | (void)printf("%9" PRIu64 " neighbour anon page faults\n", uvmexp.fltnamap); | | 1027 | (void)printf("%9" PRIu64 " neighbour anon page faults\n", uvmexp.fltnamap); |
1052 | (void)printf("%9" PRIu64 " neighbour object page faults\n", uvmexp.fltnomap); | | 1028 | (void)printf("%9" PRIu64 " neighbour object page faults\n", uvmexp.fltnomap); |
1053 | (void)printf("%9" PRIu64 " locked pager get faults\n", uvmexp.fltlget); | | 1029 | (void)printf("%9" PRIu64 " locked pager get faults\n", uvmexp.fltlget); |
1054 | (void)printf("%9" PRIu64 " unlocked pager get faults\n", uvmexp.fltget); | | 1030 | (void)printf("%9" PRIu64 " unlocked pager get faults\n", uvmexp.fltget); |
1055 | (void)printf("%9" PRIu64 " anon faults\n", uvmexp.flt_anon); | | 1031 | (void)printf("%9" PRIu64 " anon faults\n", uvmexp.flt_anon); |
1056 | (void)printf("%9" PRIu64 " anon copy on write faults\n", uvmexp.flt_acow); | | 1032 | (void)printf("%9" PRIu64 " anon copy on write faults\n", uvmexp.flt_acow); |
1057 | (void)printf("%9" PRIu64 " object faults\n", uvmexp.flt_obj); | | 1033 | (void)printf("%9" PRIu64 " object faults\n", uvmexp.flt_obj); |
1058 | (void)printf("%9" PRIu64 " promote copy faults\n", uvmexp.flt_prcopy); | | 1034 | (void)printf("%9" PRIu64 " promote copy faults\n", uvmexp.flt_prcopy); |
1059 | (void)printf("%9" PRIu64 " promote zero fill faults\n", uvmexp.flt_przero); | | 1035 | (void)printf("%9" PRIu64 " promote zero fill faults\n", uvmexp.flt_przero); |
1060 | (void)printf("%9" PRIu64 " faults upgraded lock\n", | | 1036 | (void)printf("%9" PRIu64 " faults upgraded lock\n", |
1061 | uvmexp.fltup); | | 1037 | uvmexp.fltup); |
1062 | (void)printf("%9" PRIu64 " faults couldn't upgrade lock\n", | | 1038 | (void)printf("%9" PRIu64 " faults couldn't upgrade lock\n", |
1063 | uvmexp.fltnoup); | | 1039 | uvmexp.fltnoup); |
1064 | | | 1040 | |
1065 | (void)printf("%9" PRIu64 " times daemon wokeup\n",uvmexp.pdwoke); | | 1041 | (void)printf("%9" PRIu64 " times daemon wokeup\n",uvmexp.pdwoke); |
1066 | (void)printf("%9" PRIu64 " revolutions of the clock hand\n", uvmexp.pdrevs); | | 1042 | (void)printf("%9" PRIu64 " revolutions of the clock hand\n", uvmexp.pdrevs); |
1067 | (void)printf("%9" PRIu64 " pages freed by daemon\n", uvmexp.pdfreed); | | 1043 | (void)printf("%9" PRIu64 " pages freed by daemon\n", uvmexp.pdfreed); |
1068 | (void)printf("%9" PRIu64 " pages scanned by daemon\n", uvmexp.pdscans); | | 1044 | (void)printf("%9" PRIu64 " pages scanned by daemon\n", uvmexp.pdscans); |
1069 | (void)printf("%9" PRIu64 " anonymous pages scanned by daemon\n", | | 1045 | (void)printf("%9" PRIu64 " anonymous pages scanned by daemon\n", |
1070 | uvmexp.pdanscan); | | 1046 | uvmexp.pdanscan); |
1071 | (void)printf("%9" PRIu64 " object pages scanned by daemon\n", uvmexp.pdobscan); | | 1047 | (void)printf("%9" PRIu64 " object pages scanned by daemon\n", uvmexp.pdobscan); |
1072 | (void)printf("%9" PRIu64 " pages reactivated\n", uvmexp.pdreact); | | 1048 | (void)printf("%9" PRIu64 " pages reactivated\n", uvmexp.pdreact); |
1073 | (void)printf("%9" PRIu64 " pages found busy by daemon\n", uvmexp.pdbusy); | | 1049 | (void)printf("%9" PRIu64 " pages found busy by daemon\n", uvmexp.pdbusy); |
1074 | (void)printf("%9" PRIu64 " total pending pageouts\n", uvmexp.pdpending); | | 1050 | (void)printf("%9" PRIu64 " total pending pageouts\n", uvmexp.pdpending); |
1075 | (void)printf("%9" PRIu64 " pages deactivated\n", uvmexp.pddeact); | | 1051 | (void)printf("%9" PRIu64 " pages deactivated\n", uvmexp.pddeact); |
1076 | (void)printf("%9" PRIu64 " per-cpu stats synced\n", uvmexp.countsyncall); | | 1052 | (void)printf("%9" PRIu64 " per-cpu stats synced\n", uvmexp.countsyncall); |
1077 | (void)printf("%9" PRIu64 " anon pages possibly dirty\n", uvmexp.anonunknown); | | 1053 | (void)printf("%9" PRIu64 " anon pages possibly dirty\n", uvmexp.anonunknown); |
1078 | (void)printf("%9" PRIu64 " anon pages dirty\n", uvmexp.anondirty); | | 1054 | (void)printf("%9" PRIu64 " anon pages dirty\n", uvmexp.anondirty); |
1079 | (void)printf("%9" PRIu64 " anon pages clean\n", uvmexp.anonclean); | | 1055 | (void)printf("%9" PRIu64 " anon pages clean\n", uvmexp.anonclean); |
1080 | (void)printf("%9" PRIu64 " file pages possibly dirty\n", uvmexp.fileunknown); | | 1056 | (void)printf("%9" PRIu64 " file pages possibly dirty\n", uvmexp.fileunknown); |
1081 | (void)printf("%9" PRIu64 " file pages dirty\n", uvmexp.filedirty); | | 1057 | (void)printf("%9" PRIu64 " file pages dirty\n", uvmexp.filedirty); |
1082 | (void)printf("%9" PRIu64 " file pages clean\n", uvmexp.fileclean); | | 1058 | (void)printf("%9" PRIu64 " file pages clean\n", uvmexp.fileclean); |
1083 | | | 1059 | |
1084 | if (active_kernel) { | | 1060 | if (active_kernel) { |
1085 | ssize = sizeof(nch_stats); | | 1061 | ssize = sizeof(nch_stats); |
1086 | if (sysctlbyname("vfs.namecache_stats", &nch_stats, &ssize, | | 1062 | if (sysctlbyname("vfs.namecache_stats", &nch_stats, &ssize, |
1087 | NULL, 0)) { | | 1063 | NULL, 0)) { |
1088 | warn("vfs.namecache_stats failed"); | | 1064 | warn("vfs.namecache_stats failed"); |
1089 | memset(&nch_stats, 0, sizeof(nch_stats)); | | 1065 | memset(&nch_stats, 0, sizeof(nch_stats)); |
1090 | } | | 1066 | } |
1091 | } else { | | 1067 | } else { |
1092 | kread(namelist, X_NCHSTATS, &nch_stats, sizeof(nch_stats)); | | 1068 | kread(namelist, X_NCHSTATS, &nch_stats, sizeof(nch_stats)); |
1093 | } | | 1069 | } |
1094 | | | 1070 | |
1095 | nchtotal = nch_stats.ncs_goodhits + nch_stats.ncs_neghits + | | 1071 | nchtotal = nch_stats.ncs_goodhits + nch_stats.ncs_neghits + |
1096 | nch_stats.ncs_badhits + nch_stats.ncs_falsehits + | | 1072 | nch_stats.ncs_badhits + nch_stats.ncs_falsehits + |
1097 | nch_stats.ncs_miss + nch_stats.ncs_long; | | 1073 | nch_stats.ncs_miss + nch_stats.ncs_long; |
1098 | (void)printf("%9" PRIu64 " total name lookups\n", nchtotal); | | 1074 | (void)printf("%9" PRIu64 " total name lookups\n", nchtotal); |
1099 | (void)printf("%9" PRIu64 " good hits\n", nch_stats.ncs_goodhits); | | 1075 | (void)printf("%9" PRIu64 " good hits\n", nch_stats.ncs_goodhits); |
1100 | (void)printf("%9" PRIu64 " negative hits\n", nch_stats.ncs_neghits); | | 1076 | (void)printf("%9" PRIu64 " negative hits\n", nch_stats.ncs_neghits); |
1101 | (void)printf("%9" PRIu64 " bad hits\n", nch_stats.ncs_badhits); | | 1077 | (void)printf("%9" PRIu64 " bad hits\n", nch_stats.ncs_badhits); |
1102 | (void)printf("%9" PRIu64 " false hits\n", nch_stats.ncs_falsehits); | | 1078 | (void)printf("%9" PRIu64 " false hits\n", nch_stats.ncs_falsehits); |
1103 | (void)printf("%9" PRIu64 " miss\n", nch_stats.ncs_miss); | | 1079 | (void)printf("%9" PRIu64 " miss\n", nch_stats.ncs_miss); |
1104 | (void)printf("%9" PRIu64 " too long\n", nch_stats.ncs_long); | | 1080 | (void)printf("%9" PRIu64 " too long\n", nch_stats.ncs_long); |
1105 | (void)printf("%9" PRIu64 " pass2 hits\n", nch_stats.ncs_pass2); | | 1081 | (void)printf("%9" PRIu64 " pass2 hits\n", nch_stats.ncs_pass2); |
1106 | (void)printf("%9" PRIu64 " 2passes\n", nch_stats.ncs_2passes); | | 1082 | (void)printf("%9" PRIu64 " 2passes\n", nch_stats.ncs_2passes); |
1107 | (void)printf("%9" PRIu64 " reverse hits\n", nch_stats.ncs_revhits); | | 1083 | (void)printf("%9" PRIu64 " reverse hits\n", nch_stats.ncs_revhits); |
1108 | (void)printf("%9" PRIu64 " reverse miss\n", nch_stats.ncs_revmiss); | | 1084 | (void)printf("%9" PRIu64 " reverse miss\n", nch_stats.ncs_revmiss); |
1109 | (void)printf("%9" PRIu64 " access denied\n", nch_stats.ncs_denied); | | 1085 | (void)printf("%9" PRIu64 " access denied\n", nch_stats.ncs_denied); |
1110 | (void)printf( | | 1086 | (void)printf( |
1111 | "%9s cache hits (%d%% pos + %d%% neg) system %d%% per-process\n", | | 1087 | "%9s cache hits (%d%% pos + %d%% neg) system %d%% per-process\n", |
1112 | "", PCT(nch_stats.ncs_goodhits, nchtotal), | | 1088 | "", PCT(nch_stats.ncs_goodhits, nchtotal), |
1113 | PCT(nch_stats.ncs_neghits, nchtotal), | | 1089 | PCT(nch_stats.ncs_neghits, nchtotal), |
1114 | PCT(nch_stats.ncs_pass2, nchtotal)); | | 1090 | PCT(nch_stats.ncs_pass2, nchtotal)); |
1115 | (void)printf("%9s deletions %d%%, falsehits %d%%, toolong %d%%\n", "", | | 1091 | (void)printf("%9s deletions %d%%, falsehits %d%%, toolong %d%%\n", "", |
1116 | PCT(nch_stats.ncs_badhits, nchtotal), | | 1092 | PCT(nch_stats.ncs_badhits, nchtotal), |
1117 | PCT(nch_stats.ncs_falsehits, nchtotal), | | 1093 | PCT(nch_stats.ncs_falsehits, nchtotal), |
1118 | PCT(nch_stats.ncs_long, nchtotal)); | | 1094 | PCT(nch_stats.ncs_long, nchtotal)); |
1119 | } | | 1095 | } |
1120 | | | 1096 | |
1121 | void | | 1097 | void |
1122 | doforkst(void) | | 1098 | doforkst(void) |
1123 | { | | 1099 | { |
1124 | if (memf != NULL) { | | 1100 | if (memf != NULL) { |
1125 | struct uvmexp uvmexp_kernel; | | 1101 | struct uvmexp uvmexp_kernel; |
1126 | kread(namelist, X_UVMEXP, &uvmexp_kernel, sizeof(uvmexp_kernel)); | | 1102 | kread(namelist, X_UVMEXP, &uvmexp_kernel, sizeof(uvmexp_kernel)); |
1127 | #define COPY(field) uvmexp.field = uvmexp_kernel.field | | 1103 | #define COPY(field) uvmexp.field = uvmexp_kernel.field |
1128 | COPY(forks); | | 1104 | COPY(forks); |
1129 | COPY(forks_ppwait); | | 1105 | COPY(forks_ppwait); |
1130 | COPY(forks_sharevm); | | 1106 | COPY(forks_sharevm); |
1131 | #undef COPY | | 1107 | #undef COPY |
1132 | } else { | | 1108 | } else { |
1133 | size_t size = sizeof(uvmexp); | | 1109 | size_t size = sizeof(uvmexp); |
1134 | if (sysctl(uvmexp2_mib, __arraycount(uvmexp2_mib), &uvmexp, | | 1110 | if (sysctl(uvmexp2_mib, __arraycount(uvmexp2_mib), &uvmexp, |
1135 | &size, NULL, 0) == -1) | | 1111 | &size, NULL, 0) == -1) |
1136 | warn("sysctl vm.uvmexp2 failed"); | | 1112 | warn("sysctl vm.uvmexp2 failed"); |
1137 | } | | 1113 | } |
1138 | | | 1114 | |
1139 | (void)printf("%" PRIu64 " forks total\n", uvmexp.forks); | | 1115 | (void)printf("%" PRIu64 " forks total\n", uvmexp.forks); |
1140 | (void)printf("%" PRIu64 " forks blocked parent\n", uvmexp.forks_ppwait); | | 1116 | (void)printf("%" PRIu64 " forks blocked parent\n", uvmexp.forks_ppwait); |
1141 | (void)printf("%" PRIu64 " forks shared address space with parent\n", | | 1117 | (void)printf("%" PRIu64 " forks shared address space with parent\n", |
1142 | uvmexp.forks_sharevm); | | 1118 | uvmexp.forks_sharevm); |
1143 | } | | 1119 | } |
1144 | | | 1120 | |
1145 | void | | 1121 | void |
1146 | drvstats(int *ovflwp) | | 1122 | drvstats(int *ovflwp) |
1147 | { | | 1123 | { |
1148 | size_t dn; | | 1124 | size_t dn; |
1149 | double dtime; | | 1125 | double dtime; |
1150 | int ovflw = *ovflwp; | | 1126 | int ovflw = *ovflwp; |
1151 | | | 1127 | |
1152 | /* Calculate disk stat deltas. */ | | 1128 | /* Calculate disk stat deltas. */ |
1153 | cpuswap(); | | 1129 | cpuswap(); |
1154 | drvswap(); | | 1130 | drvswap(); |
1155 | tkswap(); | | 1131 | tkswap(); |
1156 | | | 1132 | |
1157 | for (dn = 0; dn < ndrive; ++dn) { | | 1133 | for (dn = 0; dn < ndrive; ++dn) { |
1158 | /* elapsed time for disk stats */ | | 1134 | /* elapsed time for disk stats */ |
1159 | dtime = cur.cp_etime; | | 1135 | dtime = cur.cp_etime; |
1160 | if (cur.timestamp[dn].tv_sec || cur.timestamp[dn].tv_usec) { | | 1136 | if (cur.timestamp[dn].tv_sec || cur.timestamp[dn].tv_usec) { |
1161 | dtime = (double)cur.timestamp[dn].tv_sec + | | 1137 | dtime = (double)cur.timestamp[dn].tv_sec + |
1162 | ((double)cur.timestamp[dn].tv_usec / (double)1000000); | | 1138 | ((double)cur.timestamp[dn].tv_usec / (double)1000000); |
1163 | } | | 1139 | } |
1164 | | | 1140 | |
1165 | if (!drv_select[dn]) | | 1141 | if (!drv_select[dn]) |
1166 | continue; | | 1142 | continue; |
1167 | PRWORD(ovflw, " %*.0f", 3, 1, | | 1143 | PRWORD(ovflw, " %*.0f", 3, 1, |
1168 | (cur.rxfer[dn] + cur.wxfer[dn]) / dtime); | | 1144 | (cur.rxfer[dn] + cur.wxfer[dn]) / dtime); |
1169 | } | | 1145 | } |
1170 | *ovflwp = ovflw; | | 1146 | *ovflwp = ovflw; |
1171 | } | | 1147 | } |
1172 | | | 1148 | |
1173 | void | | 1149 | void |
1174 | cpucounters(struct cpu_counter *cc) | | 1150 | cpucounters(struct cpu_counter *cc) |
1175 | { | | 1151 | { |
1176 | static struct cpu_info **cpu_infos; | | 1152 | static struct cpu_info **cpu_infos; |
1177 | static int initialised; | | 1153 | static int initialised; |
1178 | struct cpu_info **slot; | | 1154 | struct cpu_info **slot; |
1179 | | | 1155 | |
1180 | if (memf == NULL) { | | 1156 | if (memf == NULL) { |
1181 | cc->nintr = uvmexp.intrs; | | 1157 | cc->nintr = uvmexp.intrs; |
1182 | cc->nsyscall = uvmexp.syscalls; | | 1158 | cc->nsyscall = uvmexp.syscalls; |
1183 | cc->nswtch = uvmexp.swtch; | | 1159 | cc->nswtch = uvmexp.swtch; |
1184 | cc->nfault = uvmexp.faults; | | 1160 | cc->nfault = uvmexp.faults; |
1185 | cc->ntrap = uvmexp.traps; | | 1161 | cc->ntrap = uvmexp.traps; |
1186 | cc->nsoft = uvmexp.softs; | | 1162 | cc->nsoft = uvmexp.softs; |
1187 | return; | | 1163 | return; |
1188 | } | | 1164 | } |
1189 | | | 1165 | |
1190 | if (!initialised) { | | 1166 | if (!initialised) { |
1191 | kread(namelist, X_CPU_INFOS, &cpu_infos, sizeof(cpu_infos)); | | 1167 | kread(namelist, X_CPU_INFOS, &cpu_infos, sizeof(cpu_infos)); |
1192 | initialised = 1; | | 1168 | initialised = 1; |
1193 | } | | 1169 | } |
1194 | | | 1170 | |
1195 | slot = cpu_infos; | | 1171 | slot = cpu_infos; |
1196 | | | 1172 | |
1197 | memset(cc, 0, sizeof(*cc)); | | 1173 | memset(cc, 0, sizeof(*cc)); |
1198 | | | 1174 | |
1199 | for (;;) { | | 1175 | for (;;) { |
1200 | struct cpu_info tci, *ci = NULL; | | 1176 | struct cpu_info tci, *ci = NULL; |
1201 | | | 1177 | |
1202 | deref_kptr(slot++, &ci, sizeof(ci), "CPU array trashed"); | | 1178 | deref_kptr(slot++, &ci, sizeof(ci), "CPU array trashed"); |
1203 | if (!ci) { | | 1179 | if (!ci) { |
1204 | break; | | 1180 | break; |
1205 | } | | 1181 | } |
1206 | | | 1182 | |
1207 | if ((size_t)kvm_read(kd, (u_long)ci, &tci, sizeof(tci)) | | 1183 | if ((size_t)kvm_read(kd, (u_long)ci, &tci, sizeof(tci)) |
1208 | != sizeof(tci)) { | | 1184 | != sizeof(tci)) { |
1209 | warnx("Can't read cpu info from %p (%s)", | | 1185 | warnx("Can't read cpu info from %p (%s)", |
1210 | ci, kvm_geterr(kd)); | | 1186 | ci, kvm_geterr(kd)); |
1211 | memset(cc, 0, sizeof(*cc)); | | 1187 | memset(cc, 0, sizeof(*cc)); |
1212 | return; | | 1188 | return; |
1213 | } | | 1189 | } |
1214 | cc->nintr += tci.ci_data.cpu_nintr; | | 1190 | cc->nintr += tci.ci_data.cpu_nintr; |
1215 | cc->nsyscall += tci.ci_data.cpu_nsyscall; | | 1191 | cc->nsyscall += tci.ci_data.cpu_nsyscall; |
1216 | cc->nswtch = tci.ci_data.cpu_nswtch; | | 1192 | cc->nswtch = tci.ci_data.cpu_nswtch; |
1217 | cc->nfault = tci.ci_data.cpu_nfault; | | 1193 | cc->nfault = tci.ci_data.cpu_nfault; |
1218 | cc->ntrap = tci.ci_data.cpu_ntrap; | | 1194 | cc->ntrap = tci.ci_data.cpu_ntrap; |
1219 | cc->nsoft = tci.ci_data.cpu_nsoft; | | 1195 | cc->nsoft = tci.ci_data.cpu_nsoft; |
1220 | } | | 1196 | } |
1221 | } | | 1197 | } |
1222 | | | 1198 | |
1223 | void | | 1199 | void |
1224 | cpustats(int *ovflwp) | | 1200 | cpustats(int *ovflwp) |
1225 | { | | 1201 | { |
1226 | int state; | | 1202 | int state; |
1227 | double pcnt, total; | | 1203 | double pcnt, total; |
1228 | double stat_us, stat_sy, stat_id; | | 1204 | double stat_us, stat_sy, stat_id; |
1229 | int ovflw = *ovflwp; | | 1205 | int ovflw = *ovflwp; |
1230 | | | 1206 | |
1231 | total = 0; | | 1207 | total = 0; |
1232 | for (state = 0; state < CPUSTATES; ++state) | | 1208 | for (state = 0; state < CPUSTATES; ++state) |
1233 | total += cur.cp_time[state]; | | 1209 | total += cur.cp_time[state]; |
1234 | if (total) | | 1210 | if (total) |
1235 | pcnt = 100 / total; | | 1211 | pcnt = 100 / total; |
1236 | else | | 1212 | else |
1237 | pcnt = 0; | | 1213 | pcnt = 0; |
1238 | stat_us = (cur.cp_time[CP_USER] + cur.cp_time[CP_NICE]) * pcnt; | | 1214 | stat_us = (cur.cp_time[CP_USER] + cur.cp_time[CP_NICE]) * pcnt; |
1239 | stat_sy = (cur.cp_time[CP_SYS] + cur.cp_time[CP_INTR]) * pcnt; | | 1215 | stat_sy = (cur.cp_time[CP_SYS] + cur.cp_time[CP_INTR]) * pcnt; |
1240 | stat_id = cur.cp_time[CP_IDLE] * pcnt; | | 1216 | stat_id = cur.cp_time[CP_IDLE] * pcnt; |
1241 | PRWORD(ovflw, " %*.0f", ((stat_sy >= 100) ? 2 : 3), 1, stat_us); | | 1217 | PRWORD(ovflw, " %*.0f", ((stat_sy >= 100) ? 2 : 3), 1, stat_us); |
1242 | PRWORD(ovflw, " %*.0f", ((stat_us >= 100 || stat_id >= 100) ? 2 : 3), 1, | | 1218 | PRWORD(ovflw, " %*.0f", ((stat_us >= 100 || stat_id >= 100) ? 2 : 3), 1, |
1243 | stat_sy); | | 1219 | stat_sy); |
1244 | PRWORD(ovflw, " %*.0f", 3, 1, stat_id); | | 1220 | PRWORD(ovflw, " %*.0f", 3, 1, stat_id); |
1245 | *ovflwp = ovflw; | | 1221 | *ovflwp = ovflw; |
1246 | } | | 1222 | } |
1247 | | | 1223 | |
1248 | void | | 1224 | void |
1249 | dointr(int verbose) | | 1225 | dointr(int verbose) |
1250 | { | | 1226 | { |
1251 | unsigned long *intrcnt, *ointrcnt; | | 1227 | unsigned long *intrcnt, *ointrcnt; |
1252 | unsigned long long inttotal, uptime; | | 1228 | unsigned long long inttotal, uptime; |
1253 | int nintr, inamlen; | | 1229 | int nintr, inamlen; |
1254 | char *intrname, *ointrname; | | 1230 | char *intrname, *ointrname; |
1255 | | | 1231 | |
1256 | if (memf == NULL) { | | 1232 | if (memf == NULL) { |
1257 | doevcnt(verbose, EVCNT_TYPE_INTR); | | 1233 | doevcnt(verbose, EVCNT_TYPE_INTR); |
1258 | return; | | 1234 | return; |
1259 | } | | 1235 | } |
1260 | | | 1236 | |
1261 | inttotal = 0; | | 1237 | inttotal = 0; |
1262 | uptime = getuptime(); | | 1238 | uptime = getuptime(); |
1263 | nintr = intrnl[X_EINTRCNT].n_value - intrnl[X_INTRCNT].n_value; | | 1239 | nintr = intrnl[X_EINTRCNT].n_value - intrnl[X_INTRCNT].n_value; |
1264 | inamlen = intrnl[X_EINTRNAMES].n_value - intrnl[X_INTRNAMES].n_value; | | 1240 | inamlen = intrnl[X_EINTRNAMES].n_value - intrnl[X_INTRNAMES].n_value; |
1265 | if (nintr != 0 && inamlen != 0) { | | 1241 | if (nintr != 0 && inamlen != 0) { |
1266 | (void)printf("%-34s %16s %8s\n", "interrupt", "total", "rate"); | | 1242 | (void)printf("%-34s %16s %8s\n", "interrupt", "total", "rate"); |
1267 | | | 1243 | |
1268 | ointrcnt = intrcnt = malloc((size_t)nintr); | | 1244 | ointrcnt = intrcnt = malloc((size_t)nintr); |
1269 | ointrname = intrname = malloc((size_t)inamlen); | | 1245 | ointrname = intrname = malloc((size_t)inamlen); |
1270 | if (intrcnt == NULL || intrname == NULL) | | 1246 | if (intrcnt == NULL || intrname == NULL) |
1271 | errx(1, "%s", ""); | | 1247 | errx(1, "%s", ""); |
1272 | kread(intrnl, X_INTRCNT, intrcnt, (size_t)nintr); | | 1248 | kread(intrnl, X_INTRCNT, intrcnt, (size_t)nintr); |
1273 | kread(intrnl, X_INTRNAMES, intrname, (size_t)inamlen); | | 1249 | kread(intrnl, X_INTRNAMES, intrname, (size_t)inamlen); |
1274 | nintr /= sizeof(long); | | 1250 | nintr /= sizeof(long); |
1275 | while (--nintr >= 0) { | | 1251 | while (--nintr >= 0) { |
1276 | if (*intrcnt || verbose) | | 1252 | if (*intrcnt || verbose) |
1277 | (void)printf("%-34s %16llu %8llu\n", intrname, | | 1253 | (void)printf("%-34s %16llu %8llu\n", intrname, |
1278 | (unsigned long long)*intrcnt, | | 1254 | (unsigned long long)*intrcnt, |
1279 | (unsigned long long) | | 1255 | (unsigned long long) |
1280 | (*intrcnt / uptime)); | | 1256 | (*intrcnt / uptime)); |
1281 | intrname += strlen(intrname) + 1; | | 1257 | intrname += strlen(intrname) + 1; |
1282 | inttotal += *intrcnt++; | | 1258 | inttotal += *intrcnt++; |
1283 | } | | 1259 | } |
1284 | free(ointrcnt); | | 1260 | free(ointrcnt); |
1285 | free(ointrname); | | 1261 | free(ointrname); |
1286 | } | | 1262 | } |
1287 | | | 1263 | |
1288 | doevcnt(verbose, EVCNT_TYPE_INTR); | | 1264 | doevcnt(verbose, EVCNT_TYPE_INTR); |
1289 | } | | 1265 | } |
1290 | | | 1266 | |
1291 | void | | 1267 | void |
1292 | doevcnt(int verbose, int type) | | 1268 | doevcnt(int verbose, int type) |
1293 | { | | 1269 | { |
1294 | static const char * const evtypes [] = { "misc", "intr", "trap" }; | | 1270 | static const char * const evtypes [] = { "misc", "intr", "trap" }; |
1295 | uint64_t counttotal, uptime; | | 1271 | uint64_t counttotal, uptime; |
1296 | struct evcntlist allevents; | | 1272 | struct evcntlist allevents; |
1297 | struct evcnt evcnt, *evptr; | | 1273 | struct evcnt evcnt, *evptr; |
1298 | size_t evlen_max, total_max, rate_max; | | 1274 | size_t evlen_max, total_max, rate_max; |
1299 | char evgroup[EVCNT_STRING_MAX], evname[EVCNT_STRING_MAX]; | | 1275 | char evgroup[EVCNT_STRING_MAX], evname[EVCNT_STRING_MAX]; |
1300 | | | 1276 | |
1301 | counttotal = 0; | | 1277 | counttotal = 0; |
1302 | uptime = getuptime(); | | 1278 | uptime = getuptime(); |
1303 | | | 1279 | |
1304 | if (memf == NULL) do { | | 1280 | if (memf == NULL) do { |
1305 | const int mib[4] = { CTL_KERN, KERN_EVCNT, type, | | 1281 | const int mib[4] = { CTL_KERN, KERN_EVCNT, type, |
1306 | verbose ? KERN_EVCNT_COUNT_ANY : KERN_EVCNT_COUNT_NONZERO }; | | 1282 | verbose ? KERN_EVCNT_COUNT_ANY : KERN_EVCNT_COUNT_NONZERO }; |
1307 | size_t buflen0, buflen = 0; | | 1283 | size_t buflen0, buflen = 0; |
1308 | void *buf0, *buf = NULL; | | 1284 | void *buf0, *buf = NULL; |
1309 | const struct evcnt_sysctl *evs, *last_evs; | | 1285 | const struct evcnt_sysctl *evs, *last_evs; |
1310 | for (;;) { | | 1286 | for (;;) { |
1311 | size_t newlen; | | 1287 | size_t newlen; |
1312 | int error; | | 1288 | int error; |
1313 | if (buflen) | | 1289 | if (buflen) |
1314 | buf = malloc(buflen); | | 1290 | buf = malloc(buflen); |
1315 | error = sysctl(mib, __arraycount(mib), | | 1291 | error = sysctl(mib, __arraycount(mib), |
1316 | buf, &newlen, NULL, 0); | | 1292 | buf, &newlen, NULL, 0); |
1317 | if (error) { | | 1293 | if (error) { |
1318 | err(1, "kern.evcnt"); | | 1294 | err(1, "kern.evcnt"); |
1319 | if (buf) | | 1295 | if (buf) |
1320 | free(buf); | | 1296 | free(buf); |
1321 | return; | | 1297 | return; |
1322 | } | | 1298 | } |
1323 | if (newlen <= buflen) { | | 1299 | if (newlen <= buflen) { |
1324 | buflen = newlen; | | 1300 | buflen = newlen; |
1325 | break; | | 1301 | break; |
1326 | } | | 1302 | } |
1327 | if (buf) | | 1303 | if (buf) |
1328 | free(buf); | | 1304 | free(buf); |
1329 | buflen = newlen; | | 1305 | buflen = newlen; |
1330 | } | | 1306 | } |
1331 | buflen0 = buflen; | | 1307 | buflen0 = buflen; |
1332 | evs = buf0 = buf; | | 1308 | evs = buf0 = buf; |
1333 | last_evs = (void *)((char *)buf + buflen); | | 1309 | last_evs = (void *)((char *)buf + buflen); |
1334 | buflen /= sizeof(uint64_t); | | 1310 | buflen /= sizeof(uint64_t); |
1335 | /* calc columns */ | | 1311 | /* calc columns */ |
1336 | evlen_max = 0; | | 1312 | evlen_max = 0; |
1337 | total_max = sizeof("total") - 1; | | 1313 | total_max = sizeof("total") - 1; |
1338 | rate_max = sizeof("rate") - 1; | | 1314 | rate_max = sizeof("rate") - 1; |
1339 | while (evs < last_evs | | 1315 | while (evs < last_evs |
1340 | && buflen >= sizeof(*evs)/sizeof(uint64_t) | | 1316 | && buflen >= sizeof(*evs)/sizeof(uint64_t) |
1341 | && buflen >= evs->ev_len) { | | 1317 | && buflen >= evs->ev_len) { |
1342 | char cbuf[64]; | | 1318 | char cbuf[64]; |
1343 | size_t len; | | 1319 | size_t len; |
1344 | len = strlen(evs->ev_strings + evs->ev_grouplen + 1); | | 1320 | len = strlen(evs->ev_strings + evs->ev_grouplen + 1); |
1345 | len += evs->ev_grouplen + 1; | | 1321 | len += evs->ev_grouplen + 1; |
1346 | if (evlen_max < len) | | 1322 | if (evlen_max < len) |
1347 | evlen_max= len; | | 1323 | evlen_max= len; |
1348 | len = snprintf(cbuf, sizeof(cbuf), "%"PRIu64, | | 1324 | len = snprintf(cbuf, sizeof(cbuf), "%"PRIu64, |
1349 | evs->ev_count); | | 1325 | evs->ev_count); |
1350 | if (total_max < len) | | 1326 | if (total_max < len) |
1351 | total_max = len; | | 1327 | total_max = len; |
1352 | len = snprintf(cbuf, sizeof(cbuf), "%"PRIu64, | | 1328 | len = snprintf(cbuf, sizeof(cbuf), "%"PRIu64, |
1353 | evs->ev_count / uptime); | | 1329 | evs->ev_count / uptime); |
1354 | if (rate_max < len) | | 1330 | if (rate_max < len) |
1355 | rate_max = len; | | 1331 | rate_max = len; |
1356 | buflen -= evs->ev_len; | | 1332 | buflen -= evs->ev_len; |
1357 | evs = (const void *) | | 1333 | evs = (const void *) |
1358 | ((const uint64_t *)evs + evs->ev_len); | | 1334 | ((const uint64_t *)evs + evs->ev_len); |
1359 | } | | 1335 | } |
1360 | | | 1336 | |
1361 | (void)printf(type == EVCNT_TYPE_ANY ? | | 1337 | (void)printf(type == EVCNT_TYPE_ANY ? |
1362 | "%-*s %*s %*s %s\n" : | | 1338 | "%-*s %*s %*s %s\n" : |
1363 | "%-*s %*s %*s\n", | | 1339 | "%-*s %*s %*s\n", |
1364 | (int)evlen_max, "interrupt", | | 1340 | (int)evlen_max, "interrupt", |
1365 | (int)total_max, "total", | | 1341 | (int)total_max, "total", |
1366 | (int)rate_max, "rate", | | 1342 | (int)rate_max, "rate", |
1367 | "type"); | | 1343 | "type"); |
1368 | | | 1344 | |
1369 | buflen = buflen0; | | 1345 | buflen = buflen0; |
1370 | evs = buf0; | | 1346 | evs = buf0; |
1371 | last_evs = (void *)((char *)buf + buflen); | | 1347 | last_evs = (void *)((char *)buf + buflen); |
1372 | buflen /= sizeof(uint64_t); | | 1348 | buflen /= sizeof(uint64_t); |
1373 | while (evs < last_evs | | 1349 | while (evs < last_evs |
1374 | && buflen >= sizeof(*evs)/sizeof(uint64_t) | | 1350 | && buflen >= sizeof(*evs)/sizeof(uint64_t) |
1375 | && buflen >= evs->ev_len) { | | 1351 | && buflen >= evs->ev_len) { |
1376 | (void)printf(type == EVCNT_TYPE_ANY ? | | 1352 | (void)printf(type == EVCNT_TYPE_ANY ? |
1377 | "%s %s%*s %*"PRIu64" %*"PRIu64" %s\n" : | | 1353 | "%s %s%*s %*"PRIu64" %*"PRIu64" %s\n" : |
1378 | "%s %s%*s %*"PRIu64" %*"PRIu64"\n", | | 1354 | "%s %s%*s %*"PRIu64" %*"PRIu64"\n", |
1379 | evs->ev_strings, | | 1355 | evs->ev_strings, |
1380 | evs->ev_strings + evs->ev_grouplen + 1, | | 1356 | evs->ev_strings + evs->ev_grouplen + 1, |
1381 | (int)evlen_max - (evs->ev_grouplen + 1 | | 1357 | (int)evlen_max - (evs->ev_grouplen + 1 |
1382 | + evs->ev_namelen), "", | | 1358 | + evs->ev_namelen), "", |
1383 | (int)total_max, evs->ev_count, | | 1359 | (int)total_max, evs->ev_count, |
1384 | (int)rate_max, evs->ev_count / uptime, | | 1360 | (int)rate_max, evs->ev_count / uptime, |
1385 | (evs->ev_type < __arraycount(evtypes) ? | | 1361 | (evs->ev_type < __arraycount(evtypes) ? |
1386 | evtypes[evs->ev_type] : "?")); | | 1362 | evtypes[evs->ev_type] : "?")); |
1387 | buflen -= evs->ev_len; | | 1363 | buflen -= evs->ev_len; |
1388 | counttotal += evs->ev_count; | | 1364 | counttotal += evs->ev_count; |
1389 | evs = (const void *) | | 1365 | evs = (const void *) |
1390 | ((const uint64_t *)evs + evs->ev_len); | | 1366 | ((const uint64_t *)evs + evs->ev_len); |
1391 | } | | 1367 | } |
1392 | free(buf); | | 1368 | free(buf); |
1393 | if (type != EVCNT_TYPE_ANY) | | 1369 | if (type != EVCNT_TYPE_ANY) |
1394 | (void)printf("%-*s %*"PRIu64" %*"PRIu64"\n", | | 1370 | (void)printf("%-*s %*"PRIu64" %*"PRIu64"\n", |
1395 | (int)evlen_max, "Total", | | 1371 | (int)evlen_max, "Total", |
1396 | (int)total_max, counttotal, | | 1372 | (int)total_max, counttotal, |
1397 | (int)rate_max, counttotal / uptime); | | 1373 | (int)rate_max, counttotal / uptime); |
1398 | return; | | 1374 | return; |
1399 | } while (/*CONSTCOND*/ 0); | | 1375 | } while (/*CONSTCOND*/ 0); |
1400 | | | 1376 | |
1401 | if (type == EVCNT_TYPE_ANY) | | 1377 | if (type == EVCNT_TYPE_ANY) |
1402 | (void)printf("%-34s %16s %8s %s\n", "event", "total", "rate", | | 1378 | (void)printf("%-34s %16s %8s %s\n", "event", "total", "rate", |
1403 | "type"); | | 1379 | "type"); |
1404 | | | 1380 | |
1405 | kread(namelist, X_ALLEVENTS, &allevents, sizeof allevents); | | 1381 | kread(namelist, X_ALLEVENTS, &allevents, sizeof allevents); |
1406 | evptr = TAILQ_FIRST(&allevents); | | 1382 | evptr = TAILQ_FIRST(&allevents); |
1407 | while (evptr) { | | 1383 | while (evptr) { |
1408 | deref_kptr(evptr, &evcnt, sizeof(evcnt), "event chain trashed"); | | 1384 | deref_kptr(evptr, &evcnt, sizeof(evcnt), "event chain trashed"); |
1409 | | | 1385 | |
1410 | evptr = TAILQ_NEXT(&evcnt, ev_list); | | 1386 | evptr = TAILQ_NEXT(&evcnt, ev_list); |
1411 | if (evcnt.ev_count == 0 && !verbose) | | 1387 | if (evcnt.ev_count == 0 && !verbose) |
1412 | continue; | | 1388 | continue; |
1413 | if (type != EVCNT_TYPE_ANY && evcnt.ev_type != type) | | 1389 | if (type != EVCNT_TYPE_ANY && evcnt.ev_type != type) |
1414 | continue; | | 1390 | continue; |
1415 | | | 1391 | |
1416 | deref_kptr(evcnt.ev_group, evgroup, | | 1392 | deref_kptr(evcnt.ev_group, evgroup, |
1417 | (size_t)evcnt.ev_grouplen + 1, "event chain trashed"); | | 1393 | (size_t)evcnt.ev_grouplen + 1, "event chain trashed"); |
1418 | deref_kptr(evcnt.ev_name, evname, | | 1394 | deref_kptr(evcnt.ev_name, evname, |
1419 | (size_t)evcnt.ev_namelen + 1, "event chain trashed"); | | 1395 | (size_t)evcnt.ev_namelen + 1, "event chain trashed"); |
1420 | | | 1396 | |
1421 | (void)printf(type == EVCNT_TYPE_ANY ? | | 1397 | (void)printf(type == EVCNT_TYPE_ANY ? |
1422 | "%s %s%*s %16"PRIu64" %8"PRIu64" %s\n" : | | 1398 | "%s %s%*s %16"PRIu64" %8"PRIu64" %s\n" : |
1423 | "%s %s%*s %16"PRIu64" %8"PRIu64"\n", | | 1399 | "%s %s%*s %16"PRIu64" %8"PRIu64"\n", |
1424 | evgroup, evname, | | 1400 | evgroup, evname, |
1425 | 34 - (evcnt.ev_grouplen + 1 + evcnt.ev_namelen), "", | | 1401 | 34 - (evcnt.ev_grouplen + 1 + evcnt.ev_namelen), "", |
1426 | evcnt.ev_count, | | 1402 | evcnt.ev_count, |
1427 | (evcnt.ev_count / uptime), | | 1403 | (evcnt.ev_count / uptime), |
1428 | (evcnt.ev_type < __arraycount(evtypes) ? | | 1404 | (evcnt.ev_type < __arraycount(evtypes) ? |
1429 | evtypes[evcnt.ev_type] : "?")); | | 1405 | evtypes[evcnt.ev_type] : "?")); |
1430 | | | 1406 | |
1431 | counttotal += evcnt.ev_count; | | 1407 | counttotal += evcnt.ev_count; |
1432 | } | | 1408 | } |
1433 | if (type != EVCNT_TYPE_ANY) | | 1409 | if (type != EVCNT_TYPE_ANY) |
1434 | (void)printf("%-34s %16"PRIu64" %8"PRIu64"\n", | | 1410 | (void)printf("%-34s %16"PRIu64" %8"PRIu64"\n", |
1435 | "Total", counttotal, counttotal / uptime); | | 1411 | "Total", counttotal, counttotal / uptime); |
1436 | } | | 1412 | } |
1437 | | | 1413 | |
1438 | static void | | 1414 | static void |
1439 | dopool_sysctl(int verbose, int wide) | | 1415 | dopool_sysctl(int verbose, int wide) |
1440 | { | | 1416 | { |
1441 | uint64_t total, inuse, this_total, this_inuse; | | 1417 | uint64_t total, inuse, this_total, this_inuse; |
1442 | struct { | | 1418 | struct { |
1443 | uint64_t pt_nget; | | 1419 | uint64_t pt_nget; |
1444 | uint64_t pt_nfail; | | 1420 | uint64_t pt_nfail; |
1445 | uint64_t pt_nput; | | 1421 | uint64_t pt_nput; |
1446 | uint64_t pt_nout; | | 1422 | uint64_t pt_nout; |
1447 | uint64_t pt_nitems; | | 1423 | uint64_t pt_nitems; |
1448 | uint64_t pt_npagealloc; | | 1424 | uint64_t pt_npagealloc; |
1449 | uint64_t pt_npagefree; | | 1425 | uint64_t pt_npagefree; |
1450 | uint64_t pt_npages; | | 1426 | uint64_t pt_npages; |
1451 | } pool_totals; | | 1427 | } pool_totals; |
1452 | size_t i, len; | | 1428 | size_t i, len; |
1453 | int name_len, ovflw; | | 1429 | int name_len, ovflw; |
1454 | struct pool_sysctl *pp, *data; | | 1430 | struct pool_sysctl *pp, *data; |
1455 | char maxp[32]; | | 1431 | char maxp[32]; |
1456 | | | 1432 | |
1457 | data = asysctlbyname("kern.pool", &len); | | 1433 | data = asysctlbyname("kern.pool", &len); |
1458 | if (data == NULL) | | 1434 | if (data == NULL) |
1459 | err(1, "failed to read kern.pool"); | | 1435 | err(1, "failed to read kern.pool"); |
1460 | | | 1436 | |
1461 | memset(&pool_totals, 0, sizeof pool_totals); | | 1437 | memset(&pool_totals, 0, sizeof pool_totals); |
1462 | total = inuse = 0; | | 1438 | total = inuse = 0; |
1463 | len /= sizeof(*data); | | 1439 | len /= sizeof(*data); |
1464 | | | 1440 | |
1465 | (void)printf("Memory resource pool statistics\n"); | | 1441 | (void)printf("Memory resource pool statistics\n"); |
1466 | (void)printf( | | 1442 | (void)printf( |
1467 | "%-*s%*s%*s%*s%*s%s%s%*s%*s%*s%s%*s%6s%*s%5s%s%s\n", | | 1443 | "%-*s%*s%*s%*s%*s%s%s%*s%*s%*s%s%*s%6s%*s%5s%s%s\n", |
1468 | wide ? 16 : 11, "Name", | | 1444 | wide ? 16 : 11, "Name", |
1469 | wide ? 7 : 5, "Size", | | 1445 | wide ? 7 : 5, "Size", |
1470 | wide ? 12 : 9, "Requests", | | 1446 | wide ? 12 : 9, "Requests", |
1471 | wide ? 8 : 5, "Fail", | | 1447 | wide ? 8 : 5, "Fail", |
1472 | wide ? 12 : 9, "Releases", | | 1448 | wide ? 12 : 9, "Releases", |
1473 | wide ? " InUse" : "", | | 1449 | wide ? " InUse" : "", |
1474 | wide ? " Avail" : "", | | 1450 | wide ? " Avail" : "", |
1475 | wide ? 11 : 6, "Pgreq", | | 1451 | wide ? 11 : 6, "Pgreq", |
1476 | wide ? 11 : 6, "Pgrel", | | 1452 | wide ? 11 : 6, "Pgrel", |
1477 | wide ? 8 : 6, "Npage", | | 1453 | wide ? 8 : 6, "Npage", |
1478 | wide ? " PageSz" : "", | | 1454 | wide ? " PageSz" : "", |
1479 | wide ? 7 : 6, "Hiwat", | | 1455 | wide ? 7 : 6, "Hiwat", |
1480 | "Minpg", | | 1456 | "Minpg", |
1481 | wide ? 7 : 6, "Maxpg", | | 1457 | wide ? 7 : 6, "Maxpg", |
1482 | "Idle", | | 1458 | "Idle", |
1483 | wide ? " Flags" : "", | | 1459 | wide ? " Flags" : "", |
1484 | wide ? " Util" : ""); | | 1460 | wide ? " Util" : ""); |
1485 | | | 1461 | |
1486 | name_len = MIN((int)sizeof(pp->pr_wchan), wide ? 16 : 11); | | 1462 | name_len = MIN((int)sizeof(pp->pr_wchan), wide ? 16 : 11); |
1487 | for (i = 0; i < len; ++i) { | | 1463 | for (i = 0; i < len; ++i) { |
1488 | pp = &data[i]; | | 1464 | pp = &data[i]; |
1489 | if (pp->pr_nget == 0 && !verbose) | | 1465 | if (pp->pr_nget == 0 && !verbose) |
1490 | continue; | | 1466 | continue; |
1491 | if (pp->pr_maxpages == UINT_MAX) | | 1467 | if (pp->pr_maxpages == UINT_MAX) |
1492 | (void)snprintf(maxp, sizeof(maxp), "inf"); | | 1468 | (void)snprintf(maxp, sizeof(maxp), "inf"); |
1493 | else | | 1469 | else |
1494 | (void)snprintf(maxp, sizeof(maxp), "%" PRIu64, | | 1470 | (void)snprintf(maxp, sizeof(maxp), "%" PRIu64, |
1495 | pp->pr_maxpages); | | 1471 | pp->pr_maxpages); |
1496 | ovflw = 0; | | 1472 | ovflw = 0; |
1497 | PRWORD(ovflw, "%-*s", name_len, 0, pp->pr_wchan); | | 1473 | PRWORD(ovflw, "%-*s", name_len, 0, pp->pr_wchan); |
1498 | PRWORD(ovflw, " %*" PRIu64, wide ? 7 : 5, 1, pp->pr_size); | | 1474 | PRWORD(ovflw, " %*" PRIu64, wide ? 7 : 5, 1, pp->pr_size); |
1499 | PRWORD(ovflw, " %*" PRIu64, wide ? 12 : 9, 1, pp->pr_nget); | | 1475 | PRWORD(ovflw, " %*" PRIu64, wide ? 12 : 9, 1, pp->pr_nget); |
1500 | pool_totals.pt_nget += pp->pr_nget; | | 1476 | pool_totals.pt_nget += pp->pr_nget; |
1501 | PRWORD(ovflw, " %*" PRIu64, wide ? 8 : 5, 1, pp->pr_nfail); | | 1477 | PRWORD(ovflw, " %*" PRIu64, wide ? 8 : 5, 1, pp->pr_nfail); |
1502 | pool_totals.pt_nfail += pp->pr_nfail; | | 1478 | pool_totals.pt_nfail += pp->pr_nfail; |
1503 | PRWORD(ovflw, " %*" PRIu64, wide ? 12 : 9, 1, pp->pr_nput); | | 1479 | PRWORD(ovflw, " %*" PRIu64, wide ? 12 : 9, 1, pp->pr_nput); |
1504 | pool_totals.pt_nput += pp->pr_nput; | | 1480 | pool_totals.pt_nput += pp->pr_nput; |
1505 | if (wide) { | | 1481 | if (wide) { |
1506 | PRWORD(ovflw, " %*" PRIu64, 9, 1, pp->pr_nout); | | 1482 | PRWORD(ovflw, " %*" PRIu64, 9, 1, pp->pr_nout); |
1507 | pool_totals.pt_nout += pp->pr_nout; | | 1483 | pool_totals.pt_nout += pp->pr_nout; |
1508 | PRWORD(ovflw, " %*" PRIu64, 9, 1, pp->pr_nitems); | | 1484 | PRWORD(ovflw, " %*" PRIu64, 9, 1, pp->pr_nitems); |
1509 | pool_totals.pt_nitems += pp->pr_nitems; | | 1485 | pool_totals.pt_nitems += pp->pr_nitems; |
1510 | } | | 1486 | } |
1511 | PRWORD(ovflw, " %*" PRIu64, wide ? 11 : 6, 1, pp->pr_npagealloc); | | 1487 | PRWORD(ovflw, " %*" PRIu64, wide ? 11 : 6, 1, pp->pr_npagealloc); |
1512 | pool_totals.pt_npagealloc += pp->pr_npagealloc; | | 1488 | pool_totals.pt_npagealloc += pp->pr_npagealloc; |
1513 | PRWORD(ovflw, " %*" PRIu64, wide ? 11 : 6, 1, pp->pr_npagefree); | | 1489 | PRWORD(ovflw, " %*" PRIu64, wide ? 11 : 6, 1, pp->pr_npagefree); |
1514 | pool_totals.pt_npagefree += pp->pr_npagefree; | | 1490 | pool_totals.pt_npagefree += pp->pr_npagefree; |
1515 | PRWORD(ovflw, " %*" PRIu64, wide ? 8 : 6, 1, pp->pr_npages); | | 1491 | PRWORD(ovflw, " %*" PRIu64, wide ? 8 : 6, 1, pp->pr_npages); |
1516 | pool_totals.pt_npages += pp->pr_npages; | | 1492 | pool_totals.pt_npages += pp->pr_npages; |
1517 | if (wide) | | 1493 | if (wide) |
1518 | PRWORD(ovflw, " %*" PRIu64, 7, 1, pp->pr_pagesize); | | 1494 | PRWORD(ovflw, " %*" PRIu64, 7, 1, pp->pr_pagesize); |
1519 | PRWORD(ovflw, " %*" PRIu64, wide ? 7 : 6, 1, pp->pr_hiwat); | | 1495 | PRWORD(ovflw, " %*" PRIu64, wide ? 7 : 6, 1, pp->pr_hiwat); |
1520 | PRWORD(ovflw, " %*" PRIu64, 6, 1, pp->pr_minpages); | | 1496 | PRWORD(ovflw, " %*" PRIu64, 6, 1, pp->pr_minpages); |
1521 | PRWORD(ovflw, " %*s", wide ? 7 : 6, 1, maxp); | | 1497 | PRWORD(ovflw, " %*s", wide ? 7 : 6, 1, maxp); |
1522 | PRWORD(ovflw, " %*" PRIu64, 5, 1, pp->pr_nidle); | | 1498 | PRWORD(ovflw, " %*" PRIu64, 5, 1, pp->pr_nidle); |
1523 | if (wide) | | 1499 | if (wide) |
1524 | PRWORD(ovflw, " 0x%0*" PRIx64, 6, 1, | | 1500 | PRWORD(ovflw, " 0x%0*" PRIx64, 6, 1, |
1525 | pp->pr_flags); | | 1501 | pp->pr_flags); |
1526 | | | 1502 | |
1527 | this_inuse = pp->pr_nout * pp->pr_size; | | 1503 | this_inuse = pp->pr_nout * pp->pr_size; |
1528 | this_total = pp->pr_npages * pp->pr_pagesize; | | 1504 | this_total = pp->pr_npages * pp->pr_pagesize; |
1529 | if (pp->pr_flags & PR_RECURSIVE) { | | 1505 | if (pp->pr_flags & PR_RECURSIVE) { |
1530 | /* | | 1506 | /* |
1531 | * Don't count in-use memory, since it's part | | 1507 | * Don't count in-use memory, since it's part |
1532 | * of another pool and will be accounted for | | 1508 | * of another pool and will be accounted for |
1533 | * there. | | 1509 | * there. |
1534 | */ | | 1510 | */ |
1535 | total += (this_total - this_inuse); | | 1511 | total += (this_total - this_inuse); |
1536 | } else { | | 1512 | } else { |
1537 | inuse += this_inuse; | | 1513 | inuse += this_inuse; |
1538 | total += this_total; | | 1514 | total += this_total; |
1539 | } | | 1515 | } |
1540 | if (wide) { | | 1516 | if (wide) { |
1541 | if (this_total == 0) | | 1517 | if (this_total == 0) |
1542 | (void)printf(" ---"); | | 1518 | (void)printf(" ---"); |
1543 | else | | 1519 | else |
1544 | (void)printf(" %5.1f%%", | | 1520 | (void)printf(" %5.1f%%", |
1545 | (100.0 * this_inuse) / this_total); | | 1521 | (100.0 * this_inuse) / this_total); |
1546 | } | | 1522 | } |
1547 | (void)printf("\n"); | | 1523 | (void)printf("\n"); |
1548 | } | | 1524 | } |
1549 | ovflw = 0; | | 1525 | ovflw = 0; |
1550 | PRWORD(ovflw, "%-*s", name_len, 0, "Totals"); | | 1526 | PRWORD(ovflw, "%-*s", name_len, 0, "Totals"); |
1551 | PRWORD(ovflw, " %*s", wide ? 7 : 5, 1, ""); | | 1527 | PRWORD(ovflw, " %*s", wide ? 7 : 5, 1, ""); |
1552 | PRWORD(ovflw, " %*" PRIu64, wide ? 12 : 9, 1, pool_totals.pt_nget); | | 1528 | PRWORD(ovflw, " %*" PRIu64, wide ? 12 : 9, 1, pool_totals.pt_nget); |
1553 | PRWORD(ovflw, " %*" PRIu64, wide ? 8 : 5, 1, pool_totals.pt_nfail); | | 1529 | PRWORD(ovflw, " %*" PRIu64, wide ? 8 : 5, 1, pool_totals.pt_nfail); |
1554 | PRWORD(ovflw, " %*" PRIu64, wide ? 12 : 9, 1, pool_totals.pt_nput); | | 1530 | PRWORD(ovflw, " %*" PRIu64, wide ? 12 : 9, 1, pool_totals.pt_nput); |
1555 | if (wide) { | | 1531 | if (wide) { |
1556 | PRWORD(ovflw, " %*" PRIu64, 9, 1, pool_totals.pt_nout); | | 1532 | PRWORD(ovflw, " %*" PRIu64, 9, 1, pool_totals.pt_nout); |
1557 | PRWORD(ovflw, " %*" PRIu64, 9, 1, pool_totals.pt_nitems); | | 1533 | PRWORD(ovflw, " %*" PRIu64, 9, 1, pool_totals.pt_nitems); |
1558 | } | | 1534 | } |
1559 | PRWORD(ovflw, " %*" PRIu64, wide ? 11 : 6, 1, pool_totals.pt_npagealloc); | | 1535 | PRWORD(ovflw, " %*" PRIu64, wide ? 11 : 6, 1, pool_totals.pt_npagealloc); |
1560 | PRWORD(ovflw, " %*" PRIu64, wide ? 11 : 6, 1, pool_totals.pt_npagefree); | | 1536 | PRWORD(ovflw, " %*" PRIu64, wide ? 11 : 6, 1, pool_totals.pt_npagefree); |
1561 | PRWORD(ovflw, " %*" PRIu64, wide ? 8 : 6, 1, pool_totals.pt_npages); | | 1537 | PRWORD(ovflw, " %*" PRIu64, wide ? 8 : 6, 1, pool_totals.pt_npages); |
1562 | (void)printf("\n"); | | 1538 | (void)printf("\n"); |
1563 | | | 1539 | |
1564 | inuse /= KILO; | | 1540 | inuse /= KILO; |
1565 | total /= KILO; | | 1541 | total /= KILO; |
1566 | (void)printf( | | 1542 | (void)printf( |
1567 | "\nIn use %" PRIu64 "K, " | | 1543 | "\nIn use %" PRIu64 "K, " |
1568 | "total allocated %" PRIu64 "K; utilization %.1f%%\n", | | 1544 | "total allocated %" PRIu64 "K; utilization %.1f%%\n", |
1569 | inuse, total, (100.0 * inuse) / total); | | 1545 | inuse, total, (100.0 * inuse) / total); |
1570 | | | 1546 | |