diff --git a/ci/diffs/0399-selftests-bpf-fix-for-bpf_signal-stalls-watchdog-for.patch b/ci/diffs/0399-selftests-bpf-fix-for-bpf_signal-stalls-watchdog-for.patch deleted file mode 100644 index 601f1bad..00000000 --- a/ci/diffs/0399-selftests-bpf-fix-for-bpf_signal-stalls-watchdog-for.patch +++ /dev/null @@ -1,445 +0,0 @@ -From f66e9f529d6b5bc2f630e498e41f8118b6554070 Mon Sep 17 00:00:00 2001 -From: Eduard Zingerman -Date: Tue, 12 Nov 2024 03:09:02 -0800 -Subject: [PATCH] selftests/bpf: fix for bpf_signal stalls, watchdog for - test_progs - -Test case 'bpf_signal' had been recently reported to stall, both on -the mailing list [1] and CI [2]. The stall is caused by CPU cycles -perf event not being delivered within expected time frame, before test -process enters system call and waits indefinitely. - -This patch-set addresses the issue in several ways: -- A watchdog timer is added to test_progs.c runner: - - it prints current sub-test name to stderr if sub-test takes longer - than 10 seconds to finish; - - it terminates process executing sub-test if sub-test takes longer - than 120 seconds to finish. -- The test case is updated to await perf event notification with a - timeout and a few retries, this serves two purposes: - - busy loops longer to increase the time frame for CPU cycles event - generation/delivery; - - makes a timeout, not stall, a worst case scenario. -- The test case is updated to lower frequency of perf events, as high - frequency of such events caused events generation throttling, - which in turn delayed events delivery by amount of time sufficient - to cause test case failure. - -Note: - - librt pthread-based timer API is used to implement watchdog timer. - I chose this API over SIGALRM because signal handler execution - within test process context was sufficient to trigger perf event - delivery for send_signal/send_signal_nmi_thread_remote test case, - w/o any additional changes. Thus I concluded that SIGALRM based - implementation interferes with tests execution. - -[1] https://lore.kernel.org/bpf/CAP01T75OUeE8E-Lw9df84dm8ag2YmHW619f1DmPSVZ5_O89+Bg@mail.gmail.com/ -[2] https://github.com/kernel-patches/bpf/actions/runs/11791485271/job/32843996871 - -Eduard Zingerman (4): - selftests/bpf: watchdog timer for test_progs - selftests/bpf: add read_with_timeout() utility function - selftests/bpf: allow send_signal test to timeout - selftests/bpf: update send_signal to lower perf evemts frequency - - tools/testing/selftests/bpf/Makefile | 1 + - tools/testing/selftests/bpf/io_helpers.c | 21 ++++ - tools/testing/selftests/bpf/io_helpers.h | 7 ++ - .../selftests/bpf/prog_tests/bpf_iter.c | 8 +- - .../testing/selftests/bpf/prog_tests/iters.c | 4 +- - .../selftests/bpf/prog_tests/send_signal.c | 35 +++--- - tools/testing/selftests/bpf/test_progs.c | 104 ++++++++++++++++++ - tools/testing/selftests/bpf/test_progs.h | 6 + - 8 files changed, 166 insertions(+), 20 deletions(-) - create mode 100644 tools/testing/selftests/bpf/io_helpers.c - create mode 100644 tools/testing/selftests/bpf/io_helpers.h - --- -2.47.0 ---- - tools/testing/selftests/bpf/Makefile | 1 + - tools/testing/selftests/bpf/io_helpers.c | 21 ++++ - tools/testing/selftests/bpf/io_helpers.h | 7 ++ - .../selftests/bpf/prog_tests/bpf_iter.c | 8 +- - .../testing/selftests/bpf/prog_tests/iters.c | 4 +- - .../selftests/bpf/prog_tests/send_signal.c | 35 +++--- - tools/testing/selftests/bpf/test_progs.c | 104 ++++++++++++++++++ - tools/testing/selftests/bpf/test_progs.h | 6 + - 8 files changed, 166 insertions(+), 20 deletions(-) - create mode 100644 tools/testing/selftests/bpf/io_helpers.c - create mode 100644 tools/testing/selftests/bpf/io_helpers.h - -diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile -index edef5df08cb2..b1080284522d 100644 ---- a/tools/testing/selftests/bpf/Makefile -+++ b/tools/testing/selftests/bpf/Makefile -@@ -742,6 +742,7 @@ TRUNNER_EXTRA_SOURCES := test_progs.c \ - unpriv_helpers.c \ - netlink_helpers.c \ - jit_disasm_helpers.c \ -+ io_helpers.c \ - test_loader.c \ - xsk.c \ - disasm.c \ -diff --git a/tools/testing/selftests/bpf/io_helpers.c b/tools/testing/selftests/bpf/io_helpers.c -new file mode 100644 -index 000000000000..4ada0a74aa1f ---- /dev/null -+++ b/tools/testing/selftests/bpf/io_helpers.c -@@ -0,0 +1,21 @@ -+// SPDX-License-Identifier: GPL-2.0 -+#include -+#include -+#include -+ -+int read_with_timeout(int fd, char *buf, size_t count, long usec) -+{ -+ const long M = 1000 * 1000; -+ struct timeval tv = { usec / M, usec % M }; -+ fd_set fds; -+ int err; -+ -+ FD_ZERO(&fds); -+ FD_SET(fd, &fds); -+ err = select(fd + 1, &fds, NULL, NULL, &tv); -+ if (err < 0) -+ return err; -+ if (FD_ISSET(fd, &fds)) -+ return read(fd, buf, count); -+ return -EAGAIN; -+} -diff --git a/tools/testing/selftests/bpf/io_helpers.h b/tools/testing/selftests/bpf/io_helpers.h -new file mode 100644 -index 000000000000..21e1134cd3ce ---- /dev/null -+++ b/tools/testing/selftests/bpf/io_helpers.h -@@ -0,0 +1,7 @@ -+// SPDX-License-Identifier: GPL-2.0 -+#include -+ -+/* As a regular read(2), but allows to specify a timeout in micro-seconds. -+ * Returns -EAGAIN on timeout. -+ */ -+int read_with_timeout(int fd, char *buf, size_t count, long usec); -diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c -index b8e1224cfd19..6f1bfacd7375 100644 ---- a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c -+++ b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c -@@ -265,10 +265,10 @@ static void *run_test_task_tid(void *arg) - - linfo.task.tid = 0; - linfo.task.pid = getpid(); -- /* This includes the parent thread, this thread, -+ /* This includes the parent thread, this thread, watchdog timer thread - * and the do_nothing_wait thread - */ -- test_task_common(&opts, 2, 1); -+ test_task_common(&opts, 3, 1); - - test_task_common_nocheck(NULL, &num_unknown_tid, &num_known_tid); - ASSERT_GT(num_unknown_tid, 2, "check_num_unknown_tid"); -@@ -297,7 +297,7 @@ static void test_task_pid(void) - opts.link_info = &linfo; - opts.link_info_len = sizeof(linfo); - -- test_task_common(&opts, 1, 1); -+ test_task_common(&opts, 2, 1); - } - - static void test_task_pidfd(void) -@@ -315,7 +315,7 @@ static void test_task_pidfd(void) - opts.link_info = &linfo; - opts.link_info_len = sizeof(linfo); - -- test_task_common(&opts, 1, 1); -+ test_task_common(&opts, 2, 1); - - close(pidfd); - } -diff --git a/tools/testing/selftests/bpf/prog_tests/iters.c b/tools/testing/selftests/bpf/prog_tests/iters.c -index 89ff23c4a8bc..3cea71f9c500 100644 ---- a/tools/testing/selftests/bpf/prog_tests/iters.c -+++ b/tools/testing/selftests/bpf/prog_tests/iters.c -@@ -192,8 +192,8 @@ static void subtest_task_iters(void) - syscall(SYS_getpgid); - iters_task__detach(skel); - ASSERT_EQ(skel->bss->procs_cnt, 1, "procs_cnt"); -- ASSERT_EQ(skel->bss->threads_cnt, thread_num + 1, "threads_cnt"); -- ASSERT_EQ(skel->bss->proc_threads_cnt, thread_num + 1, "proc_threads_cnt"); -+ ASSERT_EQ(skel->bss->threads_cnt, thread_num + 2, "threads_cnt"); -+ ASSERT_EQ(skel->bss->proc_threads_cnt, thread_num + 2, "proc_threads_cnt"); - ASSERT_EQ(skel->bss->invalid_cnt, 0, "invalid_cnt"); - pthread_mutex_unlock(&do_nothing_mutex); - for (int i = 0; i < thread_num; i++) -diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c -index 1aed94ec14ef..1702aa592c2c 100644 ---- a/tools/testing/selftests/bpf/prog_tests/send_signal.c -+++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c -@@ -3,6 +3,7 @@ - #include - #include - #include "test_send_signal_kern.skel.h" -+#include "io_helpers.h" - - static int sigusr1_received; - -@@ -24,6 +25,7 @@ static void test_send_signal_common(struct perf_event_attr *attr, - int pipe_c2p[2], pipe_p2c[2]; - int err = -1, pmu_fd = -1; - volatile int j = 0; -+ int retry_count; - char buf[256]; - pid_t pid; - int old_prio; -@@ -163,21 +165,25 @@ static void test_send_signal_common(struct perf_event_attr *attr, - /* notify child that bpf program can send_signal now */ - ASSERT_EQ(write(pipe_p2c[1], buf, 1), 1, "pipe_write"); - -- /* For the remote test, the BPF program is triggered from this -- * process but the other process/thread is signaled. -- */ -- if (remote) { -- if (!attr) { -- for (int i = 0; i < 10; i++) -- usleep(1); -- } else { -- for (int i = 0; i < 100000000; i++) -- j /= i + 1; -+ for (retry_count = 0;;) { -+ /* For the remote test, the BPF program is triggered from this -+ * process but the other process/thread is signaled. -+ */ -+ if (remote) { -+ if (!attr) { -+ for (int i = 0; i < 10; i++) -+ usleep(1); -+ } else { -+ for (int i = 0; i < 100000000; i++) -+ j /= i + 1; -+ } - } -+ /* wait for result */ -+ err = read_with_timeout(pipe_c2p[0], buf, 1, 100); -+ if (err == -EAGAIN && retry_count++ < 10000) -+ continue; -+ break; - } -- -- /* wait for result */ -- err = read(pipe_c2p[0], buf, 1); - if (!ASSERT_GE(err, 0, "reading pipe")) - goto disable_pmu; - if (!ASSERT_GT(err, 0, "reading pipe error: size 0")) { -@@ -223,7 +229,8 @@ static void test_send_signal_perf(bool signal_thread, bool remote) - static void test_send_signal_nmi(bool signal_thread, bool remote) - { - struct perf_event_attr attr = { -- .sample_period = 1, -+ .freq = 1, -+ .sample_freq = 1000, - .type = PERF_TYPE_HARDWARE, - .config = PERF_COUNT_HW_CPU_CYCLES, - }; -diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c -index 7421874380c2..6088d8222d59 100644 ---- a/tools/testing/selftests/bpf/test_progs.c -+++ b/tools/testing/selftests/bpf/test_progs.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - #include "json_writer.h" - - #include "network_helpers.h" -@@ -179,6 +180,88 @@ int usleep(useconds_t usec) - return syscall(__NR_nanosleep, &ts, NULL); - } - -+/* Watchdog timer is started by watchdog_start() and stopped by watchdog_stop(). -+ * If timer is active for longer than env.secs_till_notify, -+ * it prints the name of the current test to the stderr. -+ * If timer is active for longer than env.secs_till_kill, -+ * it kills the thread executing the test by sending a SIGSEGV signal to it. -+ */ -+static void watchdog_timer_func(union sigval sigval) -+{ -+ struct itimerspec timeout = {}; -+ char test_name[256]; -+ int err; -+ -+ if (env.subtest_state) -+ snprintf(test_name, sizeof(test_name), "%s/%s", -+ env.test->test_name, env.subtest_state->name); -+ else -+ snprintf(test_name, sizeof(test_name), "%s", -+ env.test->test_name); -+ -+ switch (env.watchdog_state) { -+ case WD_NOTIFY: -+ fprintf(env.stderr_saved, "WATCHDOG: test case %s executes for %d seconds...\n", -+ test_name, env.secs_till_notify); -+ timeout.it_value.tv_sec = env.secs_till_kill - env.secs_till_notify; -+ env.watchdog_state = WD_KILL; -+ err = timer_settime(env.watchdog, 0, &timeout, NULL); -+ if (err) -+ fprintf(env.stderr_saved, "Failed to arm watchdog timer\n"); -+ break; -+ case WD_KILL: -+ fprintf(env.stderr_saved, -+ "WATCHDOG: test case %s executes for %d seconds, terminating with SIGSEGV\n", -+ test_name, env.secs_till_kill); -+ pthread_kill(env.main_thread, SIGSEGV); -+ break; -+ } -+} -+ -+static void watchdog_start(void) -+{ -+ struct itimerspec timeout = {}; -+ int err; -+ -+ if (env.secs_till_kill == 0) -+ return; -+ if (env.secs_till_notify > 0) { -+ env.watchdog_state = WD_NOTIFY; -+ timeout.it_value.tv_sec = env.secs_till_notify; -+ } else { -+ env.watchdog_state = WD_KILL; -+ timeout.it_value.tv_sec = env.secs_till_kill; -+ } -+ err = timer_settime(env.watchdog, 0, &timeout, NULL); -+ if (err) -+ fprintf(env.stderr_saved, "Failed to start watchdog timer\n"); -+} -+ -+static void watchdog_stop(void) -+{ -+ struct itimerspec timeout = {}; -+ int err; -+ -+ env.watchdog_state = WD_NOTIFY; -+ err = timer_settime(env.watchdog, 0, &timeout, NULL); -+ if (err) -+ fprintf(env.stderr_saved, "Failed to stop watchdog timer\n"); -+} -+ -+static void watchdog_init(void) -+{ -+ struct sigevent watchdog_sev = { -+ .sigev_notify = SIGEV_THREAD, -+ .sigev_notify_function = watchdog_timer_func, -+ }; -+ int err; -+ -+ env.main_thread = pthread_self(); -+ err = timer_create(CLOCK_MONOTONIC, &watchdog_sev, &env.watchdog); -+ if (err) -+ fprintf(stderr, "Failed to initialize watchdog timer\n"); -+} -+ - static bool should_run(struct test_selector *sel, int num, const char *name) - { - int i; -@@ -515,6 +598,7 @@ bool test__start_subtest(const char *subtest_name) - - env.subtest_state = subtest_state; - stdio_hijack_init(&subtest_state->log_buf, &subtest_state->log_cnt); -+ watchdog_start(); - - return true; - } -@@ -780,6 +864,7 @@ enum ARG_KEYS { - ARG_DEBUG = -1, - ARG_JSON_SUMMARY = 'J', - ARG_TRAFFIC_MONITOR = 'm', -+ ARG_WATCHDOG_TIMEOUT = 'w', - }; - - static const struct argp_option opts[] = { -@@ -810,6 +895,8 @@ static const struct argp_option opts[] = { - { "traffic-monitor", ARG_TRAFFIC_MONITOR, "NAMES", 0, - "Monitor network traffic of tests with name matching the pattern (supports '*' wildcard)." }, - #endif -+ { "watchdog-timeout", ARG_WATCHDOG_TIMEOUT, "SECONDS", 0, -+ "Kill the process if tests are not making progress for specified number of seconds." }, - {}, - }; - -@@ -1035,6 +1122,16 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) - true); - break; - #endif -+ case ARG_WATCHDOG_TIMEOUT: -+ env->secs_till_kill = atoi(arg); -+ if (env->secs_till_kill < 0) { -+ fprintf(stderr, "Invalid watchdog timeout: %s.\n", arg); -+ return -EINVAL; -+ } -+ if (env->secs_till_kill < env->secs_till_notify) { -+ env->secs_till_notify = 0; -+ } -+ break; - default: - return ARGP_ERR_UNKNOWN; - } -@@ -1263,10 +1360,12 @@ static void run_one_test(int test_num) - - stdio_hijack(&state->log_buf, &state->log_cnt); - -+ watchdog_start(); - if (test->run_test) - test->run_test(); - else if (test->run_serial_test) - test->run_serial_test(); -+ watchdog_stop(); - - /* ensure last sub-test is finalized properly */ - if (env.subtest_state) -@@ -1707,6 +1806,7 @@ static int worker_main_send_subtests(int sock, struct test_state *state) - static int worker_main(int sock) - { - save_netns(); -+ watchdog_init(); - - while (true) { - /* receive command */ -@@ -1816,6 +1916,8 @@ int main(int argc, char **argv) - - sigaction(SIGSEGV, &sigact, NULL); - -+ env.secs_till_notify = 10; -+ env.secs_till_kill = 120; - err = argp_parse(&argp, argc, argv, 0, NULL, &env); - if (err) - return err; -@@ -1824,6 +1926,8 @@ int main(int argc, char **argv) - if (err) - return err; - -+ watchdog_init(); -+ - /* Use libbpf 1.0 API mode */ - libbpf_set_strict_mode(LIBBPF_STRICT_ALL); - libbpf_set_print(libbpf_print_fn); -diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h -index 7a58895867c3..74de33ae37e5 100644 ---- a/tools/testing/selftests/bpf/test_progs.h -+++ b/tools/testing/selftests/bpf/test_progs.h -@@ -131,6 +131,12 @@ struct test_env { - pid_t *worker_pids; /* array of worker pids */ - int *worker_socks; /* array of worker socks */ - int *worker_current_test; /* array of current running test for each worker */ -+ -+ pthread_t main_thread; -+ int secs_till_notify; -+ int secs_till_kill; -+ timer_t watchdog; /* watch for stalled tests/subtests */ -+ enum { WD_NOTIFY, WD_KILL } watchdog_state; - }; - - #define MAX_LOG_TRUNK_SIZE 8192 --- -2.47.0 - diff --git a/ci/vmtest/configs/run_veristat.kernel.cfg b/ci/vmtest/configs/run_veristat.kernel.cfg index e8aada00..807efc25 100644 --- a/ci/vmtest/configs/run_veristat.kernel.cfg +++ b/ci/vmtest/configs/run_veristat.kernel.cfg @@ -1,4 +1,4 @@ -VERISTAT_OBJECTS_DIR="${BPF_SELFTESTS_DIR}" +VERISTAT_OBJECTS_DIR="${SELFTESTS_BPF}" VERISTAT_OBJECTS_GLOB="*.bpf.o" -VERISTAT_CFG_FILE="${BPF_SELFTESTS_DIR}/veristat.cfg" +VERISTAT_CFG_FILE="${SELFTESTS_BPF}/veristat.cfg" VERISTAT_OUTPUT="veristat-kernel" diff --git a/ci/vmtest/helpers.sh b/ci/vmtest/helpers.sh deleted file mode 100755 index 86c734cf..00000000 --- a/ci/vmtest/helpers.sh +++ /dev/null @@ -1,46 +0,0 @@ -# shellcheck shell=bash - -# $1 - start or end -# $2 - fold identifier, no spaces -# $3 - fold section description -foldable() { - local YELLOW='\033[1;33m' - local NOCOLOR='\033[0m' - if [ $1 = "start" ]; then - line="::group::$2" - if [ ! -z "${3:-}" ]; then - line="$line - ${YELLOW}$3${NOCOLOR}" - fi - else - line="::endgroup::" - fi - echo -e "$line" -} - -__print() { - local TITLE="" - if [[ -n $2 ]]; then - TITLE=" title=$2" - fi - echo "::$1${TITLE}::$3" -} - -# $1 - title -# $2 - message -print_error() { - __print error $1 $2 -} - -# $1 - title -# $2 - message -print_notice() { - __print notice $1 $2 -} - -read_lists() { - (for path in "$@"; do - if [[ -s "$path" ]]; then - cat "$path" - fi; - done) | cut -d'#' -f1 | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | tr -s '\n' ',' -} diff --git a/ci/vmtest/run_selftests.sh b/ci/vmtest/run_selftests.sh deleted file mode 100755 index 7f65d46f..00000000 --- a/ci/vmtest/run_selftests.sh +++ /dev/null @@ -1,195 +0,0 @@ -#!/bin/bash - -# run_selftest.sh will run the tests within /${PROJECT_NAME}/selftests/bpf -# If no specific test names are given, all test will be ran, otherwise, it will -# run the test passed as parameters. -# There is 2 ways to pass test names. -# 1) command-line arguments to this script -# 2) a comma-separated list of test names passed as `run_tests` boot parameters. -# test names passed as any of those methods will be ran. - -set -euo pipefail - -source "$(cd "$(dirname "$0")" && pwd)/helpers.sh" - -ARCH=$(uname -m) - -STATUS_FILE=/exitstatus -OUTPUT_DIR=/command_output - -BPF_SELFTESTS_DIR="/${PROJECT_NAME}/selftests/bpf" -VMTEST_CONFIGS_PATH="/${PROJECT_NAME}/vmtest/configs" - -read_lists() { - (for path in "$@"; do - if [[ -s "$path" ]]; then - cat "$path" - fi; - done) | cut -d'#' -f1 | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | tr -s '\n' ',' -} - -DENYLIST=$(read_lists \ - "$BPF_SELFTESTS_DIR/DENYLIST" \ - "$BPF_SELFTESTS_DIR/DENYLIST.${ARCH}" \ - "$VMTEST_CONFIGS_PATH/DENYLIST" \ - "$VMTEST_CONFIGS_PATH/DENYLIST.${ARCH}" \ -) -ALLOWLIST=$(read_lists \ - "$BPF_SELFTESTS_DIR/ALLOWLIST" \ - "$BPF_SELFTESTS_DIR/ALLOWLIST.${ARCH}" \ - "$VMTEST_CONFIGS_PATH/ALLOWLIST" \ - "$VMTEST_CONFIGS_PATH/ALLOWLIST.${ARCH}" \ -) - -declare -a TEST_NAMES=() - -read_test_names() { - foldable start read_test_names "Reading test names from boot parameters and command line arguments" - # Check if test names were passed as boot parameter. - # We expect `run_tests` to be a comma-separated list of test names. - IFS=',' read -r -a test_names_from_boot <<< \ - "$(sed -n 's/.*run_tests=\([^ ]*\).*/\1/p' /proc/cmdline)" - - echo "${#test_names_from_boot[@]} tests extracted from boot parameters: ${test_names_from_boot[*]}" - # Sort and only keep unique test names from both boot params and arguments - # TEST_NAMES will contain a sorted list of uniq tests to be ran. - # Only do this if any of $test_names_from_boot[@] or $@ has elements as - # "printf '%s\0'" will otherwise generate an empty element. - if [[ ${#test_names_from_boot[@]} -gt 0 || $# -gt 0 ]] - then - readarray -t TEST_NAMES < \ - <(printf '%s\0' "${test_names_from_boot[@]}" "$@" | \ - sort --zero-terminated --unique | \ - xargs --null --max-args=1) - fi - foldable end read_test_names -} - -test_progs_helper() { - local selftest="test_progs${1}" - local args="$2" - - json_file=${selftest/-/_} - if [ "$2" == "-j" ] - then - json_file+="_parallel" - fi - json_file="/${json_file}.json" - - foldable start ${selftest} "Testing ${selftest}" - # "&& true" does not change the return code (it is not executed - # if the Python script fails), but it prevents exiting on a - # failure due to the "set -e". - ./${selftest} ${args} ${DENYLIST:+-d"$DENYLIST"} ${ALLOWLIST:+-a"$ALLOWLIST"} --json-summary "${json_file}" && true - echo "${selftest}:$?" >>"${STATUS_FILE}" - foldable end ${selftest} -} - -test_progs() { - test_progs_helper "" "" -} - -test_progs_parallel() { - test_progs_helper "" "-j" -} - -test_progs_no_alu32() { - test_progs_helper "-no_alu32" "" -} - -test_progs_no_alu32_parallel() { - test_progs_helper "-no_alu32" "-j" -} - -test_progs_cpuv4() { - test_progs_helper "-cpuv4" "" -} - -test_maps() { - foldable start test_maps "Testing test_maps" - taskset 0xF ./test_maps && true - echo "test_maps:$?" >>"${STATUS_FILE}" - foldable end test_maps -} - -test_verifier() { - foldable start test_verifier "Testing test_verifier" - ./test_verifier && true - echo "test_verifier:$?" >>"${STATUS_FILE}" - foldable end test_verifier -} - -run_veristat_helper() { - local mode="${1}" - - # Make veristat commands visible in the log - if [ -o xtrace ]; then - xtrace_was_on="1" - else - xtrace_was_on="" - set -x - fi - - ( - # shellcheck source=ci/vmtest/configs/run_veristat.default.cfg - # shellcheck source=ci/vmtest/configs/run_veristat.meta.cfg - source "${VMTEST_CONFIGS_PATH}/run_veristat.${mode}.cfg" - mkdir -p ${OUTPUT_DIR} - pushd "${VERISTAT_OBJECTS_DIR}" - - "${BPF_SELFTESTS_DIR}/veristat" -o csv -q -e file,prog,verdict,states \ - -f "@${VERISTAT_CFG_FILE}" ${VERISTAT_OBJECTS_GLOB} > \ - "${OUTPUT_DIR}/${VERISTAT_OUTPUT}" - - echo "run_veristat_${mode}:$?" >> ${STATUS_FILE} - popd - ) - - # Hide commands again - if [ -z "$xtrace_was_on" ]; then - set +x - fi - -} - -run_veristat_kernel() { - foldable start run_veristat_kernel "Running veristat.kernel" - run_veristat_helper "kernel" - foldable end run_veristat_kernel -} - -run_veristat_meta() { - foldable start run_veristat_meta "Running veristat.meta" - run_veristat_helper "meta" - foldable end run_veristat_meta -} - -foldable end vm_init - -foldable start kernel_config "Kconfig" - -zcat /proc/config.gz - -foldable end kernel_config - -echo "DENYLIST: ${DENYLIST}" -echo "ALLOWLIST: ${ALLOWLIST}" - -cd ${PROJECT_NAME}/selftests/bpf - -# populate TEST_NAMES -read_test_names "$@" -# if we don't have any test name provided to the script, we run all tests. -if [ ${#TEST_NAMES[@]} -eq 0 ]; then - test_progs - test_progs_no_alu32 - test_progs_cpuv4 - test_maps - test_verifier -else - # else we run the tests passed as command-line arguments and through boot - # parameter. - for test_name in "${TEST_NAMES[@]}"; do - "${test_name}" - done -fi diff --git a/ci/vmtest/sched_ext_selftests.sh b/ci/vmtest/sched_ext_selftests.sh deleted file mode 100755 index a20672db..00000000 --- a/ci/vmtest/sched_ext_selftests.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -source "$(cd "$(dirname "$0")" && pwd)/helpers.sh" - -foldable start selftests/sched_ext "Executing selftests/sched_ext/runner" - -SELFTESTS_DIR="${KERNEL_ROOT}/selftests/sched_ext" -STATUS_FILE=/mnt/vmtest/exitstatus - -cd "${SELFTESTS_DIR}" -./runner "$@" | tee runner.log - -failed=$(tail -n 16 runner.log | grep "FAILED" | awk '{print $2}') - -echo "selftests/sched_ext:$failed" >>"${STATUS_FILE}" - -foldable end selftests/sched_ext diff --git a/ci/vmtest/vmtest_selftests.sh b/ci/vmtest/vmtest_selftests.sh deleted file mode 100755 index 699a92e8..00000000 --- a/ci/vmtest/vmtest_selftests.sh +++ /dev/null @@ -1,188 +0,0 @@ -#!/bin/bash - -# run_selftest.sh will run the tests within /${PROJECT_NAME}/selftests/bpf -# If no specific test names are given, all test will be ran, otherwise, it will -# run the test passed as parameters. -# There is 2 ways to pass test names. -# 1) command-line arguments to this script -# 2) a comma-separated list of test names passed as `run_tests` boot parameters. -# test names passed as any of those methods will be ran. - -set -euo pipefail - -source "$(cd "$(dirname "$0")" && pwd)/helpers.sh" - -ARCH=$(uname -m) -DEPLOYMENT=$(if [[ "$GITHUB_REPOSITORY" == "kernel-patches/bpf" ]]; then echo "prod"; else echo "rc"; fi) - -STATUS_FILE=/mnt/vmtest/exitstatus -OUTPUT_DIR=/mnt/vmtest - -WORKING_DIR="/${PROJECT_NAME}" -BPF_SELFTESTS_DIR="${WORKING_DIR}/selftests/bpf" -VMTEST_CONFIGS_PATH="${WORKING_DIR}/ci/vmtest/configs" - -DENYLIST=$(read_lists \ - "$BPF_SELFTESTS_DIR/DENYLIST" \ - "$BPF_SELFTESTS_DIR/DENYLIST.${ARCH}" \ - "$VMTEST_CONFIGS_PATH/DENYLIST" \ - "$VMTEST_CONFIGS_PATH/DENYLIST.${ARCH}" \ - "$VMTEST_CONFIGS_PATH/DENYLIST.${DEPLOYMENT}" \ -) -ALLOWLIST=$(read_lists \ - "$BPF_SELFTESTS_DIR/ALLOWLIST" \ - "$BPF_SELFTESTS_DIR/ALLOWLIST.${ARCH}" \ - "$VMTEST_CONFIGS_PATH/ALLOWLIST" \ - "$VMTEST_CONFIGS_PATH/ALLOWLIST.${ARCH}" \ -) - -declare -a TEST_NAMES=() - -read_test_names() { - foldable start read_test_names "Reading test names from boot parameters and command line arguments" - # Check if test names were passed as boot parameter. - # We expect `run_tests` to be a comma-separated list of test names. - IFS=',' read -r -a test_names_from_boot <<< \ - "$(sed -n 's/.*run_tests=\([^ ]*\).*/\1/p' /proc/cmdline)" - - echo "${#test_names_from_boot[@]} tests extracted from boot parameters: ${test_names_from_boot[*]}" - # Sort and only keep unique test names from both boot params and arguments - # TEST_NAMES will contain a sorted list of uniq tests to be ran. - # Only do this if any of $test_names_from_boot[@] or $@ has elements as - # "printf '%s\0'" will otherwise generate an empty element. - if [[ ${#test_names_from_boot[@]} -gt 0 || $# -gt 0 ]] - then - readarray -t TEST_NAMES < \ - <(printf '%s\0' "${test_names_from_boot[@]}" "$@" | \ - sort --zero-terminated --unique | \ - xargs --null --max-args=1) - fi - foldable end read_test_names -} - -test_progs_helper() { - local selftest="test_progs${1}" - local args="$2" - - json_file=${selftest/-/_} - if [ "$2" == "-j" ] - then - json_file+="_parallel" - fi - json_file="${OUTPUT_DIR}/${json_file}.json" - - foldable start ${selftest} "Testing ${selftest}" - # "&& true" does not change the return code (it is not executed - # if the Python script fails), but it prevents exiting on a - # failure due to the "set -e". - ./${selftest} ${args} ${DENYLIST:+-d"$DENYLIST"} ${ALLOWLIST:+-a"$ALLOWLIST"} --json-summary "${json_file}" && true - echo "${selftest}:$?" >>"${STATUS_FILE}" - foldable end ${selftest} -} - -test_progs() { - test_progs_helper "" "" -} - -test_progs_parallel() { - test_progs_helper "" "-j" -} - -test_progs_no_alu32() { - test_progs_helper "-no_alu32" "" -} - -test_progs_no_alu32_parallel() { - test_progs_helper "-no_alu32" "-j" -} - -test_progs_cpuv4() { - test_progs_helper "-cpuv4" "" -} - -test_maps() { - foldable start test_maps "Testing test_maps" - taskset 0xF ./test_maps && true - echo "test_maps:$?" >>"${STATUS_FILE}" - foldable end test_maps -} - -test_verifier() { - foldable start test_verifier "Testing test_verifier" - ./test_verifier && true - echo "test_verifier:$?" >>"${STATUS_FILE}" - foldable end test_verifier -} - -run_veristat_helper() { - local mode="${1}" - - # Make veristat commands visible in the log - if [ -o xtrace ]; then - xtrace_was_on="1" - else - xtrace_was_on="" - set -x - fi - - ( - # shellcheck source=ci/vmtest/configs/run_veristat.default.cfg - # shellcheck source=ci/vmtest/configs/run_veristat.meta.cfg - source "${VMTEST_CONFIGS_PATH}/run_veristat.${mode}.cfg" - pushd "${VERISTAT_OBJECTS_DIR}" - - "${BPF_SELFTESTS_DIR}/veristat" -o csv -q -e file,prog,verdict,states ${VERISTAT_OBJECTS_GLOB} > \ - "${OUTPUT_DIR}/${VERISTAT_OUTPUT}" - - echo "run_veristat_${mode}:$?" >> ${STATUS_FILE} - popd - ) - - # Hide commands again - if [ -z "$xtrace_was_on" ]; then - set +x - fi - -} - -run_veristat_kernel() { - foldable start run_veristat_kernel "Running veristat.kernel" - run_veristat_helper "kernel" - foldable end run_veristat_kernel -} - -run_veristat_meta() { - foldable start run_veristat_meta "Running veristat.meta" - run_veristat_helper "meta" - foldable end run_veristat_meta -} - -foldable end vm_init - -foldable start kernel_config "Kconfig" - -zcat /proc/config.gz - -foldable end kernel_config - -echo "DENYLIST: ${DENYLIST}" -echo "ALLOWLIST: ${ALLOWLIST}" - -cd ${PROJECT_NAME}/selftests/bpf - -# populate TEST_NAMES -read_test_names "$@" -# if we don't have any test name provided to the script, we run all tests. -if [ ${#TEST_NAMES[@]} -eq 0 ]; then - test_progs - test_progs_no_alu32 - test_progs_cpuv4 - test_maps - test_verifier -else - # else we run the tests passed as command-line arguments and through boot - # parameter. - for test_name in "${TEST_NAMES[@]}"; do - "${test_name}" - done -fi