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

Annotation of src/usr.bin/systat/mbufs.c, Revision 1.34

1.34    ! dlg         1: /*     $OpenBSD: mbufs.c,v 1.33 2014/06/13 07:31:18 mpi Exp $ */
1.19      canacar     2: /*
                      3:  * Copyright (c) 2008 Can Erkin Acar <canacar@openbsd.org>
1.1       deraadt     4:  *
1.19      canacar     5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
1.1       deraadt     8:  *
1.19      canacar     9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1.1       deraadt    16:  */
                     17: #include <sys/param.h>
                     18: #include <sys/types.h>
1.19      canacar    19: #include <sys/socket.h>
                     20: #include <sys/sysctl.h>
1.1       deraadt    21: #include <sys/mbuf.h>
1.28      blambert   22: #include <sys/pool.h>
1.19      canacar    23: #include <net/if.h>
1.1       deraadt    24:
1.19      canacar    25: #include <err.h>
                     26: #include <errno.h>
                     27: #include <ifaddrs.h>
1.1       deraadt    28: #include <stdlib.h>
                     29: #include <string.h>
1.19      canacar    30:
1.1       deraadt    31: #include "systat.h"
1.18      canacar    32:
                     33:
1.19      canacar    34: /* pool info for mcl* pools */
                     35: struct mclpool_info {
                     36:        char title[16];
                     37:        int pool_offset;
                     38:        int size;
                     39: } mclpools[MCLPOOLS];
                     40:
                     41: int mclpool_count = 0;
                     42: int mbpool_index = -1;
1.34    ! dlg        43: struct kinfo_pool mbpool;
1.31      claudio    44: u_int mcllivelocks, mcllivelocks_cur, mcllivelocks_diff;
1.19      canacar    45:
                     46: /* interfaces */
                     47: static int num_ifs;
                     48: struct if_info {
                     49:        char name[16];
                     50:        struct if_data data;
                     51: } *interfaces = NULL;
                     52:
1.18      canacar    53: void print_mb(void);
                     54: int read_mb(void);
                     55: int select_mb(void);
1.23      kettenis   56: static void showmbuf(struct if_info *, int, int);
1.1       deraadt    57:
                     58:
