Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Integrate verbose verifier log into test_progs

Add exra level of verboseness, activated by -vvv argument. When -vv is
specified, verbose libbpf and verifier log (level 1) is output, even for
successful tests. With -vvv, verifier log goes to level 2.

This is extremely useful to debug verifier failures, as well as just see the
state and flow of verification. Before this, you'd have to go and modify
load_program()'s source code inside libbpf to specify extra log_level flags,
which is suboptimal to say the least.

Currently -vv and -vvv triggering verifier output is integrated into
test_stub's bpf_prog_load as well as bpf_verif_scale.c tests.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20191120003548.4159797-1-andriin@fb.com

authored by

Andrii Nakryiko and committed by
Alexei Starovoitov
a8fdaad5 5940c5bf

+27 -9
+3 -1
tools/testing/selftests/bpf/prog_tests/bpf_verif_scale.c
··· 15 15 return 0; 16 16 } 17 17 18 + extern int extra_prog_load_log_flags; 19 + 18 20 static int check_load(const char *file, enum bpf_prog_type type) 19 21 { 20 22 struct bpf_prog_load_attr attr; ··· 26 24 memset(&attr, 0, sizeof(struct bpf_prog_load_attr)); 27 25 attr.file = file; 28 26 attr.prog_type = type; 29 - attr.log_level = 4; 27 + attr.log_level = 4 | extra_prog_load_log_flags; 30 28 attr.prog_flags = BPF_F_TEST_RND_HI32; 31 29 err = bpf_prog_load_xattr(&attr, &obj, &prog_fd); 32 30 bpf_object__close(obj);
+12 -6
tools/testing/selftests/bpf/test_progs.c
··· 45 45 46 46 fflush(stdout); /* exports env.log_buf & env.log_cnt */ 47 47 48 - if (env.verbose || test->force_log || failed) { 48 + if (env.verbosity > VERBOSE_NONE || test->force_log || failed) { 49 49 if (env.log_cnt) { 50 50 env.log_buf[env.log_cnt] = '\0'; 51 51 fprintf(env.stdout, "%s", env.log_buf); ··· 346 346 { "verifier-stats", ARG_VERIFIER_STATS, NULL, 0, 347 347 "Output verifier statistics", }, 348 348 { "verbose", ARG_VERBOSE, "LEVEL", OPTION_ARG_OPTIONAL, 349 - "Verbose output (use -vv for extra verbose output)" }, 349 + "Verbose output (use -vv or -vvv for progressively verbose output)" }, 350 350 {}, 351 351 }; 352 352 353 353 static int libbpf_print_fn(enum libbpf_print_level level, 354 354 const char *format, va_list args) 355 355 { 356 - if (!env.very_verbose && level == LIBBPF_DEBUG) 356 + if (env.verbosity < VERBOSE_VERY && level == LIBBPF_DEBUG) 357 357 return 0; 358 358 vprintf(format, args); 359 359 return 0; ··· 419 419 return 0; 420 420 } 421 421 422 + extern int extra_prog_load_log_flags; 423 + 422 424 static error_t parse_arg(int key, char *arg, struct argp_state *state) 423 425 { 424 426 struct test_env *env = state->input; ··· 462 460 env->verifier_stats = true; 463 461 break; 464 462 case ARG_VERBOSE: 463 + env->verbosity = VERBOSE_NORMAL; 465 464 if (arg) { 466 465 if (strcmp(arg, "v") == 0) { 467 - env->very_verbose = true; 466 + env->verbosity = VERBOSE_VERY; 467 + extra_prog_load_log_flags = 1; 468 + } else if (strcmp(arg, "vv") == 0) { 469 + env->verbosity = VERBOSE_SUPER; 470 + extra_prog_load_log_flags = 2; 468 471 } else { 469 472 fprintf(stderr, 470 473 "Unrecognized verbosity setting ('%s'), only -v and -vv are supported\n", ··· 477 470 return -EINVAL; 478 471 } 479 472 } 480 - env->verbose = true; 481 473 break; 482 474 case ARGP_KEY_ARG: 483 475 argp_usage(state); ··· 495 489 env.stdout = stdout; 496 490 env.stderr = stderr; 497 491 498 - if (env.verbose) { 492 + if (env.verbosity > VERBOSE_NONE) { 499 493 /* nothing to do, output to stdout by default */ 500 494 return; 501 495 }
+8 -2
tools/testing/selftests/bpf/test_progs.h
··· 39 39 #include "trace_helpers.h" 40 40 #include "flow_dissector_load.h" 41 41 42 + enum verbosity { 43 + VERBOSE_NONE, 44 + VERBOSE_NORMAL, 45 + VERBOSE_VERY, 46 + VERBOSE_SUPER, 47 + }; 48 + 42 49 struct test_selector { 43 50 const char *name; 44 51 bool *num_set; ··· 56 49 struct test_selector test_selector; 57 50 struct test_selector subtest_selector; 58 51 bool verifier_stats; 59 - bool verbose; 60 - bool very_verbose; 52 + enum verbosity verbosity; 61 53 62 54 bool jit_enabled; 63 55
+4
tools/testing/selftests/bpf/test_stub.c
··· 5 5 #include <bpf/libbpf.h> 6 6 #include <string.h> 7 7 8 + int extra_prog_load_log_flags = 0; 9 + 8 10 int bpf_prog_test_load(const char *file, enum bpf_prog_type type, 9 11 struct bpf_object **pobj, int *prog_fd) 10 12 { ··· 17 15 attr.prog_type = type; 18 16 attr.expected_attach_type = 0; 19 17 attr.prog_flags = BPF_F_TEST_RND_HI32; 18 + attr.log_level = extra_prog_load_log_flags; 20 19 21 20 return bpf_prog_load_xattr(&attr, pobj, prog_fd); 22 21 } ··· 38 35 load_attr.license = license; 39 36 load_attr.kern_version = kern_version; 40 37 load_attr.prog_flags = BPF_F_TEST_RND_HI32; 38 + load_attr.log_level = extra_prog_load_log_flags; 41 39 42 40 return bpf_load_program_xattr(&load_attr, log_buf, log_buf_sz); 43 41 }