@@ -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 */
@@ -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 {
@@ -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;
@@ -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;
@@ -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 {
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@fb.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(-)