Annotation of src/usr.bin/systat/uvm.c, Revision 1.9
1.9 ! mpi 1: /* $OpenBSD: uvm.c,v 1.8 2024/04/19 10:22:51 mpi Exp $ */
1.1 krw 2: /*
3: * Copyright (c) 2008 Can Erkin Acar <canacar@openbsd.org>
4: * Copyright (c) 2018 Kenneth R Westerback <krw@openbsd.org>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: #include <sys/types.h>
20: #include <sys/signal.h>
21: #include <sys/sysctl.h>
22: #include <sys/pool.h>
23: #include <ctype.h>
24: #include <err.h>
25: #include <errno.h>
26: #include <stdlib.h>
27: #include <string.h>
28: #include <limits.h>
29:
30: #include "systat.h"
31:
32: #ifndef nitems
33: #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
34: #endif
35:
36: void print_uvm(void);
37: int read_uvm(void);
38: int select_uvm(void);
39:
40: void print_uvmexp_field(field_def *, field_def *, int *, int *, const char *);
41: void print_uvmexp_line(int);
42:
43: struct uvmexp uvmexp;
44: struct uvmexp last_uvmexp;
45:
46: struct uvmline {
47: int *v1;
48: int *ov1;
49: char *n1;
50: int *v2;
51: int *ov2;
52: char *n2;
53: int *v3;
54: int *ov3;
55: char *n3;
56: };
57:
58: struct uvmline uvmline[] = {
59: { NULL, NULL, "Page Counters",
60: NULL, NULL, "Stats Counters",
61: NULL, NULL, "Fault Counters" },
62: { &uvmexp.npages, &last_uvmexp.npages, "npages",
63: &uvmexp.faults, &last_uvmexp.faults, "faults",
64: &uvmexp.fltnoram, &last_uvmexp.fltnoram, "fltnoram" },
65: { &uvmexp.free, &last_uvmexp.free, "free",
66: &uvmexp.traps, &last_uvmexp.traps, "traps",
67: &uvmexp.fltnoanon, &last_uvmexp.fltnoanon, "fltnoanon" },
68: { &uvmexp.active, &last_uvmexp.active, "active",
69: &uvmexp.intrs, &last_uvmexp.intrs, "intrs",
70: &uvmexp.fltnoamap, &last_uvmexp.fltnoamap, "fltnoamap" },
71: { &uvmexp.inactive, &last_uvmexp.inactive, "inactive",
72: &uvmexp.swtch, &last_uvmexp.swtch, "swtch",
73: &uvmexp.fltpgwait, &last_uvmexp.fltpgwait, "fltpgwait" },
74: { &uvmexp.paging, &last_uvmexp.paging, "paging",
75: &uvmexp.softs, &last_uvmexp.softs, "softs",
76: &uvmexp.fltpgrele, &last_uvmexp.fltpgrele, "fltpgrele" },
77: { &uvmexp.wired, &last_uvmexp.wired, "wired",
78: &uvmexp.syscalls, &last_uvmexp.syscalls, "syscalls",
79: &uvmexp.fltrelck, &last_uvmexp.fltrelck, "fltrelck" },
80: { &uvmexp.zeropages, &last_uvmexp.zeropages, "zeropages",
81: &uvmexp.pageins, &last_uvmexp.pageins, "pageins",
82: &uvmexp.fltrelckok, &last_uvmexp.fltrelckok, "fltrelckok" },
1.9 ! mpi 83: { &uvmexp.percpucaches, &last_uvmexp.percpucaches, "percpucaches",
1.4 krw 84: &uvmexp.pgswapin, &last_uvmexp.pgswapin, "pgswapin",
1.1 krw 85: &uvmexp.fltanget, &last_uvmexp.fltanget, "fltanget" },
1.9 ! mpi 86: { NULL, NULL, NULL,
1.4 krw 87: &uvmexp.pgswapout, &last_uvmexp.pgswapout, "pgswapout",
1.1 krw 88: &uvmexp.fltanretry, &last_uvmexp.fltanretry, "fltanretry" },
1.3 krw 89: { NULL, NULL, NULL,
1.4 krw 90: &uvmexp.forks, &last_uvmexp.forks, "forks",
1.1 krw 91: &uvmexp.fltamcopy, &last_uvmexp.fltamcopy, "fltamcopy" },
1.4 krw 92: { NULL, NULL, "Pageout Params",
93: &uvmexp.forks_ppwait, &last_uvmexp.forks_ppwait, "forks_ppwait",
1.1 krw 94: &uvmexp.fltnamap, &last_uvmexp.fltnamap, "fltnamap" },
1.4 krw 95: { &uvmexp.freemin, &last_uvmexp.freemin, "freemin",
96: &uvmexp.forks_sharevm, &last_uvmexp.forks_sharevm, "forks_sharevm",
1.1 krw 97: &uvmexp.fltnomap, &last_uvmexp.fltnomap, "fltnomap" },
1.4 krw 98: { &uvmexp.freetarg, &last_uvmexp.freetarg, "freetarg",
99: &uvmexp.pga_zerohit, &last_uvmexp.pga_zerohit, "pga_zerohit",
1.1 krw 100: &uvmexp.fltlget, &last_uvmexp.fltlget, "fltlget" },
1.4 krw 101: { &uvmexp.inactarg, &last_uvmexp.inactarg, "inactarg",
102: &uvmexp.pga_zeromiss, &last_uvmexp.pga_zeromiss, "pga_zeromiss",
1.1 krw 103: &uvmexp.fltget, &last_uvmexp.fltget, "fltget" },
104: { &uvmexp.wiredmax, &last_uvmexp.wiredmax, "wiredmax",
105: NULL, NULL, NULL,
1.4 krw 106: &uvmexp.flt_anon, &last_uvmexp.flt_anon, "flt_anon" },
1.1 krw 107: { &uvmexp.anonmin, &last_uvmexp.anonmin, "anonmin",
1.4 krw 108: NULL, NULL, "Daemon Counters",
109: &uvmexp.flt_acow, &last_uvmexp.flt_acow, "flt_acow" },
1.1 krw 110: { &uvmexp.vtextmin, &last_uvmexp.vtextmin, "vtextmin",
1.4 krw 111: &uvmexp.pdwoke, &last_uvmexp.pdwoke, "pdwoke",
112: &uvmexp.flt_obj, &last_uvmexp.flt_obj, "flt_obj" },
1.1 krw 113: { &uvmexp.vnodemin, &last_uvmexp.vnodemin, "vnodemin",
1.4 krw 114: &uvmexp.pdrevs, &last_uvmexp.pdrevs, "pdrevs",
115: &uvmexp.flt_prcopy, &last_uvmexp.flt_prcopy, "flt_prcopy" },
1.1 krw 116: { &uvmexp.anonminpct, &last_uvmexp.anonminpct, "anonminpct",
1.4 krw 117: &uvmexp.pdswout, &last_uvmexp.pdswout, "pdswout",
118: &uvmexp.flt_przero, &last_uvmexp.flt_przero, "flt_przero" },
1.1 krw 119: { &uvmexp.vtextminpct, &last_uvmexp.vtextminpct, "vtextminpct",
120: &uvmexp.swpgonly, &last_uvmexp.swpgonly, "swpgonly",
1.4 krw 121: NULL, NULL, NULL },
1.1 krw 122: { &uvmexp.vnodeminpct, &last_uvmexp.vnodeminpct, "vnodeminpct",
1.4 krw 123: &uvmexp.pdfreed, &last_uvmexp.pdfreed, "pdfreed",
124: NULL, NULL, "Swap Counters" },
1.1 krw 125: { NULL, NULL, NULL,
1.4 krw 126: &uvmexp.pdscans, &last_uvmexp.pdscans, "pdscans",
127: &uvmexp.nswapdev, &last_uvmexp.nswapdev, "nswapdev" },
1.1 krw 128: { NULL, NULL, "Misc Counters",
1.4 krw 129: &uvmexp.pdanscan, &last_uvmexp.pdanscan, "pdanscan",
130: &uvmexp.swpages, &last_uvmexp.swpages, "swpages" },
1.1 krw 131: { &uvmexp.fpswtch, &last_uvmexp.fpswtch, "fpswtch",
1.4 krw 132: &uvmexp.pdobscan, &last_uvmexp.pdobscan, "pdobscan",
133: &uvmexp.swpginuse, &last_uvmexp.swpginuse, "swpginuse" },
1.1 krw 134: { &uvmexp.kmapent, &last_uvmexp.kmapent, "kmapent",
1.4 krw 135: &uvmexp.pdreact, &last_uvmexp.pdreact, "pdreact",
1.6 kn 136: &uvmexp.swpgonly, &last_uvmexp.swpgonly, "swpgonly" },
1.1 krw 137: { NULL, NULL, NULL,
1.4 krw 138: &uvmexp.pdbusy, &last_uvmexp.pdbusy, "pdbusy",
1.6 kn 139: &uvmexp.nswget, &last_uvmexp.nswget, "nswget" },
1.1 krw 140: { NULL, NULL, "Constants",
1.4 krw 141: &uvmexp.pdpageouts, &last_uvmexp.pdpageouts, "pdpageouts",
142: NULL, NULL, NULL },
1.1 krw 143: { &uvmexp.pagesize, &last_uvmexp.pagesize, "pagesize",
1.4 krw 144: &uvmexp.pdpending, &last_uvmexp.pdpending, "pdpending",
1.9 ! mpi 145: NULL, NULL, "Per-CPU Counters" },
1.1 krw 146: { &uvmexp.pagemask, &last_uvmexp.pagemask, "pagemask",
1.4 krw 147: &uvmexp.pddeact, &last_uvmexp.pddeact, "pddeact",
1.9 ! mpi 148: &uvmexp.pcphit, &last_uvmexp.pcphit, "pcphit" },
1.1 krw 149: { &uvmexp.pageshift, &last_uvmexp.pageshift, "pageshift",
150: NULL, NULL, NULL,
1.9 ! mpi 151: &uvmexp.pcpmiss, &last_uvmexp.pcpmiss, "pcpmiss" }
1.1 krw 152: };
153:
154: field_def fields_uvm[] = {
155: {"", 5,10,1, FLD_ALIGN_RIGHT, -1,0,0,0 },
156: {"", 18,19,1, FLD_ALIGN_LEFT, -1,0,0,0 },
157: {"", 5,10,1, FLD_ALIGN_RIGHT, -1,0,0,0 },
158: {"", 18,19,1, FLD_ALIGN_LEFT, -1,0,0,0 },
159: {"", 5,10,1, FLD_ALIGN_RIGHT, -1,0,0,0 },
160: {"", 18,19,1, FLD_ALIGN_LEFT, -1,0,0,0 },
161: };
162:
163: #define FLD_VALUE1 FIELD_ADDR(fields_uvm, 0)
164: #define FLD_NAME1 FIELD_ADDR(fields_uvm, 1)
165: #define FLD_VALUE2 FIELD_ADDR(fields_uvm, 2)
166: #define FLD_NAME2 FIELD_ADDR(fields_uvm, 3)
167: #define FLD_VALUE3 FIELD_ADDR(fields_uvm, 4)
168: #define FLD_NAME3 FIELD_ADDR(fields_uvm, 5)
169:
170: /* Define views */
171: field_def *view_uvm_0[] = {
172: FLD_VALUE1, FLD_NAME1,
173: FLD_VALUE2, FLD_NAME2,
174: FLD_VALUE3, FLD_NAME3,
175: NULL
176: };
177:
178: /* Define view managers */
179: struct view_manager uvm_mgr = {
180: "UVM", select_uvm, read_uvm, NULL, print_header,
181: print_uvm, keyboard_callback, NULL, NULL
182: };
183:
184: field_view uvm_view = {
185: view_uvm_0,
186: "uvm",
187: '5',
188: &uvm_mgr
189: };
190:
191: int
192: select_uvm(void)
193: {
194: return (0);
195: }
196:
197: int
198: read_uvm(void)
199: {
200: static int uvmexp_mib[2] = { CTL_VM, VM_UVMEXP };
201: size_t size;
202:
203: num_disp = nitems(uvmline);
204: memcpy(&last_uvmexp, &uvmexp, sizeof(uvmexp));
205:
206: size = sizeof(uvmexp);
1.5 deraadt 207: if (sysctl(uvmexp_mib, 2, &uvmexp, &size, NULL, 0) == -1) {
1.1 krw 208: error("Can't get VM_UVMEXP: %s\n", strerror(errno));
209: memset(&uvmexp, 0, sizeof(uvmexp));
210: }
211:
212: return 0;
213: }
214:
215: void
216: print_uvmexp_field(field_def *fvalue, field_def *fname, int *new, int *old,
217: const char *name)
218: {
219: char *uppername;
1.2 bluhm 220: size_t len, i;
1.1 krw 221:
222: if (new == NULL && name == NULL)
223: return;
224:
225: if (new == NULL) {
226: print_fld_str(fvalue, "=====");
227: print_fld_str(fname, name);
228: return;
229: }
230:
231: if (*new != 0)
232: print_fld_ssize(fvalue, *new);
233: if (*new == *old) {
234: print_fld_str(fname, name);
235: return;
236: }
1.2 bluhm 237: len = strlen(name);
238: uppername = malloc(len + 1);
1.1 krw 239: if (uppername == NULL)
1.2 bluhm 240: err(1, "malloc");
241: for (i = 0; i < len; i++)
1.1 krw 242: uppername[i] = toupper(name[i]);
1.2 bluhm 243: uppername[len] = '\0';
1.1 krw 244: print_fld_str(fname, uppername);
245: free(uppername);
246: }
247:
248: void
249: print_uvm(void)
250: {
251: struct uvmline *l;
252: int i, maxline;
253:
254: maxline = nitems(uvmline);
255: if (maxline > (dispstart + maxprint))
256: maxline = dispstart + maxprint;
257:
258: for (i = dispstart; i < nitems(uvmline); i++) {
259: l = &uvmline[i];
260: print_uvmexp_field(FLD_VALUE1, FLD_NAME1, l->v1, l->ov1, l->n1);
261: print_uvmexp_field(FLD_VALUE2, FLD_NAME2, l->v2, l->ov2, l->n2);
262: print_uvmexp_field(FLD_VALUE3, FLD_NAME3, l->v3, l->ov3, l->n3);
263: end_line();
264: }
265: }
266:
267: int
268: inituvm(void)
269: {
270: add_view(&uvm_view);
271: read_uvm();
272:
273: return(0);
274: }