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

selftests: bpf: use __stderr in stream error tests

Start using __stderr directly in the bpf programs to test the reporting
of may_goto timeout detection and spin_lock dead lock detection.

Signed-off-by: Puranjay Mohan <puranjay@kernel.org>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20250911145808.58042-6-puranjay@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Puranjay Mohan and committed by
Alexei Starovoitov
edd03fcd 744eeb2b

+17 -82
-82
tools/testing/selftests/bpf/prog_tests/stream.c
··· 2 2 /* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */ 3 3 #include <test_progs.h> 4 4 #include <sys/mman.h> 5 - #include <regex.h> 6 5 7 6 #include "stream.skel.h" 8 7 #include "stream_fail.skel.h" ··· 15 16 { 16 17 RUN_TESTS(stream); 17 18 return; 18 - } 19 - 20 - struct { 21 - int prog_off; 22 - const char *errstr; 23 - } stream_error_arr[] = { 24 - { 25 - offsetof(struct stream, progs.stream_cond_break), 26 - "ERROR: Timeout detected for may_goto instruction\n" 27 - "CPU: [0-9]+ UID: 0 PID: [0-9]+ Comm: .*\n" 28 - "Call trace:\n" 29 - "([a-zA-Z_][a-zA-Z0-9_]*\\+0x[0-9a-fA-F]+/0x[0-9a-fA-F]+\n" 30 - "|[ \t]+[^\n]+\n)*", 31 - }, 32 - { 33 - offsetof(struct stream, progs.stream_deadlock), 34 - "ERROR: AA or ABBA deadlock detected for bpf_res_spin_lock\n" 35 - "Attempted lock = (0x[0-9a-fA-F]+)\n" 36 - "Total held locks = 1\n" 37 - "Held lock\\[ 0\\] = \\1\n" // Lock address must match 38 - "CPU: [0-9]+ UID: 0 PID: [0-9]+ Comm: .*\n" 39 - "Call trace:\n" 40 - "([a-zA-Z_][a-zA-Z0-9_]*\\+0x[0-9a-fA-F]+/0x[0-9a-fA-F]+\n" 41 - "|[ \t]+[^\n]+\n)*", 42 - }, 43 - }; 44 - 45 - static int match_regex(const char *pattern, const char *string) 46 - { 47 - int err, rc; 48 - regex_t re; 49 - 50 - err = regcomp(&re, pattern, REG_EXTENDED | REG_NEWLINE); 51 - if (err) 52 - return -1; 53 - rc = regexec(&re, string, 0, NULL, 0); 54 - regfree(&re); 55 - return rc == 0 ? 1 : 0; 56 - } 57 - 58 - void test_stream_errors(void) 59 - { 60 - LIBBPF_OPTS(bpf_test_run_opts, opts); 61 - LIBBPF_OPTS(bpf_prog_stream_read_opts, ropts); 62 - struct stream *skel; 63 - int ret, prog_fd; 64 - char buf[1024]; 65 - 66 - skel = stream__open_and_load(); 67 - if (!ASSERT_OK_PTR(skel, "stream__open_and_load")) 68 - return; 69 - 70 - for (int i = 0; i < ARRAY_SIZE(stream_error_arr); i++) { 71 - struct bpf_program **prog; 72 - 73 - prog = (struct bpf_program **)(((char *)skel) + stream_error_arr[i].prog_off); 74 - prog_fd = bpf_program__fd(*prog); 75 - ret = bpf_prog_test_run_opts(prog_fd, &opts); 76 - ASSERT_OK(ret, "ret"); 77 - ASSERT_OK(opts.retval, "retval"); 78 - 79 - #if !defined(__x86_64__) && !defined(__s390x__) && !defined(__aarch64__) 80 - ASSERT_TRUE(1, "Timed may_goto unsupported, skip."); 81 - if (i == 0) { 82 - ret = bpf_prog_stream_read(prog_fd, 2, buf, sizeof(buf), &ropts); 83 - ASSERT_EQ(ret, 0, "stream read"); 84 - continue; 85 - } 86 - #endif 87 - 88 - ret = bpf_prog_stream_read(prog_fd, BPF_STREAM_STDERR, buf, sizeof(buf), &ropts); 89 - ASSERT_GT(ret, 0, "stream read"); 90 - ASSERT_LE(ret, 1023, "len for buf"); 91 - buf[ret] = '\0'; 92 - 93 - ret = match_regex(stream_error_arr[i].errstr, buf); 94 - if (!ASSERT_TRUE(ret == 1, "regex match")) 95 - fprintf(stderr, "Output from stream:\n%s\n", buf); 96 - } 97 - 98 - stream__destroy(skel); 99 19 } 100 20 101 21 void test_stream_syscall(void)
+17
tools/testing/selftests/bpf/progs/stream.c
··· 37 37 } 38 38 39 39 SEC("syscall") 40 + __arch_x86_64 41 + __arch_arm64 42 + __arch_s390x 40 43 __success __retval(0) 44 + __stderr("ERROR: Timeout detected for may_goto instruction") 45 + __stderr("CPU: {{[0-9]+}} UID: 0 PID: {{[0-9]+}} Comm: {{.*}}") 46 + __stderr("Call trace:\n" 47 + "{{([a-zA-Z_][a-zA-Z0-9_]*\\+0x[0-9a-fA-F]+/0x[0-9a-fA-F]+\n" 48 + "|[ \t]+[^\n]+\n)*}}") 41 49 int stream_cond_break(void *ctx) 42 50 { 43 51 while (can_loop) ··· 55 47 56 48 SEC("syscall") 57 49 __success __retval(0) 50 + __stderr("ERROR: AA or ABBA deadlock detected for bpf_res_spin_lock") 51 + __stderr("{{Attempted lock = (0x[0-9a-fA-F]+)\n" 52 + "Total held locks = 1\n" 53 + "Held lock\\[ 0\\] = \\1}}") 54 + __stderr("...") 55 + __stderr("CPU: {{[0-9]+}} UID: 0 PID: {{[0-9]+}} Comm: {{.*}}") 56 + __stderr("Call trace:\n" 57 + "{{([a-zA-Z_][a-zA-Z0-9_]*\\+0x[0-9a-fA-F]+/0x[0-9a-fA-F]+\n" 58 + "|[ \t]+[^\n]+\n)*}}") 58 59 int stream_deadlock(void *ctx) 59 60 { 60 61 struct bpf_res_spin_lock *lock, *nlock;