1.19      canacar    59: /* Define fields */
                     60: field_def fields_mbuf[] = {
                     61:        {"IFACE", 8, 16, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
                     62:        {"RXDELAY", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
                     63:        {"TXDELAY", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
                     64:        {"LIVELOCKS", 5, 10, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
                     65:        {"SIZE", 3, 5, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
                     66:        {"ALIVE", 3, 5, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
                     67:        {"LWM", 3, 5, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
                     68:        {"HWM", 3, 5, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
1.22      dlg        69:        {"CWM", 3, 5, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
1.1       deraadt    70: };
                     71:
                     72:
1.32      jasper     73: #define FLD_MB_IFACE   FIELD_ADDR(fields_mbuf,0)
                     74: #define FLD_MB_RXDELAY FIELD_ADDR(fields_mbuf,1)
                     75: #define FLD_MB_TXDELAY FIELD_ADDR(fields_mbuf,2)
                     76: #define FLD_MB_LLOCKS  FIELD_ADDR(fields_mbuf,3)
                     77: #define FLD_MB_MSIZE   FIELD_ADDR(fields_mbuf,4)
                     78: #define FLD_MB_MALIVE  FIELD_ADDR(fields_mbuf,5)
                     79: #define FLD_MB_MLWM    FIELD_ADDR(fields_mbuf,6)
                     80: #define FLD_MB_MHWM    FIELD_ADDR(fields_mbuf,7)
                     81: #define FLD_MB_MCWM    FIELD_ADDR(fields_mbuf,8)
1.18      canacar    82:
                     83:
                     84: /* Define views */
1.19      canacar    85: field_def *view_mbuf[] = {
                     86:        FLD_MB_IFACE,
1.26      henning    87:        FLD_MB_LLOCKS, FLD_MB_MSIZE, FLD_MB_MALIVE, FLD_MB_MLWM, FLD_MB_MHWM,
                     88:        FLD_MB_MCWM, NULL
1.18      canacar    89: };
                     90:
1.19      canacar    91: /* Define view managers */
1.18      canacar    92:
                     93: struct view_manager mbuf_mgr = {
                     94:        "Mbufs", select_mb, read_mb, NULL, print_header,
                     95:        print_mb, keyboard_callback, NULL, NULL
                     96: };
                     97:
                     98: field_view views_mb[] = {
1.19      canacar    99:        {view_mbuf, "mbufs", '4', &mbuf_mgr},
1.18      canacar   100:        {NULL, NULL, 0, NULL}
                    101: };
                    102:
                    103:
                    104: int
1.19      canacar   105: initmembufs(void)
1.1       deraadt   106: {
1.19      canacar   107:        field_view *v;
                    108:        int i, mib[4], npools;
1.34    ! dlg       109:        struct kinfo_pool pool;
1.19      canacar   110:        char pname[32];
                    111:        size_t size;
                    112:
                    113:        /* go through all pools to identify mbuf and cluster pools */
                    114:        bzero(mclpools, sizeof(mclpools));
1.18      canacar   115:
1.19      canacar   116:        mib[0] = CTL_KERN;
                    117:        mib[1] = KERN_POOL;
                    118:        mib[2] = KERN_POOL_NPOOLS;
                    119:        size = sizeof(npools);
                    120:
                    121:        if (sysctl(mib, 3, &npools, &size, NULL, 0) < 0) {
                    122:                err(1, "sysctl(KERN_POOL_NPOOLS)");
                    123:                /* NOTREACHED */
                    124:        }
                    125:
                    126:        for (i = 1; i <= npools; i++) {
                    127:                mib[0] = CTL_KERN;
                    128:                mib[1] = KERN_POOL;
                    129:                mib[2] = KERN_POOL_NAME;
                    130:                mib[3] = i;
                    131:                size = sizeof(pname);
                    132:                if (sysctl(mib, 4, &pname, &size, NULL, 0) < 0) {
1.21      canacar   133:                        continue;
1.19      canacar   134:                }
                    135:
                    136:                if (strcmp(pname, "mbpl") == 0) {
                    137:                        mbpool_index = i;
                    138:                        continue;
                    139:                }
                    140:
                    141:                if (strncmp(pname, "mcl", 3) != 0)
                    142:                        continue;
                    143:
                    144:                if (mclpool_count == MCLPOOLS) {
1.24      chl       145:                        warnx("mbufs: Too many mcl* pools");
1.19      canacar   146:                        break;
                    147:                }
                    148:
                    149:                mib[2] = KERN_POOL_POOL;
1.34    ! dlg       150:                size = sizeof(pool);
1.19      canacar   151:
                    152:                if (sysctl(mib, 4, &pool, &size, NULL, 0) < 0) {
                    153:                        err(1, "sysctl(KERN_POOL_POOL, %d)", i);
                    154:                        /* NOTREACHED */
                    155:                }
                    156:
                    157:                mclpools[mclpool_count].size = pool.pr_size;
                    158:                mclpools[mclpool_count].pool_offset = i;
                    159:                snprintf(mclpools[mclpool_count].title,
                    160:                    sizeof(mclpools[0].title), "%dk",
                    161:                    pool.pr_size / 1024);
                    162:
                    163:                mclpool_count++;
                    164:        }
                    165:
                    166:        if (mclpool_count != MCLPOOLS)
                    167:                warnx("mbufs: Unable to read all %d mcl* pools", MCLPOOLS);
                    168:
                    169:        /* add view to the engine */
                    170:        for (v = views_mb; v->name != NULL; v++)
                    171:                add_view(v);
                    172:
                    173:
                    174:        /* finally read it once */
1.18      canacar   175:        read_mb();
                    176:
1.19      canacar   177:        return(1);
                    178: }
1.18      canacar   179:
1.19      canacar   180: int
                    181: select_mb(void)
                    182: {
                    183:        num_disp = 0;
1.18      canacar   184:        return (0);
1.1       deraadt   185: }
                    186:
1.18      canacar   187: int
                    188: read_mb(void)
1.1       deraadt   189: {
1.34    ! dlg       190:        struct kinfo_pool pool;
1.19      canacar   191:        struct ifaddrs *ifap, *ifa;
                    192:        struct if_info *ifi;
                    193:        int mib[4];
                    194:        int i, p, nif, ret = 1;
                    195:        size_t size;
                    196:
1.30      dlg       197:        mib[0] = CTL_KERN;
                    198:        mib[1] = KERN_NETLIVELOCKS;
1.31      claudio   199:        size = sizeof(mcllivelocks_cur);
                    200:        if (sysctl(mib, 2, &mcllivelocks_cur, &size, NULL, 0) < 0 &&
1.30      dlg       201:            errno != EOPNOTSUPP) {
                    202:                error("sysctl(KERN_NETLIVELOCKS)");
                    203:                goto exit;
                    204:        }
1.31      claudio   205:        mcllivelocks_diff = mcllivelocks_cur - mcllivelocks;
                    206:        mcllivelocks = mcllivelocks_cur;
1.30      dlg       207:
1.19      canacar   208:        num_disp = 0;
                    209:        if (getifaddrs(&ifap)) {
                    210:                error("getifaddrs: %s", strerror(errno));
                    211:                return (1);
                    212:        }
                    213:
                    214:        nif = 1;
                    215:        for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next)
                    216:                if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_LINK)
                    217:                        nif++;
                    218:
                    219:        if (interfaces == NULL || num_ifs < nif) {
                    220:                size_t len = sizeof(*ifi) * nif;
                    221:                if (nif > SIZE_MAX / sizeof(*ifi)) {
                    222:                        error("overflow allocting %u interfaces", nif);
                    223:                        goto exit;
                    224:                }
                    225:
                    226:                ifi = realloc(interfaces, len);
                    227:                if (ifi == NULL) {
                    228:                        error("realloc: out of memory allocating %lld bytes",
                    229:                              (long long) len);
                    230:                        goto exit;
                    231:                }
                    232:
                    233:                interfaces = ifi;
                    234:                num_ifs = nif;
                    235:        }
                    236:
                    237:        /* Fill in the "real" interfaces */
                    238:        ifi = interfaces + 1;
                    239:
                    240:        for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
                    241:                if (ifa->ifa_addr == NULL ||
                    242:                    ifa->ifa_addr->sa_family != AF_LINK)
                    243:                        continue;
                    244:
                    245:                strlcpy(ifi->name, ifa->ifa_name, sizeof(ifi->name));
                    246:
                    247:                if (ifa->ifa_data)
                    248:                        memcpy(&ifi->data, ifa->ifa_data, sizeof(ifi->data));
                    249:                else
                    250:                        bzero(&ifi->data, sizeof(ifi->data));
                    251:                ifi++;
                    252:        }
                    253:
                    254:        /* Fill in the "System" entry from pools */
                    255:        bzero(interfaces, sizeof(interfaces[0]));
                    256:        strlcpy(interfaces[0].name, "System", sizeof(interfaces[0].name));
1.18      canacar   257:
                    258:        mib[0] = CTL_KERN;
1.19      canacar   259:        mib[1] = KERN_POOL;
                    260:        mib[2] = KERN_POOL_POOL;
                    261:        mib[3] = mbpool_index;
1.34    ! dlg       262:        size = sizeof(mbpool);
1.19      canacar   263:
                    264:        if (sysctl(mib, 4, &mbpool, &size, NULL, 0) < 0) {
1.27      chl       265:                error("sysctl(KERN_POOL_POOL, %d)", mib[3]);
1.19      canacar   266:                goto exit;
                    267:        }
                    268:
                    269:        for (i = 0; i < mclpool_count; i++) {
                    270:                struct mclpool *mp = &interfaces[0].data.ifi_mclpool[i];
                    271:
                    272:                mib[3] = mclpools[i].pool_offset;
1.34    ! dlg       273:                size = sizeof(pool);
1.18      canacar   274:
1.19      canacar   275:                if (sysctl(mib, 4, &pool, &size, NULL, 0) < 0) {
                    276:                        error("sysctl(KERN_POOL_POOL, %d)", mib[3]);
                    277:                        continue;
                    278:                }
                    279:
1.33      mpi       280:                mp->mcl_livelocks = mcllivelocks;
1.19      canacar   281:                mp->mcl_alive = pool.pr_nget - pool.pr_nput;
                    282:                mp->mcl_hwm = pool.pr_hiwat;
1.18      canacar   283:        }
                    284:
1.19      canacar   285:        num_disp = 1;
                    286:        ret = 0;
1.18      canacar   287:
1.19      canacar   288:        for (i = 0; i < num_ifs; i++) {
                    289:                struct if_info *ifi = &interfaces[i];
                    290:                int pnd = num_disp;
                    291:                for (p = 0; p < mclpool_count; p++) {
                    292:                        struct mclpool *mp = &ifi->data.ifi_mclpool[p];
                    293:                        if (mp->mcl_alive == 0)
                    294:                                continue;
                    295:                        num_disp++;
                    296:                }
                    297:                if (i && pnd == num_disp)
                    298:                        num_disp++;
1.18      canacar   299:        }
                    300:
1.19      canacar   301:  exit:
                    302:        freeifaddrs(ifap);
                    303:        return (ret);
1.1       deraadt   304: }
                    305:
                    306: void
1.18      canacar   307: print_mb(void)
1.1       deraadt   308: {
1.19      canacar   309:        int i, p, n, count = 0;
1.1       deraadt   310:
1.23      kettenis  311:        showmbuf(interfaces, -1, 1);
1.19      canacar   312:
                    313:        for (n = i = 0; i < num_ifs; i++) {
                    314:                struct if_info *ifi = &interfaces[i];
                    315:                int pcnt = count;
1.23      kettenis  316:                int showif = i;
                    317:
1.18      canacar   318:                if (maxprint > 0 && count >= maxprint)
1.19      canacar   319:                        return;
1.1       deraadt   320:
1.19      canacar   321:                for (p = 0; p < mclpool_count; p++) {
                    322:                        struct mclpool *mp = &ifi->data.ifi_mclpool[p];
                    323:                        if (mp->mcl_alive == 0)
                    324:                                continue;
                    325:                        if (n++ >= dispstart) {
1.23      kettenis  326:                                showmbuf(ifi, p, showif);
                    327:                                showif = 0;
1.19      canacar   328:                                count++;
                    329:                        }
                    330:                }
                    331:
                    332:                if (i && pcnt == count) {
                    333:                        /* only print the first line */
                    334:                        if (n++ >= dispstart) {
1.23      kettenis  335:                                showmbuf(ifi, -1, 1);
1.19      canacar   336:                                count++;
                    337:                        }
                    338:                }
1.1       deraadt   339:
1.5       ericj     340:
1.19      canacar   341:        }
1.1       deraadt   342: }
                    343:
1.18      canacar   344:
                    345: static void
1.23      kettenis  346: showmbuf(struct if_info *ifi, int p, int showif)
1.1       deraadt   347: {
1.23      kettenis  348:        if (showif)
1.19      canacar   349:                print_fld_str(FLD_MB_IFACE, ifi->name);
                    350:
                    351:        if (p == -1 && ifi == interfaces) {
1.31      claudio   352:                print_fld_uint(FLD_MB_LLOCKS, mcllivelocks_diff);
1.19      canacar   353:                print_fld_size(FLD_MB_MSIZE, mbpool.pr_size);
                    354:                print_fld_size(FLD_MB_MALIVE, mbpool.pr_nget - mbpool.pr_nput);
                    355:                print_fld_size(FLD_MB_MHWM, mbpool.pr_hiwat);
                    356:        }
                    357:
                    358:        if (p >= 0 && p < mclpool_count) {
                    359:                struct mclpool *mp = &ifi->data.ifi_mclpool[p];
1.33      mpi       360:                int livelocks_diff;
1.19      canacar   361:
1.33      mpi       362:                livelocks_diff = mp->mcl_livelocks - mcllivelocks;
                    363:                if (livelocks_diff)
                    364:                        print_fld_uint(FLD_MB_LLOCKS, livelocks_diff);
1.19      canacar   365:                print_fld_str(FLD_MB_MSIZE, mclpools[p].title);
                    366:                print_fld_uint(FLD_MB_MALIVE, mp->mcl_alive);
                    367:                if (mp->mcl_lwm)
                    368:                        print_fld_size(FLD_MB_MLWM, mp->mcl_lwm);
                    369:                if (mp->mcl_hwm)
                    370:                        print_fld_size(FLD_MB_MHWM, mp->mcl_hwm);
1.22      dlg       371:                if (mp->mcl_cwm)
                    372:                        print_fld_size(FLD_MB_MCWM, mp->mcl_cwm);
1.19      canacar   373:        }
1.18      canacar   374:
                    375:        end_line();
1.1       deraadt   376: }