diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2014-07-08 05:35:20 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2014-07-08 05:35:20 +0000 |
commit | 4930c61b730e44cdce66c7f71fa9f703fcae2b38 (patch) | |
tree | 69bcdb82287306b3e015c5b2778bccc9790f2f81 /usr.bin | |
parent | f201a4bbc9d2fe8c3664f8b02ebf1ac13ae5b94e (diff) |
cut things that relied on mclgeti for rx ring accounting/restriction over
to using if_rxr.
cut the reporting systat did over to the rxr ioctl.
tested as much as i can on alpha, amd64, and sparc64.
mpi@ has run it on macppc.
ok mpi@
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/systat/mbufs.c | 175 |
1 files changed, 107 insertions, 68 deletions
diff --git a/usr.bin/systat/mbufs.c b/usr.bin/systat/mbufs.c index bbd3980405c..fef6095c614 100644 --- a/usr.bin/systat/mbufs.c +++ b/usr.bin/systat/mbufs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mbufs.c,v 1.34 2014/07/02 00:12:34 dlg Exp $ */ +/* $OpenBSD: mbufs.c,v 1.35 2014/07/08 05:35:19 dlg Exp $ */ /* * Copyright (c) 2008 Can Erkin Acar <canacar@openbsd.org> * @@ -21,6 +21,8 @@ #include <sys/mbuf.h> #include <sys/pool.h> #include <net/if.h> +#include <sys/sockio.h> +#include <sys/ioctl.h> #include <err.h> #include <errno.h> @@ -30,32 +32,27 @@ #include "systat.h" - -/* pool info for mcl* pools */ -struct mclpool_info { - char title[16]; - int pool_offset; - int size; -} mclpools[MCLPOOLS]; - -int mclpool_count = 0; +/* pool info */ int mbpool_index = -1; +int mclpools_index[MCLPOOLS]; +int mclpool_count = 0; struct kinfo_pool mbpool; u_int mcllivelocks, mcllivelocks_cur, mcllivelocks_diff; /* interfaces */ -static int num_ifs; +static int num_ifs = 0; struct if_info { char name[16]; - struct if_data data; + struct if_rxrinfo data; } *interfaces = NULL; +static int sock; + void print_mb(void); int read_mb(void); int select_mb(void); static void showmbuf(struct if_info *, int, int); - /* Define fields */ field_def fields_mbuf[] = { {"IFACE", 8, 16, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0}, @@ -104,14 +101,35 @@ field_view views_mb[] = { int initmembufs(void) { + struct if_rxring_info *ifr; field_view *v; int i, mib[4], npools; struct kinfo_pool pool; char pname[32]; size_t size; + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock == -1) { + err(1, "socket()"); + /* NOTREACHED */ + } + + /* set up the "System" interface */ + + interfaces = calloc(1, sizeof(*interfaces)); + if (interfaces == NULL) + err(1, "calloc: interfaces"); + + ifr = calloc(MCLPOOLS, sizeof(*ifr)); + if (ifr == NULL) + err(1, "calloc: system pools"); + + strlcpy(interfaces[0].name, "System", sizeof(interfaces[0].name)); + interfaces[0].data.ifri_total = MCLPOOLS; + interfaces[0].data.ifri_entries = ifr; + num_ifs = 1; + /* go through all pools to identify mbuf and cluster pools */ - bzero(mclpools, sizeof(mclpools)); mib[0] = CTL_KERN; mib[1] = KERN_POOL; @@ -154,13 +172,12 @@ initmembufs(void) /* NOTREACHED */ } - mclpools[mclpool_count].size = pool.pr_size; - mclpools[mclpool_count].pool_offset = i; - snprintf(mclpools[mclpool_count].title, - sizeof(mclpools[0].title), "%dk", + snprintf(ifr[mclpool_count].ifr_name, + sizeof(ifr[mclpool_count].ifr_name), "%dk", pool.pr_size / 1024); + ifr[mclpool_count].ifr_size = pool.pr_size; - mclpool_count++; + mclpools_index[mclpool_count++] = i; } if (mclpool_count != MCLPOOLS) @@ -170,7 +187,6 @@ initmembufs(void) for (v = views_mb; v->name != NULL; v++) add_view(v); - /* finally read it once */ read_mb(); @@ -190,8 +206,10 @@ read_mb(void) struct kinfo_pool pool; struct ifaddrs *ifap, *ifa; struct if_info *ifi; + struct if_rxring_info *ifr; int mib[4]; - int i, p, nif, ret = 1; + int i, p, nif, ret = 1, rv; + u_int rings; size_t size; mib[0] = CTL_KERN; @@ -212,26 +230,24 @@ read_mb(void) } nif = 1; - for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) - if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_LINK) - nif++; - - if (interfaces == NULL || num_ifs < nif) { - size_t len = sizeof(*ifi) * nif; - if (nif > SIZE_MAX / sizeof(*ifi)) { - error("overflow allocting %u interfaces", nif); - goto exit; - } + for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL || + ifa->ifa_addr->sa_family != AF_LINK) + continue; + + nif++; + } - ifi = realloc(interfaces, len); + if (num_ifs < nif) { + ifi = reallocarray(interfaces, nif, sizeof(*interfaces)); if (ifi == NULL) { - error("realloc: out of memory allocating %lld bytes", - (long long) len); + error("reallocarray: %d interfaces", nif); goto exit; } interfaces = ifi; - num_ifs = nif; + while (num_ifs < nif) + memset(&interfaces[num_ifs++], 0, sizeof(*interfaces)); } /* Fill in the "real" interfaces */ @@ -243,17 +259,47 @@ read_mb(void) continue; strlcpy(ifi->name, ifa->ifa_name, sizeof(ifi->name)); + for (;;) { + struct ifreq ifreq; + rings = ifi->data.ifri_total; + + memset(&ifreq, 0, sizeof(ifreq)); + strlcpy(ifreq.ifr_name, ifa->ifa_name, + sizeof(ifreq.ifr_name)); + ifreq.ifr_data = (caddr_t)&ifi->data; + + rv = ioctl(sock, SIOCGIFRXR, &ifreq); + if (rv == -1) { + if (errno == ENOTTY) { + free(ifi->data.ifri_entries); + ifi->data.ifri_total = 0; + ifi->data.ifri_entries = NULL; + break; + } + + error("ioctl(SIOCGIFRXR) %s", strerror(errno)); + break; + } + + if (rings >= ifi->data.ifri_total) + break; + + ifr = reallocarray(ifi->data.ifri_entries, + ifi->data.ifri_total, sizeof(*ifr)); + if (ifr == NULL) { + ifi->data.ifri_total = rings; + error("reallocarray: %u rings", + ifi->data.ifri_total); + goto exit; + } + + ifi->data.ifri_entries = ifr; + } - if (ifa->ifa_data) - memcpy(&ifi->data, ifa->ifa_data, sizeof(ifi->data)); - else - bzero(&ifi->data, sizeof(ifi->data)); ifi++; } /* Fill in the "System" entry from pools */ - bzero(interfaces, sizeof(interfaces[0])); - strlcpy(interfaces[0].name, "System", sizeof(interfaces[0].name)); mib[0] = CTL_KERN; mib[1] = KERN_POOL; @@ -267,9 +313,9 @@ read_mb(void) } for (i = 0; i < mclpool_count; i++) { - struct mclpool *mp = &interfaces[0].data.ifi_mclpool[i]; + ifr = &interfaces[0].data.ifri_entries[i]; - mib[3] = mclpools[i].pool_offset; + mib[3] = mclpools_index[i]; size = sizeof(pool); if (sysctl(mib, 4, &pool, &size, NULL, 0) < 0) { @@ -277,9 +323,8 @@ read_mb(void) continue; } - mp->mcl_livelocks = mcllivelocks; - mp->mcl_alive = pool.pr_nget - pool.pr_nput; - mp->mcl_hwm = pool.pr_hiwat; + ifr->ifr_info.rxr_alive = pool.pr_nget - pool.pr_nput; + ifr->ifr_info.rxr_hwm = pool.pr_hiwat; } num_disp = 1; @@ -288,9 +333,9 @@ read_mb(void) for (i = 0; i < num_ifs; i++) { struct if_info *ifi = &interfaces[i]; int pnd = num_disp; - for (p = 0; p < mclpool_count; p++) { - struct mclpool *mp = &ifi->data.ifi_mclpool[p]; - if (mp->mcl_alive == 0) + for (p = 0; p < ifi->data.ifri_total; p++) { + ifr = &ifi->data.ifri_entries[p]; + if (ifr->ifr_info.rxr_alive == 0); continue; num_disp++; } @@ -318,9 +363,9 @@ print_mb(void) if (maxprint > 0 && count >= maxprint) return; - for (p = 0; p < mclpool_count; p++) { - struct mclpool *mp = &ifi->data.ifi_mclpool[p]; - if (mp->mcl_alive == 0) + for (p = 0; p < ifi->data.ifri_total; p++) { + struct if_rxring_info *ifr = &ifi->data.ifri_entries[p]; + if (ifr->ifr_info.rxr_alive == 0) continue; if (n++ >= dispstart) { showmbuf(ifi, p, showif); @@ -336,8 +381,6 @@ print_mb(void) count++; } } - - } } @@ -356,20 +399,16 @@ showmbuf(struct if_info *ifi, int p, int showif) } if (p >= 0 && p < mclpool_count) { - struct mclpool *mp = &ifi->data.ifi_mclpool[p]; - int livelocks_diff; - - livelocks_diff = mp->mcl_livelocks - mcllivelocks; - if (livelocks_diff) - print_fld_uint(FLD_MB_LLOCKS, livelocks_diff); - print_fld_str(FLD_MB_MSIZE, mclpools[p].title); - print_fld_uint(FLD_MB_MALIVE, mp->mcl_alive); - if (mp->mcl_lwm) - print_fld_size(FLD_MB_MLWM, mp->mcl_lwm); - if (mp->mcl_hwm) - print_fld_size(FLD_MB_MHWM, mp->mcl_hwm); - if (mp->mcl_cwm) - print_fld_size(FLD_MB_MCWM, mp->mcl_cwm); + struct if_rxring_info *ifr = &ifi->data.ifri_entries[p]; + struct if_rxring *rxr= &ifr->ifr_info; + print_fld_uint(FLD_MB_MSIZE, ifr->ifr_size); + print_fld_uint(FLD_MB_MALIVE, rxr->rxr_alive); + if (rxr->rxr_lwm) + print_fld_size(FLD_MB_MLWM, rxr->rxr_lwm); + if (rxr->rxr_hwm) + print_fld_size(FLD_MB_MHWM, rxr->rxr_hwm); + if (rxr->rxr_cwm) + print_fld_size(FLD_MB_MCWM, rxr->rxr_cwm); } end_line(); |