From 73e00a3af64075f653db0f9a1d4d7ad7a2ced5ea Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Thu, 24 Oct 2024 14:35:05 -0700 Subject: [PATCH 1/9] run-vmtest: sched_ext selftests support --- .github/workflows/test.yml | 8 +++++++- ci/vmtest/helpers.sh | 8 ++++++++ ci/vmtest/sched_ext_selftests.sh | 19 +++++++++++++++++++ ci/vmtest/vmtest_selftests.sh | 8 -------- run-vmtest/action.yml | 9 +++++++-- run-vmtest/run.sh | 27 ++++++++++++++++++++------- 6 files changed, 61 insertions(+), 18 deletions(-) create mode 100755 ci/vmtest/sched_ext_selftests.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ae3e273..0604f3d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,7 +20,13 @@ jobs: toolchain: - {"name": "gcc", "fullname": "gcc", "version": 17} - {"name": "llvm", "fullname": "llvm-17", "version": 17} - tests: [{"include": [{"test": "test_progs", "continue_on_error": false, "timeout_minutes": 360}, {"test": "test_progs_no_alu32", "continue_on_error": false, "timeout_minutes": 360}, {"test": "test_verifier", "continue_on_error": false, "timeout_minutes": 360}, {"test": "test_maps", "continue_on_error": false, "timeout_minutes": 360}]}] + tests: + - include: + - {"test": "test_progs", "continue_on_error": false, "timeout_minutes": 360} + - {"test": "test_progs_no_alu32", "continue_on_error": false, "timeout_minutes": 360} + - {"test": "test_verifier", "continue_on_error": false, "timeout_minutes": 360} + - {"test": "test_maps", "continue_on_error": false, "timeout_minutes": 360} + - {"test": "sched_ext", "continue_on_error": false, "timeout_minutes": 360} fail-fast: false # Setting name to arch-compiler here to avoid lengthy autogenerated names due to matrix # e.g build-and-test x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc diff --git a/ci/vmtest/helpers.sh b/ci/vmtest/helpers.sh index c44d098..86c734c 100755 --- a/ci/vmtest/helpers.sh +++ b/ci/vmtest/helpers.sh @@ -36,3 +36,11 @@ print_error() { 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/sched_ext_selftests.sh b/ci/vmtest/sched_ext_selftests.sh new file mode 100755 index 0000000..a20672d --- /dev/null +++ b/ci/vmtest/sched_ext_selftests.sh @@ -0,0 +1,19 @@ +#!/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 index b37eded..699a92e 100755 --- a/ci/vmtest/vmtest_selftests.sh +++ b/ci/vmtest/vmtest_selftests.sh @@ -22,14 +22,6 @@ WORKING_DIR="/${PROJECT_NAME}" BPF_SELFTESTS_DIR="${WORKING_DIR}/selftests/bpf" VMTEST_CONFIGS_PATH="${WORKING_DIR}/ci/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}" \ diff --git a/run-vmtest/action.yml b/run-vmtest/action.yml index d998990..17cfee6 100644 --- a/run-vmtest/action.yml +++ b/run-vmtest/action.yml @@ -29,6 +29,10 @@ inputs: required: false type: string default: 'kbuild-output' + vmtest-release: + description: 'Release version of vmtest tool to use' + required: false + default: 'v0.14.0' runs: using: "composite" @@ -42,9 +46,10 @@ runs: cp "$vmlinuz" ${{ inputs.vmlinuz }} - name: Download vmtest shell: bash - # FIXME: move to proper release run: | - sudo curl -L https://github.com/danobi/vmtest/releases/download/v0.12.0/vmtest-$(uname -m) -o /usr/bin/vmtest && sudo chmod 755 /usr/bin/vmtest + VMTEST_URL="https://github.com/danobi/vmtest/releases/download/${{ inputs.vmtest-release }}/vmtest-$(uname -m)" + sudo curl -L $VMTEST_URL -o /usr/bin/vmtest + sudo chmod 755 /usr/bin/vmtest - name: install qemu tools and selftest dependencies shell: bash run: | diff --git a/run-vmtest/run.sh b/run-vmtest/run.sh index b1cc175..08e030a 100755 --- a/run-vmtest/run.sh +++ b/run-vmtest/run.sh @@ -3,14 +3,28 @@ set -euo pipefail trap 'exit 2' ERR -source $(cd $(dirname $0) && pwd)/../helpers.sh +source "${GITHUB_ACTION_PATH}/../helpers.sh" + +RUN_BPFTOOL_CHECKS= + +if [[ "$KERNEL_TEST" != "sched_ext" ]]; then + VMTEST_SCRIPT="${GITHUB_ACTION_PATH}/../ci/vmtest/vmtest_selftests.sh" + if [[ "${KERNEL}" = 'LATEST' ]]; then + RUN_BPFTOOL_CHECKS=true + fi +else + VMTEST_SCRIPT="${GITHUB_ACTION_PATH}/../ci/vmtest/sched_ext_selftests.sh" +fi + +# clear exitstatus file +echo -n "" > exitstatus foldable start bpftool_checks "Running bpftool checks..." -bpftool_exitstatus=0 # bpftool checks are aimed at checking type names, documentation, shell # completion etc. against the current kernel, so only run on LATEST. -if [[ "${KERNEL}" = 'LATEST' ]]; then +if [[ -n "${RUN_BPFTOOL_CHECKS}" ]]; then + bpftool_exitstatus=0 # "&& true" does not change the return code (it is not executed if the # Python script fails), but it prevents the trap on ERR set at the top # of this file to trigger on failure. @@ -21,11 +35,11 @@ if [[ "${KERNEL}" = 'LATEST' ]]; then else echo "bpftool checks returned ${bpftool_exitstatus}." fi + echo "bpftool:${bpftool_exitstatus}" >> exitstatus else echo "bpftool checks skipped." fi -bpftool_exitstatus="bpftool:${bpftool_exitstatus}" foldable end bpftool_checks foldable start vmtest "Starting virtual machine..." @@ -37,14 +51,13 @@ vmtest -k "${VMLINUZ}" --kargs "panic=-1 sysctl.vm.panic_on_oom=1" "umount /tmp /bin/mount bpffs /sys/fs/bpf -t bpf && \ ip link set lo up && \ cd '${GITHUB_WORKSPACE}' && \ - ./ci/vmtest/vmtest_selftests.sh ${T}" + ${VMTEST_SCRIPT} ${T}" foldable end vmtest foldable start collect_status "Collecting exit status" -exitfile="${bpftool_exitstatus}\n" -exitfile+="$(cat exitstatus 2>/dev/null)" +exitfile="$(cat exitstatus 2>/dev/null)" exitstatus="$(echo -e "$exitfile" | awk --field-separator ':' \ 'BEGIN { s=0 } { if ($2) {s=1} } END { print s }')" From 8e0703596b2134878090bd271edf005ea8a89bf1 Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Thu, 24 Oct 2024 16:46:49 -0700 Subject: [PATCH 2/9] run-vmtest/run.sh: remove umount /tmp command passed to vmtest --- run-vmtest/run.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/run-vmtest/run.sh b/run-vmtest/run.sh index 08e030a..f353b7e 100755 --- a/run-vmtest/run.sh +++ b/run-vmtest/run.sh @@ -46,12 +46,11 @@ foldable start vmtest "Starting virtual machine..." # Tests may be comma-separated. vmtest_selftest expect them to come from CLI space-separated. T=$(echo ${KERNEL_TEST} | tr -s ',' ' ') -# HACK: We need to unmount /tmp to access /tmp from the container.... -vmtest -k "${VMLINUZ}" --kargs "panic=-1 sysctl.vm.panic_on_oom=1" "umount /tmp && \ - /bin/mount bpffs /sys/fs/bpf -t bpf && \ - ip link set lo up && \ - cd '${GITHUB_WORKSPACE}' && \ - ${VMTEST_SCRIPT} ${T}" +vmtest -k "${VMLINUZ}" --kargs "panic=-1 sysctl.vm.panic_on_oom=1" \ + "/bin/mount bpffs /sys/fs/bpf -t bpf && \ + ip link set lo up && \ + cd '${GITHUB_WORKSPACE}' && \ + ${VMTEST_SCRIPT} ${T}" foldable end vmtest From 70bdc5f2d0c65a140ae8654091a107db3d688894 Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Wed, 6 Nov 2024 15:39:24 -0800 Subject: [PATCH 3/9] test.yml: disable sched_ext tests --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0604f3d..f815813 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,8 @@ jobs: - {"test": "test_progs_no_alu32", "continue_on_error": false, "timeout_minutes": 360} - {"test": "test_verifier", "continue_on_error": false, "timeout_minutes": 360} - {"test": "test_maps", "continue_on_error": false, "timeout_minutes": 360} - - {"test": "sched_ext", "continue_on_error": false, "timeout_minutes": 360} + # Uncomment this to enable sched_ext selftests jobs + # - {"test": "sched_ext", "continue_on_error": false, "timeout_minutes": 360} fail-fast: false # Setting name to arch-compiler here to avoid lengthy autogenerated names due to matrix # e.g build-and-test x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc From 46b38583bb6f19b4b5d59ee825bcdfa288085784 Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Fri, 1 Nov 2024 14:03:22 -0700 Subject: [PATCH 4/9] run-vmtest@v2: remove unused img input, make vmlinuz optional Previously the first run-vmtest action step would always search for vmlinux image in KERNEL_ROOT, and then copy it to path specified by inputs.vmlinuz However, the caller may want to pass vmlinux image directly. Change this behavior: search only inputs.vmlinuz was not passed. Signed-off-by: Ihor Solodrai --- run-vmtest/action.yml | 20 +++++--------------- run-vmtest/run.sh | 5 +++++ 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/run-vmtest/action.yml b/run-vmtest/action.yml index 17cfee6..cb21047 100644 --- a/run-vmtest/action.yml +++ b/run-vmtest/action.yml @@ -4,12 +4,11 @@ inputs: arch: description: 'arch' required: true - img: - description: 'img path' - required: true vmlinuz: - description: 'vmlinuz path' - required: true + description: | + If passed, this vmlinuz will be used. Otherwise vmlinuz will be + searched via make -s image_name in kbuild-output. + required: false kernel-root: description: 'kernel source dir' default: '.' @@ -27,7 +26,6 @@ inputs: kbuild-output: description: 'Path to KBUILD_OUTPUT' required: false - type: string default: 'kbuild-output' vmtest-release: description: 'Release version of vmtest tool to use' @@ -37,13 +35,6 @@ inputs: runs: using: "composite" steps: - - name: Find kernel - id: find-kernel - shell: bash - run: | - BUILDDIR=$(realpath ${{ inputs.kbuild-output }}) - vmlinuz="$BUILDDIR/$(KBUILD_OUTPUT="${BUILDDIR}" make -C "${{ inputs.kernel-root }}" -s image_name)" - cp "$vmlinuz" ${{ inputs.vmlinuz }} - name: Download vmtest shell: bash run: | @@ -76,8 +67,7 @@ runs: - name: Run vmtest shell: bash env: - VMLINUZ: ${{ inputs.vmlinuz }} - IMG: ${{ inputs.img }} + VMLINUZ: ${{ inputs.vmlinuz || '' }} KERNEL_ROOT: ${{ inputs.kernel-root }} MAX_CPU: ${{ inputs.max-cpu }} KERNEL_TEST: ${{ inputs.kernel-test }} diff --git a/run-vmtest/run.sh b/run-vmtest/run.sh index f353b7e..b63d1dd 100755 --- a/run-vmtest/run.sh +++ b/run-vmtest/run.sh @@ -5,6 +5,11 @@ trap 'exit 2' ERR source "${GITHUB_ACTION_PATH}/../helpers.sh" +if [[ -z "${VMLINUZ}" || ! -f "${VMLINUZ}" ]]; then + image_name=$(make -C ${KERNEL_ROOT} -s image_name) + export VMLINUZ=$(realpath ${KERNEL_ROOT}/${image_name}) +fi + RUN_BPFTOOL_CHECKS= if [[ "$KERNEL_TEST" != "sched_ext" ]]; then From 58a9063d496c406695913d508ddbb2cabb41b236 Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Tue, 5 Nov 2024 13:36:00 -0800 Subject: [PATCH 5/9] run-vmtest@v2: make the scripts more reusable Various changes in the scripts aimed to make run-vmtest action usable by libbpf/libbpf workflows: * Change how ALLOWLIST and DENYLIST are set up. A script executing in qemu (vmtest) is now expecting a single $ALLOWLIST_FILE and $DENYLIST_FILE which are parsed by read_lists as usual. This change makes it easier for an action caller to modify the lists, as they are often composed from a number of files. * Update vmtest init command (executed in qemu before the tests), to create a link from /boot to vmlinux being tested. This is necessary when older kernels are tested. * Allow some env variables to be defined outside of the scripts to give the caller more control over the action. That is, before setting a default value, check if the variable is set. * Remove env vars like $THISDIR, $PROJECT_NAME etc. in favor of $GITHUB_ACTION_PATH, $GITHUB_WORKSPACE and $KERNEL_ROOT * Move selftests running scripts from ci/vmtest to run-vmtest, so that they are local to the action Signed-off-by: Ihor Solodrai --- build-selftests/build_selftests.sh | 21 +++------ patch-kernel/patch_kernel.sh | 2 +- {ci/vmtest => run-vmtest}/helpers.sh | 0 .../run-bpf-selftests.sh | 46 +++++++------------ .../run-scx-selftests.sh | 0 run-vmtest/run.sh | 27 +++++++---- 6 files changed, 40 insertions(+), 56 deletions(-) rename {ci/vmtest => run-vmtest}/helpers.sh (100%) rename ci/vmtest/vmtest_selftests.sh => run-vmtest/run-bpf-selftests.sh (78%) rename ci/vmtest/sched_ext_selftests.sh => run-vmtest/run-scx-selftests.sh (100%) diff --git a/build-selftests/build_selftests.sh b/build-selftests/build_selftests.sh index df4280e..9030242 100755 --- a/build-selftests/build_selftests.sh +++ b/build-selftests/build_selftests.sh @@ -2,14 +2,13 @@ set -euo pipefail -THISDIR="$(cd $(dirname $0) && pwd)" - -source "${THISDIR}"/../helpers.sh +source "${GITHUB_ACTION_PATH}/../helpers.sh" TARGET_ARCH="$1" KERNEL="$2" TOOLCHAIN="$3" export KBUILD_OUTPUT="$4" +VMLINUX_H=${VMLINUX_H:-} ARCH="$(platform_to_kernel_arch ${TARGET_ARCH})" CROSS_COMPILE="" @@ -26,19 +25,11 @@ fi foldable start build_selftests "Building selftests with $TOOLCHAIN" -PREPARE_SELFTESTS_SCRIPT=${THISDIR}/prepare_selftests-${KERNEL}.sh +PREPARE_SELFTESTS_SCRIPT=$(find $GITHUB_WORKSPACE -name prepare_selftests-${KERNEL}.sh) if [ -f "${PREPARE_SELFTESTS_SCRIPT}" ]; then - (cd "${REPO_ROOT}/${REPO_PATH}/tools/testing/selftests/bpf" && ${PREPARE_SELFTESTS_SCRIPT}) -fi - -if [[ "${KERNEL}" = 'LATEST' ]]; then - VMLINUX_H= -else - VMLINUX_H=${THISDIR}/vmlinux.h + (cd "${KERNEL_ROOT}/tools/testing/selftests/bpf" && ${PREPARE_SELFTESTS_SCRIPT}) fi -cd ${REPO_ROOT}/${REPO_PATH} - MAKE_OPTS=$(cat </dev/null 2>&1; then for file in ${DIFF_DIR}/*.${ext}; do - if patch --dry-run -p1 -s < "${file}" 2>/dev/null; then + if patch --dry-run -N --silent -p1 -s < "${file}" 2>/dev/null; then patch -s -p1 < "${file}" 2>/dev/null echo "Successfully applied ${file}!" else diff --git a/ci/vmtest/helpers.sh b/run-vmtest/helpers.sh similarity index 100% rename from ci/vmtest/helpers.sh rename to run-vmtest/helpers.sh diff --git a/ci/vmtest/vmtest_selftests.sh b/run-vmtest/run-bpf-selftests.sh similarity index 78% rename from ci/vmtest/vmtest_selftests.sh rename to run-vmtest/run-bpf-selftests.sh index 699a92e..f12f906 100755 --- a/ci/vmtest/vmtest_selftests.sh +++ b/run-vmtest/run-bpf-selftests.sh @@ -1,40 +1,26 @@ #!/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. +# This script runs the tests within ${GITHUB_WORKSPACE}/selftests/bpf +# If no specific test names are given, all test runners will be +# executed. Otherwise, executed runners passed as parameters. +# There are 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. +# 2) a comma-separated list of test names passed as `run_tests` boot +# parameters. set -euo pipefail -source "$(cd "$(dirname "$0")" && pwd)/helpers.sh" +source "${GITHUB_ACTION_PATH}/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}" \ -) + +STATUS_FILE=${STATUS_FILE:-/mnt/vmtest/exitstatus} +OUTPUT_DIR=${OUTPUT_DIR:-/mnt/vmtest} + +ALLOWLIST_FILE=${ALLOWLIST_FILE:-} +ALLOWLIST=$(read_lists "${ALLOWLIST_FILE}") +DENYLIST_FILE=${DENYLIST_FILE:-} +DENYLIST=$(read_lists "${DENYLIST_FILE}") declare -a TEST_NAMES=() @@ -168,7 +154,7 @@ foldable end kernel_config echo "DENYLIST: ${DENYLIST}" echo "ALLOWLIST: ${ALLOWLIST}" -cd ${PROJECT_NAME}/selftests/bpf +cd ${GITHUB_WORKSPACE}/selftests/bpf # populate TEST_NAMES read_test_names "$@" diff --git a/ci/vmtest/sched_ext_selftests.sh b/run-vmtest/run-scx-selftests.sh similarity index 100% rename from ci/vmtest/sched_ext_selftests.sh rename to run-vmtest/run-scx-selftests.sh diff --git a/run-vmtest/run.sh b/run-vmtest/run.sh index b63d1dd..fe7706a 100755 --- a/run-vmtest/run.sh +++ b/run-vmtest/run.sh @@ -10,15 +10,21 @@ if [[ -z "${VMLINUZ}" || ! -f "${VMLINUZ}" ]]; then export VMLINUZ=$(realpath ${KERNEL_ROOT}/${image_name}) fi -RUN_BPFTOOL_CHECKS= +RUN_BPFTOOL_CHECKS=${RUN_BPFTOOL_CHECKS:-} +if [[ -z "${RUN_BPFTOOL_CHECKS}" \ + && "${KERNEL}" = 'LATEST' \ + && "$KERNEL_TEST" != "sched_ext" ]]; +then + RUN_BPFTOOL_CHECKS=true +fi -if [[ "$KERNEL_TEST" != "sched_ext" ]]; then - VMTEST_SCRIPT="${GITHUB_ACTION_PATH}/../ci/vmtest/vmtest_selftests.sh" - if [[ "${KERNEL}" = 'LATEST' ]]; then - RUN_BPFTOOL_CHECKS=true - fi +VMTEST_SCRIPT=${VMTEST_SCRIPT:-} +if [[ -z "$VMTEST_SCRIPT" \ + && "$KERNEL_TEST" != "sched_ext" ]]; +then + VMTEST_SCRIPT="${GITHUB_ACTION_PATH}/run-bpf-selftests.sh" else - VMTEST_SCRIPT="${GITHUB_ACTION_PATH}/../ci/vmtest/sched_ext_selftests.sh" + VMTEST_SCRIPT="${GITHUB_ACTION_PATH}/run-scx-selftests.sh" fi # clear exitstatus file @@ -52,9 +58,10 @@ foldable start vmtest "Starting virtual machine..." # Tests may be comma-separated. vmtest_selftest expect them to come from CLI space-separated. T=$(echo ${KERNEL_TEST} | tr -s ',' ' ') vmtest -k "${VMLINUZ}" --kargs "panic=-1 sysctl.vm.panic_on_oom=1" \ - "/bin/mount bpffs /sys/fs/bpf -t bpf && \ - ip link set lo up && \ - cd '${GITHUB_WORKSPACE}' && \ + "ln -sf /mnt/vmtest/vmlinux /boot/vmlinux-$(uname -r) && \ + /bin/mount bpffs /sys/fs/bpf -t bpf && \ + ip link set lo up && \ + cd '${GITHUB_WORKSPACE}' && \ ${VMTEST_SCRIPT} ${T}" foldable end vmtest From d2edfb950ce73065a2ca688aa5b80d34ed296e04 Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Wed, 13 Nov 2024 13:53:22 -0800 Subject: [PATCH 6/9] run-vmtest: more flexible configuration Adjust run-vmtest scripts so that the action is callable from libbpf/libbpf, particularly with pre-built kernels. More environment variables can now be set by a caller to direct the scripts behavior: SELFTESTS_BPF, VERISTAT_CONFIGS, VMLINUX, VMLINUZ A symlink to standard vmlinux location is created before vmtest is executed to accomodate older kernels. The command passed tp vmtest is refactored, separating generic vmtet init and VMTEST_SCRIPT execution. Search and processing of json test summaries is now noop in case when no summaries are found. Signed-off-by: Ihor Solodrai --- run-vmtest/action.yml | 8 +++---- run-vmtest/run-bpf-selftests.sh | 19 +++++++++++---- run-vmtest/run.sh | 42 +++++++++++++++++++++++---------- run-vmtest/vmtest-init.sh | 5 ++++ 4 files changed, 53 insertions(+), 21 deletions(-) create mode 100755 run-vmtest/vmtest-init.sh diff --git a/run-vmtest/action.yml b/run-vmtest/action.yml index cb21047..60d9cb9 100644 --- a/run-vmtest/action.yml +++ b/run-vmtest/action.yml @@ -30,7 +30,7 @@ inputs: vmtest-release: description: 'Release version of vmtest tool to use' required: false - default: 'v0.14.0' + default: 'v0.15.0' runs: using: "composite" @@ -67,12 +67,12 @@ runs: - name: Run vmtest shell: bash env: - VMLINUZ: ${{ inputs.vmlinuz || '' }} + KBUILD_OUTPUT: ${{ inputs.kbuild-output }} KERNEL_ROOT: ${{ inputs.kernel-root }} - MAX_CPU: ${{ inputs.max-cpu }} KERNEL_TEST: ${{ inputs.kernel-test }} + MAX_CPU: ${{ inputs.max-cpu }} OUTPUT_DIR: ${{ inputs.output-dir }} - PROJECT_NAME: "/mnt/vmtest" + VMLINUZ: ${{ inputs.vmlinuz || '' }} run: | ${GITHUB_ACTION_PATH}/run.sh diff --git a/run-vmtest/run-bpf-selftests.sh b/run-vmtest/run-bpf-selftests.sh index f12f906..ff2a28e 100755 --- a/run-vmtest/run-bpf-selftests.sh +++ b/run-vmtest/run-bpf-selftests.sh @@ -1,6 +1,14 @@ #!/bin/bash -# This script runs the tests within ${GITHUB_WORKSPACE}/selftests/bpf +# This script is expected to be executed by vmtest program (a qemu +# wrapper). By default vmtest mounts working directory to /mnt/vmtest, +# which is why this path is often assumed in the script. The working +# directory is usually (although not necessarily) the +# $GITHUB_WORKSPACE of the Github Action workflow, calling +# libbpf/ci/run-vmtest action. +# See also action.yml and run.sh +# +# The script executes the tests within $SELFTESTS_BPF directory. # If no specific test names are given, all test runners will be # executed. Otherwise, executed runners passed as parameters. # There are 2 ways to pass test names. @@ -10,10 +18,11 @@ set -euo pipefail -source "${GITHUB_ACTION_PATH}/helpers.sh" +source "$(cd "$(dirname "$0")" && pwd)/helpers.sh" ARCH=$(uname -m) +SELFTESTS_BPF=${SELFTESTS_BPF:-/mnt/vmtest/selftests/bpf} STATUS_FILE=${STATUS_FILE:-/mnt/vmtest/exitstatus} OUTPUT_DIR=${OUTPUT_DIR:-/mnt/vmtest} @@ -100,6 +109,8 @@ test_verifier() { foldable end test_verifier } +export VERISTAT_CONFIGS=${VERISTAT_CONFIGS:-/mnt/vmtest/ci/vmtest/configs} + run_veristat_helper() { local mode="${1}" @@ -114,7 +125,7 @@ run_veristat_helper() { ( # 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" + source "${VERISTAT_CONFIGS}/run_veristat.${mode}.cfg" pushd "${VERISTAT_OBJECTS_DIR}" "${BPF_SELFTESTS_DIR}/veristat" -o csv -q -e file,prog,verdict,states ${VERISTAT_OBJECTS_GLOB} > \ @@ -154,7 +165,7 @@ foldable end kernel_config echo "DENYLIST: ${DENYLIST}" echo "ALLOWLIST: ${ALLOWLIST}" -cd ${GITHUB_WORKSPACE}/selftests/bpf +cd $SELFTESTS_BPF # populate TEST_NAMES read_test_names "$@" diff --git a/run-vmtest/run.sh b/run-vmtest/run.sh index fe7706a..2d72ada 100755 --- a/run-vmtest/run.sh +++ b/run-vmtest/run.sh @@ -5,9 +5,22 @@ trap 'exit 2' ERR source "${GITHUB_ACTION_PATH}/../helpers.sh" -if [[ -z "${VMLINUZ}" || ! -f "${VMLINUZ}" ]]; then +export VMLINUZ=${VMLINUZ:-} +if [[ ! -f "${VMLINUZ}" ]]; then image_name=$(make -C ${KERNEL_ROOT} -s image_name) - export VMLINUZ=$(realpath ${KERNEL_ROOT}/${image_name}) + export VMLINUZ=$(realpath ${KBUILD_OUTPUT})/${image_name} +fi + +# Create a symlink to vmlinux from a "standard" location +# See btf__load_vmlinux_btf() in libbpf +VMLINUX=${VMLINUX:-"$KBUILD_OUTPUT/vmlinux"} +if [[ -f "${VMLINUX}" ]]; then + VMLINUX_VERSION="$(strings ${VMLINUX} | grep -m 1 'Linux version' | awk '{print $3}')" || true + sudo mkdir -p /usr/lib/debug/boot + sudo ln -sf "${VMLINUX}" "/usr/lib/debug/boot/vmlinux-${VMLINUX_VERSION}" +else + echo "$VMLINUX does not exist" + exit 2 fi RUN_BPFTOOL_CHECKS=${RUN_BPFTOOL_CHECKS:-} @@ -56,13 +69,11 @@ foldable end bpftool_checks foldable start vmtest "Starting virtual machine..." # Tests may be comma-separated. vmtest_selftest expect them to come from CLI space-separated. -T=$(echo ${KERNEL_TEST} | tr -s ',' ' ') +TEST_RUNNERS=$(echo ${KERNEL_TEST} | tr -s ',' ' ') vmtest -k "${VMLINUZ}" --kargs "panic=-1 sysctl.vm.panic_on_oom=1" \ - "ln -sf /mnt/vmtest/vmlinux /boot/vmlinux-$(uname -r) && \ - /bin/mount bpffs /sys/fs/bpf -t bpf && \ - ip link set lo up && \ - cd '${GITHUB_WORKSPACE}' && \ - ${VMTEST_SCRIPT} ${T}" + "${GITHUB_ACTION_PATH}/vmtest-init.sh && \ + cd '${GITHUB_WORKSPACE}' && \ + ${VMTEST_SCRIPT} ${TEST_RUNNERS}" foldable end vmtest @@ -81,13 +92,18 @@ fi foldable end collect_status -# Try to collect json summary from VM -if [[ -n ${KERNEL_TEST} && ${KERNEL_TEST} =~ test_progs* ]] -then - ## Job summary - "${GITHUB_ACTION_PATH}/print_test_summary.py" -s "${GITHUB_STEP_SUMMARY}" -j "${KERNEL_TEST}.json" +if [ -n "${TEST_RUNNERS}" ]; then + SUMMARIES=$(for runner in ${TEST_RUNNERS}; do echo "${runner}.json"; done) +else + SUMMARIES=$(find . -maxdepth 1 -name "test_*.json") fi +for summary in ${SUMMARIES}; do + if [ -f "${summary}" ]; then + "${GITHUB_ACTION_PATH}/print_test_summary.py" -s "${GITHUB_STEP_SUMMARY}" -j "${summary}" + fi +done + # Final summary - Don't use a fold, keep it visible echo -e "\033[1;33mTest Results:\033[0m" echo -e "$exitfile" | while read result; do diff --git a/run-vmtest/vmtest-init.sh b/run-vmtest/vmtest-init.sh new file mode 100755 index 0000000..84954d0 --- /dev/null +++ b/run-vmtest/vmtest-init.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +/bin/mount bpffs /sys/fs/bpf -t bpf +ip link set lo up + From e67a7e49765f2ed2e4389b9d822b39988828edae Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Wed, 13 Nov 2024 14:08:23 -0800 Subject: [PATCH 7/9] get-linux-source: introduce FETCH_DEPTH env variable FETCH_DEPTH now controls how to get linux source. If it's 0, the snapshot is searched for and downloaded if found. Otherwise git clone --depth $FETCH_DEPTH is executed, and .git is preserved. Signed-off-by: Ihor Solodrai --- get-linux-source/checkout_latest_kernel.sh | 34 ++++++++++++---------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/get-linux-source/checkout_latest_kernel.sh b/get-linux-source/checkout_latest_kernel.sh index 8e36e47..4b33ed3 100755 --- a/get-linux-source/checkout_latest_kernel.sh +++ b/get-linux-source/checkout_latest_kernel.sh @@ -6,6 +6,9 @@ source $(cd $(dirname $0) && pwd)/../helpers.sh CWD=$(pwd) +# 0 means just download a snapshot +FETCH_DEPTH=${FETCH_DEPTH:-0} + echo KERNEL_ORIGIN = ${KERNEL_ORIGIN} echo KERNEL_BRANCH = ${KERNEL_BRANCH} echo REPO_PATH = ${REPO_PATH} @@ -29,26 +32,27 @@ if [ ! -d "${REPO_PATH}" ]; then mkdir -p $(dirname "${REPO_PATH}") cd $(dirname "${REPO_PATH}") # attempt to fetch desired bpf-next repo snapshot - if [ -n "${SNAPSHOT_URL}" ] && \ + if [ -n "${SNAPSHOT_URL}" ] && [ "${FETCH_DEPTH}" -eq 0 ] && \ wget -U 'BPFCIBot/1.0 (bpf@vger.kernel.org)' -nv ${SNAPSHOT_URL} && \ tar xf bpf-next-${LINUX_SHA}.tar.gz --totals ; then mv bpf-next-${LINUX_SHA} $(basename ${REPO_PATH}) else - # but fallback to git fetch approach if that fails - mkdir -p $(basename ${REPO_PATH}) - cd $(basename ${REPO_PATH}) - git init - git remote add bpf-next ${KERNEL_ORIGIN} - # try shallow clone first - git fetch --depth 32 bpf-next - # check if desired SHA exists - if ! git cat-file -e ${LINUX_SHA}^{commit} ; then - # if not, fetch all of bpf-next; slow and painful - git fetch bpf-next - fi - git reset --hard ${LINUX_SHA} + # but fallback to git fetch approach if that fails + git clone --depth ${FETCH_DEPTH} ${KERNEL_ORIGIN} ${REPO_PATH} + cd "${REPO_PATH}" + # check if desired SHA exists + if ! git cat-file -e ${LINUX_SHA}^{commit} ; then + # if not, fetch all of bpf-next; slow and painful + git fetch origin + fi + git reset --hard ${LINUX_SHA} + cd - fi - rm -rf ${REPO_PATH}/.git || true + if [ "${FETCH_DEPTH}" -eq 0 ]; then + rm -rf ${REPO_PATH}/.git || true + fi foldable end pull_kernel_srcs +else + echo "${REPO_PATH} directory already exists, will not download kernel sources" fi From 0af20a506f0c0b8cb48822e34a810d17e5bb523b Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Wed, 13 Nov 2024 14:13:26 -0800 Subject: [PATCH 8/9] build-selftests: v2 of the action inputs Changes in action inputs: * kernel-root is now a required input * kernel, kbuild-output and max-make-jobs are removed kernel-root input is required, because to build selftests one must to clone a kernel source tree first. The build script behavior can be directed more granularly with env variables: * KBUILD_OUTPUT now defaults to the kernel-root * VMLINUX_BTF now can be set externally * MAX_MAKE_JOBS can be set as env variable if desired Preparation script logic is removed: the rationale is that the caller is responsible for setting up required environment before building. Signed-off-by: Ihor Solodrai --- build-selftests/action.yml | 33 ++++++++++++------------------ build-selftests/build_selftests.sh | 17 +++++++-------- 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/build-selftests/action.yml b/build-selftests/action.yml index e066398..a040f3b 100644 --- a/build-selftests/action.yml +++ b/build-selftests/action.yml @@ -1,34 +1,27 @@ name: 'build selftests' description: 'Build BPF selftests' inputs: - kernel: - description: 'kernel version' - default: 'LATEST' - toolchain: - description: 'what toolchain to use' - default: 'gcc' - kbuild-output: - description: 'relative or absolute path to use for storing build artifacts' + arch: + description: 'arch' + required: true + kernel-root: + description: 'Path to the root of the kernel source tree' required: true - max-make-jobs: - description: 'Maximum number of jobs to use when running make (e.g argument to -j). Default: 4*nproc' - default: '' llvm-version: description: 'llvm version' required: false - default: '16' - arch: - description: 'arch' - required: true + default: '18' + toolchain: + description: 'gcc or llvm' + default: 'gcc' runs: using: "composite" steps: - name: build selftests shell: bash - run: | - kbuild_output="$(realpath ${{ inputs.kbuild-output }})" - export LLVM_VERSION=${{ inputs.llvm-version }} - ${GITHUB_ACTION_PATH}/build_selftests.sh "${{ inputs.arch }}" "${{ inputs.kernel }}" "${{ inputs.toolchain }}" "${kbuild_output}" env: - MAX_MAKE_JOBS: ${{ inputs.max-make-jobs }} + LLVM_VERSION: ${{ inputs.llvm-version }} + run: | + ${GITHUB_ACTION_PATH}/build_selftests.sh "${{ inputs.arch }}" "${{ inputs.toolchain }}" "${{ inputs.kernel-root }}" + diff --git a/build-selftests/build_selftests.sh b/build-selftests/build_selftests.sh index 9030242..29fd67c 100755 --- a/build-selftests/build_selftests.sh +++ b/build-selftests/build_selftests.sh @@ -5,10 +5,12 @@ set -euo pipefail source "${GITHUB_ACTION_PATH}/../helpers.sh" TARGET_ARCH="$1" -KERNEL="$2" -TOOLCHAIN="$3" -export KBUILD_OUTPUT="$4" -VMLINUX_H=${VMLINUX_H:-} +TOOLCHAIN="$2" +KERNEL_ROOT="$(realpath $3)" + +export KBUILD_OUTPUT="${KBUILD_OUTPUT:-${KERNEL_ROOT}}" +export VMLINUX_BTF="${VMLINUX_BTF:-${KBUILD_OUTPUT}/vmlinux}" +export VMLINUX_H="${VMLINUX_H:-}" ARCH="$(platform_to_kernel_arch ${TARGET_ARCH})" CROSS_COMPILE="" @@ -25,18 +27,13 @@ fi foldable start build_selftests "Building selftests with $TOOLCHAIN" -PREPARE_SELFTESTS_SCRIPT=$(find $GITHUB_WORKSPACE -name prepare_selftests-${KERNEL}.sh) -if [ -f "${PREPARE_SELFTESTS_SCRIPT}" ]; then - (cd "${KERNEL_ROOT}/tools/testing/selftests/bpf" && ${PREPARE_SELFTESTS_SCRIPT}) -fi - MAKE_OPTS=$(cat < Date: Wed, 13 Nov 2024 14:24:51 -0800 Subject: [PATCH 9/9] ci workflows: cached kernel build and updated actions Introduce CACHED_KERNEL_BUILD variable and change download/build steps to make use of the cached incremental build on libbpf/ci workflows. Change parameters passed to build-selftests. Add a step preparing allow/denylist before running vmtest. Signed-off-by: Ihor Solodrai --- .github/workflows/kernel-build.yml | 52 ++++++++++++++++-------------- .github/workflows/kernel-test.yml | 25 ++++++++++++++ 2 files changed, 53 insertions(+), 24 deletions(-) diff --git a/.github/workflows/kernel-build.yml b/.github/workflows/kernel-build.yml index 071e9ff..96cbf66 100644 --- a/.github/workflows/kernel-build.yml +++ b/.github/workflows/kernel-build.yml @@ -46,16 +46,13 @@ jobs: timeout-minutes: 100 env: ARTIFACTS_ARCHIVE: "vmlinux-${{ inputs.arch }}-${{ inputs.toolchain_full }}.tar.zst" - BASE_BRANCH: >- - ${{ github.event_name == 'push' && github.ref_name - || github.base_ref - || 'bpf-next' - }} BUILD_SCHED_EXT_SELFTESTS: ${{ inputs.arch == 'x86_64' || inputs.arch == 'aarch64' && 'true' || '' }} + CACHED_KERNEL_BUILD: ${{ github.event_name == 'push' || github.repository == 'libbpf/ci' && 'true' || '' }} KBUILD_OUTPUT: ${{ github.workspace }}/kbuild-output KERNEL: ${{ inputs.kernel }} REPO_PATH: "" REPO_ROOT: ${{ github.workspace }} + KERNEL_ROOT: ${{ github.workspace }} steps: - uses: actions/checkout@v4 # We fetch an actual bit of history here to facilitate incremental @@ -64,23 +61,32 @@ jobs: fetch-depth: 50 - if: ${{ inputs.download_sources }} name: Download bpf-next tree + env: + FETCH_DEPTH: ${{ env.CACHED_KERNEL_BUILD && 16 || 0 }} uses: ./get-linux-source with: dest: '.kernel' - - if: ${{ inputs.download_sources }} - name: Move linux source in place - shell: bash - run: | - rm -rf .kernel/.git - cp -rf .kernel/. . - rm -rf .kernel - - uses: ./prepare-incremental-build + - if: ${{ env.CACHED_KERNEL_BUILD }} + uses: ./prepare-incremental-build with: - repo-root: ${{ env.REPO_ROOT }} - base-branch: ${{ env.BASE_BRANCH }} + repo-root: ${{ inputs.download_sources && '.kernel' || env.REPO_ROOT }} + base-branch: >- + ${{ github.repository == 'kernel-patches/bpf' && github.event_name == 'push' && github.ref_name + || github.repository == 'kernel-patches/bpf' && github.event_name != 'push' && github.base_ref + || 'master' + }} arch: ${{ inputs.arch }} toolchain_full: ${{ inputs.toolchain_full }} kbuild-output: ${{ env.KBUILD_OUTPUT }} + - if: ${{ inputs.download_sources }} + name: Move linux source in place + shell: bash + run: | + cd .kernel + rm -rf .git + mv -t .. $(ls -A) + cd .. + rmdir .kernel - uses: ./patch-kernel with: patches-root: '${{ github.workspace }}/ci/diffs' @@ -109,17 +115,15 @@ jobs: llvm-version: ${{ inputs.llvm-version }} - name: Build selftests/bpf uses: ./build-selftests + env: + MAX_MAKE_JOBS: 32 + RELEASE: ${{ inputs.release && '1' || '' }} with: arch: ${{ inputs.arch }} - toolchain: ${{ inputs.toolchain }} - kbuild-output: ${{ env.KBUILD_OUTPUT }} - max-make-jobs: 32 + kernel-root: ${{ env.KERNEL_ROOT }} llvm-version: ${{ inputs.llvm-version }} - env: - # RELEASE= disables all optimizaions - # RELEASE=0 adds -O0 make flag - # RELEASE=1 adds -O2 make flag - RELEASE: ${{ inputs.release && '1' || '' }} + toolchain: ${{ inputs.toolchain }} + - if: ${{ env.BUILD_SCHED_EXT_SELFTESTS }} name: Build selftests/sched_ext uses: ./build-scx-selftests @@ -151,7 +155,7 @@ jobs: archive: ${{ env.ARTIFACTS_ARCHIVE }} kbuild-output: ${{ env.KBUILD_OUTPUT }} repo-root: ${{ env.REPO_ROOT }} - - if: ${{ github.event_name != 'push' }} + - if: ${{ ! env.CACHED_KERNEL_BUILD }} name: Remove KBUILD_OUTPUT content shell: bash run: | diff --git a/.github/workflows/kernel-test.yml b/.github/workflows/kernel-test.yml index 21efc04..f2386ce 100644 --- a/.github/workflows/kernel-test.yml +++ b/.github/workflows/kernel-test.yml @@ -38,21 +38,46 @@ jobs: runs-on: ${{ fromJSON(inputs.runs_on) }} timeout-minutes: 100 env: + ARCH: ${{ inputs.arch }} KERNEL: ${{ inputs.kernel }} REPO_ROOT: ${{ github.workspace }} REPO_PATH: "" # https://github.com/actions/runner/issues/1483#issuecomment-1031671517 # booleans are weird in GH. CONTINUE_ON_ERROR: ${{ inputs.continue_on_error }} + DEPLOYMENT: ${{ github.repository == 'kernel-patches/bpf' && 'prod' || 'rc' }} + ALLOWLIST_FILE: /tmp/allowlist + DENYLIST_FILE: /tmp/denylist steps: - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 with: name: vmlinux-${{ inputs.arch }}-${{ inputs.toolchain_full }} path: . + - name: Untar artifacts # zstd is installed by default in the runner images. run: zstd -d -T0 vmlinux-${{ inputs.arch }}-${{ inputs.toolchain_full }}.tar.zst --stdout | tar -xf - + + - name: Prepare ALLOW/DENYLIST + env: + SELFTESTS_BPF: ${{ github.workspace }}/selftests/bpf + VMTEST_CONFIGS: ${{ github.workspace }}/ci/vmtest/configs + run: | + cat "${SELFTESTS_BPF}/ALLOWLIST" \ + "${SELFTESTS_BPF}/ALLOWLIST.${ARCH}" \ + "${VMTEST_CONFIGS}/ALLOWLIST" \ + "${VMTEST_CONFIGS}/ALLOWLIST.${ARCH}" \ + 2> /dev/null > "${ALLOWLIST_FILE}" || true + + cat "${SELFTESTS_BPF}/DENYLIST" \ + "${SELFTESTS_BPF}/DENYLIST.${ARCH}" \ + "${VMTEST_CONFIGS}/DENYLIST" \ + "${VMTEST_CONFIGS}/DENYLIST.${ARCH}" \ + "${VMTEST_CONFIGS}/DENYLIST.${DEPLOYMENT}" \ + 2> /dev/null > "${DENYLIST_FILE}" || true + - name: Run selftests uses: ./run-vmtest # https://github.com/actions/runner/issues/1483#issuecomment-1031671517