static void stats_get_devmap_xmit_multi()

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");
		}
	}
}