mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
samples: bpf: Add xdp_exception tracepoint statistics support
This implements the retrieval and printing, as well the help output. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/20210821002010.845777-8-memxor@gmail.com
This commit is contained in:
parent
451588764e
commit
82c450803a
@ -74,6 +74,7 @@
|
||||
enum map_type {
|
||||
MAP_RX,
|
||||
MAP_REDIRECT_ERR,
|
||||
MAP_EXCEPTION,
|
||||
NUM_MAP,
|
||||
};
|
||||
|
||||
@ -98,6 +99,7 @@ struct map_entry {
|
||||
struct stats_record {
|
||||
struct record rx_cnt;
|
||||
struct record redir_err[XDP_REDIRECT_ERR_MAX];
|
||||
struct record exception[XDP_ACTION_MAX];
|
||||
};
|
||||
|
||||
struct sample_output {
|
||||
@ -115,6 +117,9 @@ struct sample_output {
|
||||
__u64 suc;
|
||||
__u64 err;
|
||||
} redir_cnt;
|
||||
struct {
|
||||
__u64 hits;
|
||||
} except_cnt;
|
||||
};
|
||||
|
||||
struct xdp_desc {
|
||||
@ -156,6 +161,15 @@ static const char *xdp_redirect_err_help[XDP_REDIRECT_ERR_MAX - 1] = {
|
||||
"No space in ptr_ring of cpumap kthread",
|
||||
};
|
||||
|
||||
static const char *xdp_action_names[XDP_ACTION_MAX] = {
|
||||
[XDP_ABORTED] = "XDP_ABORTED",
|
||||
[XDP_DROP] = "XDP_DROP",
|
||||
[XDP_PASS] = "XDP_PASS",
|
||||
[XDP_TX] = "XDP_TX",
|
||||
[XDP_REDIRECT] = "XDP_REDIRECT",
|
||||
[XDP_UNKNOWN] = "XDP_UNKNOWN",
|
||||
};
|
||||
|
||||
static __u64 gettime(void)
|
||||
{
|
||||
struct timespec t;
|
||||
@ -169,6 +183,13 @@ static __u64 gettime(void)
|
||||
return (__u64)t.tv_sec * NANOSEC_PER_SEC + t.tv_nsec;
|
||||
}
|
||||
|
||||
static const char *action2str(int action)
|
||||
{
|
||||
if (action < XDP_ACTION_MAX)
|
||||
return xdp_action_names[action];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void sample_print_help(int mask)
|
||||
{
|
||||
printf("Output format description\n\n"
|
||||
@ -206,6 +227,15 @@ static void sample_print_help(int mask)
|
||||
|
||||
printf(" \n\t\t\t\terror/s - Packets that failed redirection per second\n\n");
|
||||
}
|
||||
|
||||
if (mask & SAMPLE_EXCEPTION_CNT) {
|
||||
printf(" xdp_exception\t\tDisplays xdp_exception tracepoint events\n"
|
||||
" \t\t\tThis can occur due to internal driver errors, unrecognized\n"
|
||||
" \t\t\tXDP actions and due to explicit user trigger by use of XDP_ABORTED\n"
|
||||
" \t\t\tEach action is expanded below this field with its count\n"
|
||||
" \t\t\t\thit/s - Number of times the tracepoint was hit per second\n\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void sample_usage(char *argv[], const struct option *long_options,
|
||||
@ -327,9 +357,26 @@ static struct stats_record *alloc_stats_record(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sample_mask & SAMPLE_EXCEPTION_CNT) {
|
||||
for (i = 0; i < XDP_ACTION_MAX; i++) {
|
||||
rec->exception[i].cpu = alloc_record_per_cpu();
|
||||
if (!rec->exception[i].cpu) {
|
||||
fprintf(stderr,
|
||||
"Failed to allocate exception per-CPU array for "
|
||||
"\"%s\" case\n",
|
||||
action2str(i));
|
||||
while (i--)
|
||||
free(rec->exception[i].cpu);
|
||||
goto end_redir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rec;
|
||||
|
||||
end_redir:
|
||||
for (i = 0; i < XDP_REDIRECT_ERR_MAX; i++)
|
||||
free(rec->redir_err[i].cpu);
|
||||
end_rx_cnt:
|
||||
free(rec->rx_cnt.cpu);
|
||||
end_rec:
|
||||
@ -343,6 +390,8 @@ static void free_stats_record(struct stats_record *r)
|
||||
struct map_entry *e;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < XDP_ACTION_MAX; i++)
|
||||
free(r->exception[i].cpu);
|
||||
for (i = 0; i < XDP_REDIRECT_ERR_MAX; i++)
|
||||
free(r->redir_err[i].cpu);
|
||||
free(r->rx_cnt.cpu);
|
||||
@ -551,6 +600,50 @@ static void stats_get_redirect_err_cnt(struct stats_record *stats_rec,
|
||||
}
|
||||
}
|
||||
|
||||
static void stats_get_exception_cnt(struct stats_record *stats_rec,
|
||||
struct stats_record *stats_prev,
|
||||
unsigned int nr_cpus,
|
||||
struct sample_output *out)
|
||||
{
|
||||
double t, drop, sum = 0;
|
||||
struct record *rec, *prev;
|
||||
int rec_i, i;
|
||||
|
||||
for (rec_i = 0; rec_i < XDP_ACTION_MAX; rec_i++) {
|
||||
rec = &stats_rec->exception[rec_i];
|
||||
prev = &stats_prev->exception[rec_i];
|
||||
t = calc_period(rec, prev);
|
||||
|
||||
drop = calc_drop_pps(&rec->total, &prev->total, t);
|
||||
/* Fold out errors after heading */
|
||||
sum += drop;
|
||||
|
||||
if (drop > 0 && !out) {
|
||||
print_always(" %-18s " FMT_COLUMNf "\n",
|
||||
action2str(rec_i), ERR(drop));
|
||||
|
||||
for (i = 0; i < nr_cpus; i++) {
|
||||
struct datarec *r = &rec->cpu[i];
|
||||
struct datarec *p = &prev->cpu[i];
|
||||
char str[64];
|
||||
double drop;
|
||||
|
||||
drop = calc_drop_pps(r, p, t);
|
||||
if (!drop)
|
||||
continue;
|
||||
|
||||
snprintf(str, sizeof(str), "cpu:%d", i);
|
||||
print_default(" %-16s" FMT_COLUMNf "\n",
|
||||
str, ERR(drop));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (out) {
|
||||
out->except_cnt.hits = sum;
|
||||
out->totals.err += sum;
|
||||
}
|
||||
}
|
||||
|
||||
static void stats_print(const char *prefix, int mask, struct stats_record *r,
|
||||
struct stats_record *p, struct sample_output *out)
|
||||
@ -595,6 +688,16 @@ static void stats_print(const char *prefix, int mask, struct stats_record *r,
|
||||
stats_get_redirect_err_cnt(r, p, nr_cpus, NULL);
|
||||
}
|
||||
|
||||
if (mask & SAMPLE_EXCEPTION_CNT) {
|
||||
str = out->except_cnt.hits ? "xdp_exception total" :
|
||||
"xdp_exception";
|
||||
|
||||
print_err(out->except_cnt.hits, " %-20s " FMT_COLUMNl "\n", str,
|
||||
HITS(out->except_cnt.hits));
|
||||
|
||||
stats_get_exception_cnt(r, p, nr_cpus, NULL);
|
||||
}
|
||||
|
||||
if (sample_log_level & LL_DEFAULT ||
|
||||
((sample_log_level & LL_SIMPLE) && sample_err_exp)) {
|
||||
sample_err_exp = false;
|
||||
@ -617,6 +720,9 @@ int sample_setup_maps(struct bpf_map **maps)
|
||||
sample_map_count[i] =
|
||||
XDP_REDIRECT_ERR_MAX * sample_n_cpus;
|
||||
break;
|
||||
case MAP_EXCEPTION:
|
||||
sample_map_count[i] = XDP_ACTION_MAX * sample_n_cpus;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -788,6 +894,11 @@ static int sample_stats_collect(struct stats_record *rec)
|
||||
&rec->redir_err[i]);
|
||||
}
|
||||
|
||||
if (sample_mask & SAMPLE_EXCEPTION_CNT)
|
||||
for (i = 0; i < XDP_ACTION_MAX; i++)
|
||||
map_collect_percpu(&sample_mmap[MAP_EXCEPTION][i * sample_n_cpus],
|
||||
&rec->exception[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -811,6 +922,8 @@ static void sample_stats_print(int mask, struct stats_record *cur,
|
||||
stats_get_redirect_cnt(cur, prev, 0, &out);
|
||||
if (mask & SAMPLE_REDIRECT_ERR_CNT)
|
||||
stats_get_redirect_err_cnt(cur, prev, 0, &out);
|
||||
if (mask & SAMPLE_EXCEPTION_CNT)
|
||||
stats_get_exception_cnt(cur, prev, 0, &out);
|
||||
sample_summary_update(&out, interval);
|
||||
|
||||
stats_print(prog_name, mask, cur, prev, &out);
|
||||
|
@ -11,6 +11,7 @@ enum stats_mask {
|
||||
_SAMPLE_REDIRECT_MAP = 1U << 0,
|
||||
SAMPLE_RX_CNT = 1U << 1,
|
||||
SAMPLE_REDIRECT_ERR_CNT = 1U << 2,
|
||||
SAMPLE_EXCEPTION_CNT = 1U << 5,
|
||||
SAMPLE_REDIRECT_CNT = 1U << 7,
|
||||
SAMPLE_REDIRECT_MAP_CNT = SAMPLE_REDIRECT_CNT | _SAMPLE_REDIRECT_MAP,
|
||||
SAMPLE_REDIRECT_ERR_MAP_CNT = SAMPLE_REDIRECT_ERR_CNT | _SAMPLE_REDIRECT_MAP,
|
||||
@ -75,6 +76,8 @@ static inline char *safe_strncpy(char *dst, const char *src, size_t size)
|
||||
__attach_tp(tp_xdp_redirect_map_err); \
|
||||
if (mask & SAMPLE_REDIRECT_ERR_CNT) \
|
||||
__attach_tp(tp_xdp_redirect_err); \
|
||||
if (mask & SAMPLE_EXCEPTION_CNT) \
|
||||
__attach_tp(tp_xdp_exception); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user