in bpf/xdp_sample_user.c [1001:1101]
static void stats_get_devmap_xmit_multi(struct stats_record *stats_rec,
struct stats_record *stats_prev,
unsigned int nr_cpus,
struct sample_output *out,
bool xmit_total)
{
double pps, drop, info, err;
struct map_entry *entry;
struct record *r, *p;
double t;
int bkt;
hash_for_each(stats_rec->xmit_map, bkt, entry, node) {
struct map_entry *e, *x = NULL;
char ifname_from[IFNAMSIZ];
char ifname_to[IFNAMSIZ];
const char *fstr, *tstr;
unsigned long prev_time;
struct record beg = {};
__u32 from_idx, to_idx;
char str[128];
__u64 pair;
int i;
prev_time = sample_interval * NANOSEC_PER_SEC;
pair = entry->pair;
from_idx = pair >> 32;
to_idx = pair & 0xFFFFFFFF;
r = &entry->val;
beg.timestamp = r->timestamp - prev_time;
/* Find matching entry from stats_prev map */
hash_for_each_possible(stats_prev->xmit_map, e, node, pair) {
if (e->pair == pair) {
x = e;
break;
}
}
if (x)
p = &x->val;
else
p = &beg;
t = calc_period(r, p);
pps = calc_pps(&r->total, &p->total, t);
drop = calc_drop_pps(&r->total, &p->total, t);
info = calc_info_pps(&r->total, &p->total, t);
if (info > 0)
info = (pps + drop) / info; /* calc avg bulk */
err = calc_errs_pps(&r->total, &p->total, t);
if (out) {
/* We are responsible for filling out totals */
out->totals.xmit += pps;
out->totals.drop_xmit += drop;
out->totals.err += err;
continue;
}
fstr = tstr = NULL;
if (if_indextoname(from_idx, ifname_from))
fstr = ifname_from;
if (if_indextoname(to_idx, ifname_to))
tstr = ifname_to;
snprintf(str, sizeof(str), "xmit %s->%s", fstr ?: "?",
tstr ?: "?");
/* Skip idle streams of redirection */
if (pps || drop || err) {
print_err(drop,
" %-20s " FMT_COLUMNf FMT_COLUMNf FMT_COLUMNf
__COLUMN(".2f") "\n", str, XMIT(pps), DROP(drop),
err, "drv_err/s", info, "bulk-avg");
}
for (i = 0; i < nr_cpus; i++) {
struct datarec *rc = &r->cpu[i];
struct datarec *pc, p_beg = {};
char str[64];
pc = p == &beg ? &p_beg : &p->cpu[i];
pps = calc_pps(rc, pc, t);
drop = calc_drop_pps(rc, pc, t);
err = calc_errs_pps(rc, pc, t);
if (!pps && !drop && !err)
continue;
snprintf(str, sizeof(str), "cpu:%d", i);
info = calc_info_pps(rc, pc, t);
if (info > 0)
info = (pps + drop) / info; /* calc avg bulk */
print_default(" %-18s" FMT_COLUMNf FMT_COLUMNf FMT_COLUMNf
__COLUMN(".2f") "\n", str, XMIT(pps),
DROP(drop), err, "drv_err/s", info, "bulk-avg");
}
}
}