void TimerCalculator::calculate(unsigned long duration) { _duration = duration; t2_prescaler_pointer = 0; t2_comparator = 1; t1_comparator = 1; // clock_period = CLOCK_PERIOD; unsigned long max_t1_comparator = 65535; unsigned long max_duration = calc_period(max_t1_comparator); while (duration > max_duration) { if (t2_comparator < (t2_prescaler_array[t2_prescaler_pointer + 1] / t2_prescaler_array[t2_prescaler_pointer])) { t2_comparator += 1; } else { t2_comparator = 1; t2_prescaler_pointer += 1; } max_duration = calc_period(max_t1_comparator); if (t2_comparator == MAX_T2_COMPARATOR) break; } t1_comparator = (int)(duration / calc_t2_period()); }
static void stats_print(struct stats_record *stats_rec, struct stats_record *stats_prev, int prog_num) { unsigned int nr_cpus = bpf_num_possible_cpus(); double pps = 0, drop = 0, err = 0; struct record *rec, *prev; int to_cpu; double t; int i; /* Header */ printf("Running XDP/eBPF prog_num:%d\n", prog_num); printf("%-15s %-7s %-14s %-11s %-9s\n", "XDP-cpumap", "CPU:to", "pps", "drop-pps", "extra-info"); /* XDP rx_cnt */ { char *fmt_rx = "%-15s %-7d %'-14.0f %'-11.0f %'-10.0f %s\n"; char *fm2_rx = "%-15s %-7s %'-14.0f %'-11.0f\n"; char *errstr = ""; rec = &stats_rec->rx_cnt; prev = &stats_prev->rx_cnt; t = calc_period(rec, prev); for (i = 0; i < nr_cpus; i++) { struct datarec *r = &rec->cpu[i]; struct datarec *p = &prev->cpu[i]; pps = calc_pps(r, p, t); drop = calc_drop_pps(r, p, t); err = calc_errs_pps(r, p, t); if (err > 0) errstr = "cpu-dest/err"; if (pps > 0) printf(fmt_rx, "XDP-RX", i, pps, drop, err, errstr); } pps = calc_pps(&rec->total, &prev->total, t); drop = calc_drop_pps(&rec->total, &prev->total, t); err = calc_errs_pps(&rec->total, &prev->total, t); printf(fm2_rx, "XDP-RX", "total", pps, drop); } /* cpumap enqueue stats */ for (to_cpu = 0; to_cpu < MAX_CPUS; to_cpu++) { char *fmt = "%-15s %3d:%-3d %'-14.0f %'-11.0f %'-10.2f %s\n"; char *fm2 = "%-15s %3s:%-3d %'-14.0f %'-11.0f %'-10.2f %s\n"; char *errstr = ""; rec = &stats_rec->enq[to_cpu]; prev = &stats_prev->enq[to_cpu]; t = calc_period(rec, prev); for (i = 0; i < nr_cpus; i++) { struct datarec *r = &rec->cpu[i]; struct datarec *p = &prev->cpu[i]; pps = calc_pps(r, p, t); drop = calc_drop_pps(r, p, t); err = calc_errs_pps(r, p, t); if (err > 0) { errstr = "bulk-average"; err = pps / err; /* calc average bulk size */ } if (pps > 0) printf(fmt, "cpumap-enqueue", i, to_cpu, pps, drop, err, errstr); } pps = calc_pps(&rec->total, &prev->total, t); if (pps > 0) { drop = calc_drop_pps(&rec->total, &prev->total, t); err = calc_errs_pps(&rec->total, &prev->total, t); if (err > 0) { errstr = "bulk-average"; err = pps / err; /* calc average bulk size */ } printf(fm2, "cpumap-enqueue", "sum", to_cpu, pps, drop, err, errstr); } } /* cpumap kthread stats */ { char *fmt_k = "%-15s %-7d %'-14.0f %'-11.0f %'-10.0f %s\n"; char *fm2_k = "%-15s %-7s %'-14.0f %'-11.0f %'-10.0f %s\n"; char *e_str = ""; rec = &stats_rec->kthread; prev = &stats_prev->kthread; t = calc_period(rec, prev); for (i = 0; i < nr_cpus; i++) { struct datarec *r = &rec->cpu[i]; struct datarec *p = &prev->cpu[i]; pps = calc_pps(r, p, t); drop = calc_drop_pps(r, p, t); err = calc_errs_pps(r, p, t); if (err > 0) e_str = "sched"; if (pps > 0) printf(fmt_k, "cpumap_kthread", i, pps, drop, err, e_str); } pps = calc_pps(&rec->total, &prev->total, t); drop = calc_drop_pps(&rec->total, &prev->total, t); err = calc_errs_pps(&rec->total, &prev->total, t); if (err > 0) e_str = "sched-sum"; printf(fm2_k, "cpumap_kthread", "total", pps, drop, err, e_str); } /* XDP redirect err tracepoints (very unlikely) */ { char *fmt_err = "%-15s %-7d %'-14.0f %'-11.0f\n"; char *fm2_err = "%-15s %-7s %'-14.0f %'-11.0f\n"; rec = &stats_rec->redir_err; prev = &stats_prev->redir_err; t = calc_period(rec, prev); for (i = 0; i < nr_cpus; i++) { struct datarec *r = &rec->cpu[i]; struct datarec *p = &prev->cpu[i]; pps = calc_pps(r, p, t); drop = calc_drop_pps(r, p, t); if (pps > 0) printf(fmt_err, "redirect_err", i, pps, drop); } pps = calc_pps(&rec->total, &prev->total, t); drop = calc_drop_pps(&rec->total, &prev->total, t); printf(fm2_err, "redirect_err", "total", pps, drop); } /* XDP general exception tracepoints */ { char *fmt_err = "%-15s %-7d %'-14.0f %'-11.0f\n"; char *fm2_err = "%-15s %-7s %'-14.0f %'-11.0f\n"; rec = &stats_rec->exception; prev = &stats_prev->exception; t = calc_period(rec, prev); for (i = 0; i < nr_cpus; i++) { struct datarec *r = &rec->cpu[i]; struct datarec *p = &prev->cpu[i]; pps = calc_pps(r, p, t); drop = calc_drop_pps(r, p, t); if (pps > 0) printf(fmt_err, "xdp_exception", i, pps, drop); } pps = calc_pps(&rec->total, &prev->total, t); drop = calc_drop_pps(&rec->total, &prev->total, t); printf(fm2_err, "xdp_exception", "total", pps, drop); } printf("\n"); fflush(stdout); }
static void stats_print(struct stats_record *stats_rec, struct stats_record *stats_prev, bool err_only) { unsigned int nr_cpus = bpf_num_possible_cpus(); int rec_i = 0, i, to_cpu; double t = 0, pps = 0; /* Header */ printf("%-15s %-7s %-12s %-12s %-9s\n", "XDP-event", "CPU:to", "pps", "drop-pps", "extra-info"); /* tracepoint: xdp:xdp_redirect_* */ if (err_only) rec_i = REDIR_ERROR; for (; rec_i < REDIR_RES_MAX; rec_i++) { struct record_u64 *rec, *prev; char *fmt1 = "%-15s %-7d %'-12.0f %'-12.0f %s\n"; char *fmt2 = "%-15s %-7s %'-12.0f %'-12.0f %s\n"; rec = &stats_rec->xdp_redirect[rec_i]; prev = &stats_prev->xdp_redirect[rec_i]; t = calc_period_u64(rec, prev); for (i = 0; i < nr_cpus; i++) { struct u64rec *r = &rec->cpu[i]; struct u64rec *p = &prev->cpu[i]; pps = calc_pps_u64(r, p, t); if (pps > 0) printf(fmt1, "XDP_REDIRECT", i, rec_i ? 0.0: pps, rec_i ? pps : 0.0, err2str(rec_i)); } pps = calc_pps_u64(&rec->total, &prev->total, t); printf(fmt2, "XDP_REDIRECT", "total", rec_i ? 0.0: pps, rec_i ? pps : 0.0, err2str(rec_i)); } /* tracepoint: xdp:xdp_exception */ for (rec_i = 0; rec_i < XDP_ACTION_MAX; rec_i++) { struct record_u64 *rec, *prev; char *fmt1 = "%-15s %-7d %'-12.0f %'-12.0f %s\n"; char *fmt2 = "%-15s %-7s %'-12.0f %'-12.0f %s\n"; rec = &stats_rec->xdp_exception[rec_i]; prev = &stats_prev->xdp_exception[rec_i]; t = calc_period_u64(rec, prev); for (i = 0; i < nr_cpus; i++) { struct u64rec *r = &rec->cpu[i]; struct u64rec *p = &prev->cpu[i]; pps = calc_pps_u64(r, p, t); if (pps > 0) printf(fmt1, "Exception", i, 0.0, pps, action2str(rec_i)); } pps = calc_pps_u64(&rec->total, &prev->total, t); if (pps > 0) printf(fmt2, "Exception", "total", 0.0, pps, action2str(rec_i)); } /* cpumap enqueue stats */ for (to_cpu = 0; to_cpu < MAX_CPUS; to_cpu++) { char *fmt1 = "%-15s %3d:%-3d %'-12.0f %'-12.0f %'-10.2f %s\n"; char *fmt2 = "%-15s %3s:%-3d %'-12.0f %'-12.0f %'-10.2f %s\n"; struct record *rec, *prev; char *info_str = ""; double drop, info; rec = &stats_rec->xdp_cpumap_enqueue[to_cpu]; prev = &stats_prev->xdp_cpumap_enqueue[to_cpu]; t = calc_period(rec, prev); for (i = 0; i < nr_cpus; i++) { struct datarec *r = &rec->cpu[i]; struct datarec *p = &prev->cpu[i]; pps = calc_pps(r, p, t); drop = calc_drop(r, p, t); info = calc_info(r, p, t); if (info > 0) { info_str = "bulk-average"; info = pps / info; /* calc average bulk size */ } if (pps > 0) printf(fmt1, "cpumap-enqueue", i, to_cpu, pps, drop, info, info_str); } pps = calc_pps(&rec->total, &prev->total, t); if (pps > 0) { drop = calc_drop(&rec->total, &prev->total, t); info = calc_info(&rec->total, &prev->total, t); if (info > 0) { info_str = "bulk-average"; info = pps / info; /* calc average bulk size */ } printf(fmt2, "cpumap-enqueue", "sum", to_cpu, pps, drop, info, info_str); } } /* cpumap kthread stats */ { char *fmt1 = "%-15s %-7d %'-12.0f %'-12.0f %'-10.0f %s\n"; char *fmt2 = "%-15s %-7s %'-12.0f %'-12.0f %'-10.0f %s\n"; struct record *rec, *prev; double drop, info; char *i_str = ""; rec = &stats_rec->xdp_cpumap_kthread; prev = &stats_prev->xdp_cpumap_kthread; t = calc_period(rec, prev); for (i = 0; i < nr_cpus; i++) { struct datarec *r = &rec->cpu[i]; struct datarec *p = &prev->cpu[i]; pps = calc_pps(r, p, t); drop = calc_drop(r, p, t); info = calc_info(r, p, t); if (info > 0) i_str = "sched"; if (pps > 0 || drop > 0) printf(fmt1, "cpumap-kthread", i, pps, drop, info, i_str); } pps = calc_pps(&rec->total, &prev->total, t); drop = calc_drop(&rec->total, &prev->total, t); info = calc_info(&rec->total, &prev->total, t); if (info > 0) i_str = "sched-sum"; printf(fmt2, "cpumap-kthread", "total", pps, drop, info, i_str); } /* devmap ndo_xdp_xmit stats */ { char *fmt1 = "%-15s %-7d %'-12.0f %'-12.0f %'-10.2f %s %s\n"; char *fmt2 = "%-15s %-7s %'-12.0f %'-12.0f %'-10.2f %s %s\n"; struct record *rec, *prev; double drop, info, err; char *i_str = ""; char *err_str = ""; rec = &stats_rec->xdp_devmap_xmit; prev = &stats_prev->xdp_devmap_xmit; t = calc_period(rec, prev); for (i = 0; i < nr_cpus; i++) { struct datarec *r = &rec->cpu[i]; struct datarec *p = &prev->cpu[i]; pps = calc_pps(r, p, t); drop = calc_drop(r, p, t); info = calc_info(r, p, t); err = calc_err(r, p, t); if (info > 0) { i_str = "bulk-average"; info = (pps+drop) / info; /* calc avg bulk */ } if (err > 0) err_str = "drv-err"; if (pps > 0 || drop > 0) printf(fmt1, "devmap-xmit", i, pps, drop, info, i_str, err_str); } pps = calc_pps(&rec->total, &prev->total, t); drop = calc_drop(&rec->total, &prev->total, t); info = calc_info(&rec->total, &prev->total, t); err = calc_err(&rec->total, &prev->total, t); if (info > 0) { i_str = "bulk-average"; info = (pps+drop) / info; /* calc avg bulk */ } if (err > 0) err_str = "drv-err"; printf(fmt2, "devmap-xmit", "total", pps, drop, info, i_str, err_str); } printf("\n"); }