[BACK]Return to uvm.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / systat

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: }