[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20210920151112.3770991-2-davemarchevsky@fb.com>
Date: Mon, 20 Sep 2021 08:11:11 -0700
From: Dave Marchevsky <davemarchevsky@...com>
To: <bpf@...r.kernel.org>
CC: <netdev@...r.kernel.org>, Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
Andrii Nakryiko <andrii@...nel.org>,
Yonghong Song <yhs@...com>,
Dave Marchevsky <davemarchevsky@...com>
Subject: [RFC PATCH bpf-next 1/2] bpf: add verifier stats to bpf_prog_info and fdinfo
These stats are currently printed in the verifier log and not stored
anywhere. To ease consumption of this data, add a bpf_prog_verif_stats
struct to bpf_prog_aux so they can be exposed via BPF_OBJ_GET_INFO_BY_FD
and fdinfo.
Signed-off-by: Dave Marchevsky <davemarchevsky@...com>
---
include/linux/bpf.h | 1 +
include/uapi/linux/bpf.h | 10 ++++++++++
kernel/bpf/syscall.c | 20 ++++++++++++++++++--
kernel/bpf/verifier.c | 13 +++++++++++++
tools/include/uapi/linux/bpf.h | 10 ++++++++++
5 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index b6c45a6cbbba..206c19b253b7 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -876,6 +876,7 @@ struct bpf_prog_aux {
struct bpf_kfunc_desc_tab *kfunc_tab;
u32 size_poke_tab;
struct bpf_ksym ksym;
+ struct bpf_prog_verif_stats verif_stats;
const struct bpf_prog_ops *ops;
struct bpf_map **used_maps;
struct mutex used_maps_mutex; /* mutex for used_maps and used_map_cnt */
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 6fc59d61937a..cb0fa49e62d7 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -5576,6 +5576,15 @@ struct sk_reuseport_md {
#define BPF_TAG_SIZE 8
+struct bpf_prog_verif_stats {
+ __u64 verification_time;
+ __u32 insn_processed;
+ __u32 max_states_per_insn;
+ __u32 total_states;
+ __u32 peak_states;
+ __u32 longest_mark_read_walk;
+};
+
struct bpf_prog_info {
__u32 type;
__u32 id;
@@ -5613,6 +5622,7 @@ struct bpf_prog_info {
__u64 run_time_ns;
__u64 run_cnt;
__u64 recursion_misses;
+ struct bpf_prog_verif_stats verif_stats;
} __attribute__((aligned(8)));
struct bpf_map_info {
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 4e50c0bfdb7d..0fa95ebd4276 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1836,9 +1836,11 @@ static void bpf_prog_show_fdinfo(struct seq_file *m, struct file *filp)
{
const struct bpf_prog *prog = filp->private_data;
char prog_tag[sizeof(prog->tag) * 2 + 1] = { };
+ struct bpf_prog_verif_stats *verif_stats;
struct bpf_prog_stats stats;
bpf_prog_get_stats(prog, &stats);
+ verif_stats = &prog->aux->verif_stats;
bin2hex(prog_tag, prog->tag, sizeof(prog->tag));
seq_printf(m,
"prog_type:\t%u\n"
@@ -1848,7 +1850,13 @@ static void bpf_prog_show_fdinfo(struct seq_file *m, struct file *filp)
"prog_id:\t%u\n"
"run_time_ns:\t%llu\n"
"run_cnt:\t%llu\n"
- "recursion_misses:\t%llu\n",
+ "recursion_misses:\t%llu\n"
+ "verification_time:\t%llu\n"
+ "verif_insn_processed:\t%u\n"
+ "verif_max_states_per_insn:\t%u\n"
+ "verif_total_states:\t%u\n"
+ "verif_peak_states:\t%u\n"
+ "verif_longest_mark_read_walk:\t%u\n",
prog->type,
prog->jited,
prog_tag,
@@ -1856,7 +1864,13 @@ static void bpf_prog_show_fdinfo(struct seq_file *m, struct file *filp)
prog->aux->id,
stats.nsecs,
stats.cnt,
- stats.misses);
+ stats.misses,
+ verif_stats->verification_time,
+ verif_stats->insn_processed,
+ verif_stats->max_states_per_insn,
+ verif_stats->total_states,
+ verif_stats->peak_states,
+ verif_stats->longest_mark_read_walk);
}
#endif
@@ -3625,6 +3639,8 @@ static int bpf_prog_get_info_by_fd(struct file *file,
info.run_cnt = stats.cnt;
info.recursion_misses = stats.misses;
+ info.verif_stats = prog->aux->verif_stats;
+
if (!bpf_capable()) {
info.jited_prog_len = 0;
info.xlated_prog_len = 0;
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index e76b55917905..97cd3b71d5ae 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -13245,6 +13245,18 @@ static void print_verification_stats(struct bpf_verifier_env *env)
env->peak_states, env->longest_mark_read_walk);
}
+static void populate_aux_verif_stats(struct bpf_verifier_env *env)
+{
+ struct bpf_prog_verif_stats *verif_stats = &env->prog->aux->verif_stats;
+
+ verif_stats->verification_time = env->verification_time;
+ verif_stats->insn_processed = env->insn_processed;
+ verif_stats->max_states_per_insn = env->max_states_per_insn;
+ verif_stats->total_states = env->total_states;
+ verif_stats->peak_states = env->peak_states;
+ verif_stats->longest_mark_read_walk = env->longest_mark_read_walk;
+}
+
static int check_struct_ops_btf_id(struct bpf_verifier_env *env)
{
const struct btf_type *t, *func_proto;
@@ -13826,6 +13838,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr)
env->verification_time = ktime_get_ns() - start_time;
print_verification_stats(env);
+ populate_aux_verif_stats(env);
if (log->level && bpf_verifier_log_full(log))
ret = -ENOSPC;
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 6fc59d61937a..cb0fa49e62d7 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -5576,6 +5576,15 @@ struct sk_reuseport_md {
#define BPF_TAG_SIZE 8
+struct bpf_prog_verif_stats {
+ __u64 verification_time;
+ __u32 insn_processed;
+ __u32 max_states_per_insn;
+ __u32 total_states;
+ __u32 peak_states;
+ __u32 longest_mark_read_walk;
+};
+
struct bpf_prog_info {
__u32 type;
__u32 id;
@@ -5613,6 +5622,7 @@ struct bpf_prog_info {
__u64 run_time_ns;
__u64 run_cnt;
__u64 recursion_misses;
+ struct bpf_prog_verif_stats verif_stats;
} __attribute__((aligned(8)));
struct bpf_map_info {
--
2.30.2
Powered by blists - more mailing lists