version 1.34, 2014/07/02 00:12:34 |
version 1.35, 2014/07/08 05:35:19 |
|
|
#include <sys/mbuf.h> |
#include <sys/mbuf.h> |
#include <sys/pool.h> |
#include <sys/pool.h> |
#include <net/if.h> |
#include <net/if.h> |
|
#include <sys/sockio.h> |
|
#include <sys/ioctl.h> |
|
|
#include <err.h> |
#include <err.h> |
#include <errno.h> |
#include <errno.h> |
|
|
|
|
#include "systat.h" |
#include "systat.h" |
|
|
|
/* pool info */ |
/* pool info for mcl* pools */ |
|
struct mclpool_info { |
|
char title[16]; |
|
int pool_offset; |
|
int size; |
|
} mclpools[MCLPOOLS]; |
|
|
|
int mclpool_count = 0; |
|
int mbpool_index = -1; |
int mbpool_index = -1; |
|
int mclpools_index[MCLPOOLS]; |
|
int mclpool_count = 0; |
struct kinfo_pool mbpool; |
struct kinfo_pool mbpool; |
u_int mcllivelocks, mcllivelocks_cur, mcllivelocks_diff; |
u_int mcllivelocks, mcllivelocks_cur, mcllivelocks_diff; |
|
|
/* interfaces */ |
/* interfaces */ |
static int num_ifs; |
static int num_ifs = 0; |
struct if_info { |
struct if_info { |
char name[16]; |
char name[16]; |
struct if_data data; |
struct if_rxrinfo data; |
} *interfaces = NULL; |
} *interfaces = NULL; |
|
|
|
static int sock; |
|
|
void print_mb(void); |
void print_mb(void); |
int read_mb(void); |
int read_mb(void); |
int select_mb(void); |
int select_mb(void); |
static void showmbuf(struct if_info *, int, int); |
static void showmbuf(struct if_info *, int, int); |
|
|
|
|
/* Define fields */ |
/* Define fields */ |
field_def fields_mbuf[] = { |
field_def fields_mbuf[] = { |
{"IFACE", 8, 16, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0}, |
{"IFACE", 8, 16, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0}, |
|
|
int |
int |
initmembufs(void) |
initmembufs(void) |
{ |
{ |
|
struct if_rxring_info *ifr; |
field_view *v; |
field_view *v; |
int i, mib[4], npools; |
int i, mib[4], npools; |
struct kinfo_pool pool; |
struct kinfo_pool pool; |
char pname[32]; |
char pname[32]; |
size_t size; |
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 */ |
/* go through all pools to identify mbuf and cluster pools */ |
bzero(mclpools, sizeof(mclpools)); |
|
|
|
mib[0] = CTL_KERN; |
mib[0] = CTL_KERN; |
mib[1] = KERN_POOL; |
mib[1] = KERN_POOL; |
|
|
/* NOTREACHED */ |
/* NOTREACHED */ |
} |
} |
|
|
mclpools[mclpool_count].size = pool.pr_size; |
snprintf(ifr[mclpool_count].ifr_name, |
mclpools[mclpool_count].pool_offset = i; |
sizeof(ifr[mclpool_count].ifr_name), "%dk", |
snprintf(mclpools[mclpool_count].title, |
|
sizeof(mclpools[0].title), "%dk", |
|
pool.pr_size / 1024); |
pool.pr_size / 1024); |
|
ifr[mclpool_count].ifr_size = pool.pr_size; |
|
|
mclpool_count++; |
mclpools_index[mclpool_count++] = i; |
} |
} |
|
|
if (mclpool_count != MCLPOOLS) |
if (mclpool_count != MCLPOOLS) |
|
|
for (v = views_mb; v->name != NULL; v++) |
for (v = views_mb; v->name != NULL; v++) |
add_view(v); |
add_view(v); |
|
|
|
|
/* finally read it once */ |
/* finally read it once */ |
read_mb(); |
read_mb(); |
|
|
|
|
struct kinfo_pool pool; |
struct kinfo_pool pool; |
struct ifaddrs *ifap, *ifa; |
struct ifaddrs *ifap, *ifa; |
struct if_info *ifi; |
struct if_info *ifi; |
|
struct if_rxring_info *ifr; |
int mib[4]; |
int mib[4]; |
int i, p, nif, ret = 1; |
int i, p, nif, ret = 1, rv; |
|
u_int rings; |
size_t size; |
size_t size; |
|
|
mib[0] = CTL_KERN; |
mib[0] = CTL_KERN; |
|
|
} |
} |
|
|
nif = 1; |
nif = 1; |
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) |
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { |
if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_LINK) |
if (ifa->ifa_addr == NULL || |
nif++; |
ifa->ifa_addr->sa_family != AF_LINK) |
|
continue; |
|
|
if (interfaces == NULL || num_ifs < nif) { |
nif++; |
size_t len = sizeof(*ifi) * nif; |
} |
if (nif > SIZE_MAX / sizeof(*ifi)) { |
|
error("overflow allocting %u interfaces", nif); |
|
goto exit; |
|
} |
|
|
|
ifi = realloc(interfaces, len); |
if (num_ifs < nif) { |
|
ifi = reallocarray(interfaces, nif, sizeof(*interfaces)); |
if (ifi == NULL) { |
if (ifi == NULL) { |
error("realloc: out of memory allocating %lld bytes", |
error("reallocarray: %d interfaces", nif); |
(long long) len); |
|
goto exit; |
goto exit; |
} |
} |
|
|
interfaces = ifi; |
interfaces = ifi; |
num_ifs = nif; |
while (num_ifs < nif) |
|
memset(&interfaces[num_ifs++], 0, sizeof(*interfaces)); |
} |
} |
|
|
/* Fill in the "real" interfaces */ |
/* Fill in the "real" interfaces */ |
|
|
continue; |
continue; |
|
|
strlcpy(ifi->name, ifa->ifa_name, sizeof(ifi->name)); |
strlcpy(ifi->name, ifa->ifa_name, sizeof(ifi->name)); |
|
for (;;) { |
|
struct ifreq ifreq; |
|
rings = ifi->data.ifri_total; |
|
|
if (ifa->ifa_data) |
memset(&ifreq, 0, sizeof(ifreq)); |
memcpy(&ifi->data, ifa->ifa_data, sizeof(ifi->data)); |
strlcpy(ifreq.ifr_name, ifa->ifa_name, |
else |
sizeof(ifreq.ifr_name)); |
bzero(&ifi->data, sizeof(ifi->data)); |
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; |
|
} |
|
|
ifi++; |
ifi++; |
} |
} |
|
|
/* Fill in the "System" entry from pools */ |
/* 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[0] = CTL_KERN; |
mib[1] = KERN_POOL; |
mib[1] = KERN_POOL; |
|
|
} |
} |
|
|
for (i = 0; i < mclpool_count; i++) { |
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); |
size = sizeof(pool); |
|
|
if (sysctl(mib, 4, &pool, &size, NULL, 0) < 0) { |
if (sysctl(mib, 4, &pool, &size, NULL, 0) < 0) { |
|
|
continue; |
continue; |
} |
} |
|
|
mp->mcl_livelocks = mcllivelocks; |
ifr->ifr_info.rxr_alive = pool.pr_nget - pool.pr_nput; |
mp->mcl_alive = pool.pr_nget - pool.pr_nput; |
ifr->ifr_info.rxr_hwm = pool.pr_hiwat; |
mp->mcl_hwm = pool.pr_hiwat; |
|
} |
} |
|
|
num_disp = 1; |
num_disp = 1; |
|
|
for (i = 0; i < num_ifs; i++) { |
for (i = 0; i < num_ifs; i++) { |
struct if_info *ifi = &interfaces[i]; |
struct if_info *ifi = &interfaces[i]; |
int pnd = num_disp; |
int pnd = num_disp; |
for (p = 0; p < mclpool_count; p++) { |
for (p = 0; p < ifi->data.ifri_total; p++) { |
struct mclpool *mp = &ifi->data.ifi_mclpool[p]; |
ifr = &ifi->data.ifri_entries[p]; |
if (mp->mcl_alive == 0) |
if (ifr->ifr_info.rxr_alive == 0); |
continue; |
continue; |
num_disp++; |
num_disp++; |
} |
} |
|
|
if (maxprint > 0 && count >= maxprint) |
if (maxprint > 0 && count >= maxprint) |
return; |
return; |
|
|
for (p = 0; p < mclpool_count; p++) { |
for (p = 0; p < ifi->data.ifri_total; p++) { |
struct mclpool *mp = &ifi->data.ifi_mclpool[p]; |
struct if_rxring_info *ifr = &ifi->data.ifri_entries[p]; |
if (mp->mcl_alive == 0) |
if (ifr->ifr_info.rxr_alive == 0) |
continue; |
continue; |
if (n++ >= dispstart) { |
if (n++ >= dispstart) { |
showmbuf(ifi, p, showif); |
showmbuf(ifi, p, showif); |
|
|
count++; |
count++; |
} |
} |
} |
} |
|
|
|
|
} |
} |
} |
} |
|
|
|
|
} |
} |
|
|
if (p >= 0 && p < mclpool_count) { |
if (p >= 0 && p < mclpool_count) { |
struct mclpool *mp = &ifi->data.ifi_mclpool[p]; |
struct if_rxring_info *ifr = &ifi->data.ifri_entries[p]; |
int livelocks_diff; |
struct if_rxring *rxr= &ifr->ifr_info; |
|
print_fld_uint(FLD_MB_MSIZE, ifr->ifr_size); |
livelocks_diff = mp->mcl_livelocks - mcllivelocks; |
print_fld_uint(FLD_MB_MALIVE, rxr->rxr_alive); |
if (livelocks_diff) |
if (rxr->rxr_lwm) |
print_fld_uint(FLD_MB_LLOCKS, livelocks_diff); |
print_fld_size(FLD_MB_MLWM, rxr->rxr_lwm); |
print_fld_str(FLD_MB_MSIZE, mclpools[p].title); |
if (rxr->rxr_hwm) |
print_fld_uint(FLD_MB_MALIVE, mp->mcl_alive); |
print_fld_size(FLD_MB_MHWM, rxr->rxr_hwm); |
if (mp->mcl_lwm) |
if (rxr->rxr_cwm) |
print_fld_size(FLD_MB_MLWM, mp->mcl_lwm); |
print_fld_size(FLD_MB_MCWM, rxr->rxr_cwm); |
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); |
|
} |
} |
|
|
end_line(); |
end_line(); |