diff mbox series

[RFC,bpf-next,1/2] bpf: add verifier stats to bpf_prog_info and fdinfo

Message ID 20210920151112.3770991-2-davemarchevsky@fb.com (mailing list archive)
State RFC
Delegated to: BPF
Headers show
Series bpf: keep track of prog verification stats | expand

Checks

Context Check Description
bpf/vmtest-bpf-next pending VM_Test
bpf/vmtest-bpf-next-PR pending PR summary
netdev/cover_letter success Link
netdev/fixes_present success Link
netdev/patch_count success Link
netdev/tree_selection success Clearly marked for bpf-next
netdev/subject_prefix success Link
netdev/cc_maintainers warning 8 maintainers not CCed: kpsingh@kernel.org john.fastabend@gmail.com haoluo@google.com jackmanb@google.com joe@cilium.io songliubraving@fb.com brouer@redhat.com kafai@fb.com
netdev/source_inline success Was 0 now: 0
netdev/verify_signedoff success Link
netdev/module_param success Was 0 now: 0
netdev/build_32bit success Errors and warnings before: 11843 this patch: 11843
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/verify_fixes success Link
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 123 lines checked
netdev/build_allmodconfig_warn success Errors and warnings before: 11501 this patch: 11501
netdev/header_inline success Link

Commit Message

Dave Marchevsky Sept. 20, 2021, 3:11 p.m. UTC
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(-)
diff mbox series

Patch

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 {