Annotation of src/usr.bin/systat/uvm.c, Revision 1.1
1.1 ! krw 1: /* $OpenBSD$ */
! 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" },
! 83: { &uvmexp.reserve_pagedaemon, &last_uvmexp.reserve_pagedaemon,
! 84: "reserve_pagedaemon",
! 85: &uvmexp.obsolete_swapins, &last_uvmexp.obsolete_swapins,
! 86: "obsolete_swapins",
! 87: &uvmexp.fltanget, &last_uvmexp.fltanget, "fltanget" },
! 88: { &uvmexp.reserve_kernel, &last_uvmexp.reserve_kernel, "reserve_kernel",
! 89: &uvmexp.obsolete_swapouts, &last_uvmexp.obsolete_swapouts,
! 90: "obsolete_swapouts",
! 91: &uvmexp.fltanretry, &last_uvmexp.fltanretry, "fltanretry" },
! 92: { &uvmexp.anonpages, &last_uvmexp.anonpages, "anonpages",
! 93: &uvmexp.pgswapin, &last_uvmexp.pgswapin, "pgswapin",
! 94: &uvmexp.fltamcopy, &last_uvmexp.fltamcopy, "fltamcopy" },
! 95: { &uvmexp.vnodepages, &last_uvmexp.vnodepages, "vnodepages",
! 96: &uvmexp.pgswapout, &last_uvmexp.pgswapout, "pgswapout",
! 97: &uvmexp.fltnamap, &last_uvmexp.fltnamap, "fltnamap" },
! 98: { &uvmexp.vtextpages, &last_uvmexp.vtextpages, "vtextpages",
! 99: &uvmexp.forks, &last_uvmexp.forks, "forks",
! 100: &uvmexp.fltnomap, &last_uvmexp.fltnomap, "fltnomap" },
! 101: { NULL, NULL, NULL,
! 102: &uvmexp.forks_ppwait, &last_uvmexp.forks_ppwait, "forks_ppwait",
! 103: &uvmexp.fltlget, &last_uvmexp.fltlget, "fltlget" },
! 104: { NULL, NULL, "Pageout Params",
! 105: &uvmexp.forks_sharevm, &last_uvmexp.forks_sharevm, "forks_sharevm",
! 106: &uvmexp.fltget, &last_uvmexp.fltget, "fltget" },
! 107: { &uvmexp.freemin, &last_uvmexp.freemin, "freemin",
! 108: &uvmexp.pga_zerohit, &last_uvmexp.pga_zerohit, "pga_zerohit",
! 109: &uvmexp.flt_anon, &last_uvmexp.flt_anon, "flt_anon" },
! 110: { &uvmexp.freetarg, &last_uvmexp.freetarg, "freetarg",
! 111: &uvmexp.pga_zeromiss, &last_uvmexp.pga_zeromiss, "pga_zeromiss",
! 112: &uvmexp.flt_acow, &last_uvmexp.flt_acow, "flt_acow" },
! 113: { &uvmexp.inactarg, &last_uvmexp.inactarg, "inactarg",
! 114: &uvmexp.zeroaborts, &last_uvmexp.zeroaborts, "zeroaborts",
! 115: &uvmexp.flt_obj, &last_uvmexp.flt_obj, "flt_obj" },
! 116: { &uvmexp.wiredmax, &last_uvmexp.wiredmax, "wiredmax",
! 117: NULL, NULL, NULL,
! 118: &uvmexp.flt_prcopy, &last_uvmexp.flt_prcopy, "flt_prcopy" },
! 119: { &uvmexp.anonmin, &last_uvmexp.anonmin, "anonmin",
! 120: NULL, NULL, "Swap Counters",
! 121: &uvmexp.flt_przero, &last_uvmexp.flt_przero, "flt_przero" },
! 122: { &uvmexp.vtextmin, &last_uvmexp.vtextmin, "vtextmin",
! 123: &uvmexp.nswapdev, &last_uvmexp.nswapdev, "nswapdev",
! 124: NULL, NULL, NULL },
! 125: { &uvmexp.vnodemin, &last_uvmexp.vnodemin, "vnodemin",
! 126: &uvmexp.swpages, &last_uvmexp.swpages, "swpages",
! 127: NULL, NULL, "Daemon Counters" },
! 128: { &uvmexp.anonminpct, &last_uvmexp.anonminpct, "anonminpct",
! 129: &uvmexp.swpginuse, &last_uvmexp.swpginuse, "swpginuse",
! 130: &uvmexp.pdwoke, &last_uvmexp.pdwoke, "pdwoke" },
! 131: { &uvmexp.vtextminpct, &last_uvmexp.vtextminpct, "vtextminpct",
! 132: &uvmexp.swpgonly, &last_uvmexp.swpgonly, "swpgonly",
! 133: &uvmexp.pdrevs, &last_uvmexp.pdrevs, "pdrevs" },
! 134: { &uvmexp.vnodeminpct, &last_uvmexp.vnodeminpct, "vnodeminpct",
! 135: &uvmexp.nswget, &last_uvmexp.nswget, "nswget",
! 136: &uvmexp.pdswout, &last_uvmexp.pdswout, "pdswout" },
! 137: { NULL, NULL, NULL,
! 138: &uvmexp.nanon, &last_uvmexp.nanon, "nanon",
! 139: &uvmexp.pdfreed, &last_uvmexp.pdfreed, "pdfreed" },
! 140: { NULL, NULL, "Misc Counters",
! 141: &uvmexp.nanonneeded, &last_uvmexp.nanonneeded, "nanonneeded",
! 142: &uvmexp.pdscans, &last_uvmexp.pdscans, "pdscans" },
! 143: { &uvmexp.fpswtch, &last_uvmexp.fpswtch, "fpswtch",
! 144: &uvmexp.nfreeanon, &last_uvmexp.nfreeanon, "nfreeanon",
! 145: &uvmexp.pdanscan, &last_uvmexp.pdanscan, "pdanscan" },
! 146: { &uvmexp.kmapent, &last_uvmexp.kmapent, "kmapent",
! 147: NULL, NULL, NULL,
! 148: &uvmexp.pdobscan, &last_uvmexp.pdobscan, "pdobscan" },
! 149: { NULL, NULL, NULL,
! 150: NULL, NULL, NULL,
! 151: &uvmexp.pdreact, &last_uvmexp.pdreact, "pdreact" },
! 152: { NULL, NULL, "Constants",
! 153: NULL, NULL, NULL,
! 154: &uvmexp.pdbusy, &last_uvmexp.pdbusy, "pdbusy" },
! 155: { &uvmexp.pagesize, &last_uvmexp.pagesize, "pagesize",
! 156: NULL, NULL, NULL,
! 157: &uvmexp.pdpageouts, &last_uvmexp.pdpageouts, "pdpageouts" },
! 158: { &uvmexp.pagemask, &last_uvmexp.pagemask, "pagemask",
! 159: NULL, NULL, NULL,
! 160: &uvmexp.pdpending, &last_uvmexp.pdpending, "pdpending" },
! 161: { &uvmexp.pageshift, &last_uvmexp.pageshift, "pageshift",
! 162: NULL, NULL, NULL,
! 163: &uvmexp.pddeact, &last_uvmexp.pddeact, "pddeact" },
! 164: { NULL, NULL, NULL,
! 165: NULL, NULL, NULL,
! 166: &uvmexp.pdreanon, &last_uvmexp.pdreanon, "pdrenon" },
! 167: { NULL, NULL, NULL,
! 168: NULL, NULL, NULL,
! 169: &uvmexp.pdrevnode, &last_uvmexp.pdrevnode, "pdrevnode" },
! 170: { NULL, NULL, NULL,
! 171: NULL, NULL, NULL,
! 172: &uvmexp.pdrevtext, &last_uvmexp.pdrevtext, "pdrevtext" }
! 173: };
! 174:
! 175: field_def fields_uvm[] = {
! 176: {"", 5,10,1, FLD_ALIGN_RIGHT, -1,0,0,0 },
! 177: {"", 18,19,1, FLD_ALIGN_LEFT, -1,0,0,0 },
! 178: {"", 5,10,1, FLD_ALIGN_RIGHT, -1,0,0,0 },
! 179: {"", 18,19,1, FLD_ALIGN_LEFT, -1,0,0,0 },
! 180: {"", 5,10,1, FLD_ALIGN_RIGHT, -1,0,0,0 },
! 181: {"", 18,19,1, FLD_ALIGN_LEFT, -1,0,0,0 },
! 182: };
! 183:
! 184: #define FLD_VALUE1 FIELD_ADDR(fields_uvm, 0)
! 185: #define FLD_NAME1 FIELD_ADDR(fields_uvm, 1)
! 186: #define FLD_VALUE2 FIELD_ADDR(fields_uvm, 2)
! 187: #define FLD_NAME2 FIELD_ADDR(fields_uvm, 3)
! 188: #define FLD_VALUE3 FIELD_ADDR(fields_uvm, 4)
! 189: #define FLD_NAME3 FIELD_ADDR(fields_uvm, 5)
! 190:
! 191: /* Define views */
! 192: field_def *view_uvm_0[] = {
! 193: FLD_VALUE1, FLD_NAME1,
! 194: FLD_VALUE2, FLD_NAME2,
! 195: FLD_VALUE3, FLD_NAME3,
! 196: NULL
! 197: };
! 198:
! 199: /* Define view managers */
! 200: struct view_manager uvm_mgr = {
! 201: "UVM", select_uvm, read_uvm, NULL, print_header,
! 202: print_uvm, keyboard_callback, NULL, NULL
! 203: };
! 204:
! 205: field_view uvm_view = {
! 206: view_uvm_0,
! 207: "uvm",
! 208: '5',
! 209: &uvm_mgr
! 210: };
! 211:
! 212: int
! 213: select_uvm(void)
! 214: {
! 215: return (0);
! 216: }
! 217:
! 218: int
! 219: read_uvm(void)
! 220: {
! 221: static int uvmexp_mib[2] = { CTL_VM, VM_UVMEXP };
! 222: size_t size;
! 223:
! 224: num_disp = nitems(uvmline);
! 225: memcpy(&last_uvmexp, &uvmexp, sizeof(uvmexp));
! 226:
! 227: size = sizeof(uvmexp);
! 228: if (sysctl(uvmexp_mib, 2, &uvmexp, &size, NULL, 0) < 0) {
! 229: error("Can't get VM_UVMEXP: %s\n", strerror(errno));
! 230: memset(&uvmexp, 0, sizeof(uvmexp));
! 231: }
! 232:
! 233: return 0;
! 234: }
! 235:
! 236: void
! 237: print_uvmexp_field(field_def *fvalue, field_def *fname, int *new, int *old,
! 238: const char *name)
! 239: {
! 240: char *uppername;
! 241: size_t i;
! 242:
! 243: if (new == NULL && name == NULL)
! 244: return;
! 245:
! 246: if (new == NULL) {
! 247: print_fld_str(fvalue, "=====");
! 248: print_fld_str(fname, name);
! 249: return;
! 250: }
! 251:
! 252: if (*new != 0)
! 253: print_fld_ssize(fvalue, *new);
! 254: if (*new == *old) {
! 255: print_fld_str(fname, name);
! 256: return;
! 257: }
! 258: uppername = calloc(1, strlen(name) + 1);
! 259: if (uppername == NULL)
! 260: err(1, "calloc");
! 261: for (i = 0; i < strlen(name); i++)
! 262: uppername[i] = toupper(name[i]);
! 263: print_fld_str(fname, uppername);
! 264: free(uppername);
! 265: }
! 266:
! 267: void
! 268: print_uvm(void)
! 269: {
! 270: struct uvmline *l;
! 271: int i, maxline;
! 272:
! 273: maxline = nitems(uvmline);
! 274: if (maxline > (dispstart + maxprint))
! 275: maxline = dispstart + maxprint;
! 276:
! 277: for (i = dispstart; i < nitems(uvmline); i++) {
! 278: l = &uvmline[i];
! 279: print_uvmexp_field(FLD_VALUE1, FLD_NAME1, l->v1, l->ov1, l->n1);
! 280: print_uvmexp_field(FLD_VALUE2, FLD_NAME2, l->v2, l->ov2, l->n2);
! 281: print_uvmexp_field(FLD_VALUE3, FLD_NAME3, l->v3, l->ov3, l->n3);
! 282: end_line();
! 283: }
! 284: }
! 285:
! 286: int
! 287: inituvm(void)
! 288: {
! 289: add_view(&uvm_view);
! 290: read_uvm();
! 291:
! 292: return(0);
! 293: }