Skip to content

Commit 58f6291

Browse files
author
Kernel Patches Daemon
committed
adding ci files
1 parent 8ca77b8 commit 58f6291

File tree

45 files changed

+3015
-18
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+3015
-18
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: 'run-veristat'
2+
description: 'Run veristat benchmark'
3+
inputs:
4+
veristat_output:
5+
description: 'Veristat output filepath'
6+
required: true
7+
baseline_name:
8+
description: 'Veristat baseline cache name'
9+
required: true
10+
runs:
11+
using: "composite"
12+
steps:
13+
- uses: actions/upload-artifact@v4
14+
with:
15+
name: ${{ inputs.baseline_name }}
16+
if-no-files-found: error
17+
path: ${{ github.workspace }}/${{ inputs.veristat_output }}
18+
19+
# For pull request:
20+
# - get baseline log from cache
21+
# - compare it to current run
22+
- if: ${{ github.event_name == 'pull_request' }}
23+
uses: actions/cache/restore@v4
24+
with:
25+
key: ${{ inputs.baseline_name }}
26+
restore-keys: |
27+
${{ inputs.baseline_name }}-
28+
path: '${{ github.workspace }}/${{ inputs.baseline_name }}'
29+
30+
- if: ${{ github.event_name == 'pull_request' }}
31+
name: Show veristat comparison
32+
shell: bash
33+
run: ./.github/scripts/compare-veristat-results.sh
34+
env:
35+
BASELINE_PATH: ${{ github.workspace }}/${{ inputs.baseline_name }}
36+
VERISTAT_OUTPUT: ${{ inputs.veristat_output }}
37+
38+
# For push: just put baseline log to cache
39+
- if: ${{ github.event_name == 'push' }}
40+
shell: bash
41+
run: |
42+
mv "${{ github.workspace }}/${{ inputs.veristat_output }}" \
43+
"${{ github.workspace }}/${{ inputs.baseline_name }}"
44+
45+
- if: ${{ github.event_name == 'push' }}
46+
uses: actions/cache/save@v4
47+
with:
48+
key: ${{ inputs.baseline_name }}-${{ github.run_id }}
49+
path: '${{ github.workspace }}/${{ inputs.baseline_name }}'
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
3+
if [[ ! -f "${BASELINE_PATH}" ]]; then
4+
echo "# No ${BASELINE_PATH} available" >> "${GITHUB_STEP_SUMMARY}"
5+
6+
echo "No ${BASELINE_PATH} available"
7+
echo "Printing veristat results"
8+
cat "${VERISTAT_OUTPUT}"
9+
10+
exit
11+
fi
12+
13+
selftests/bpf/veristat \
14+
--output-format csv \
15+
--emit file,prog,verdict,states \
16+
--compare "${BASELINE_PATH}" "${VERISTAT_OUTPUT}" > compare.csv
17+
18+
python3 ./.github/scripts/veristat_compare.py compare.csv

.github/scripts/matrix.py

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
import dataclasses
5+
import json
6+
7+
from enum import Enum
8+
from typing import Any, Dict, List, Final, Set, Union
9+
10+
MANAGED_OWNER: Final[str] = "kernel-patches"
11+
MANAGED_REPOS: Final[Set[str]] = {
12+
f"{MANAGED_OWNER}/bpf",
13+
f"{MANAGED_OWNER}/vmtest",
14+
}
15+
# We need to run on ubuntu 20.04 because our rootfs is based on debian buster and we
16+
# otherwise get library versioning issue such as
17+
# `./test_verifier: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./test_verifier)`
18+
DEFAULT_RUNNER: Final[str] = "ubuntu-20.04"
19+
DEFAULT_LLVM_VERSION: Final[int] = 17
20+
DEFAULT_SELF_HOSTED_RUNNER_TAGS: Final[List[str]] = ["self-hosted", "docker-noble-main"]
21+
22+
23+
class Arch(str, Enum):
24+
"""
25+
CPU architecture supported by CI.
26+
"""
27+
28+
AARCH64 = "aarch64"
29+
S390X = "s390x"
30+
X86_64 = "x86_64"
31+
32+
33+
class Compiler(str, Enum):
34+
GCC = "gcc"
35+
LLVM = "llvm"
36+
37+
38+
@dataclasses.dataclass
39+
class Toolchain:
40+
compiler: Compiler
41+
# This is relevant ONLY for LLVM and should not be required for GCC
42+
version: int
43+
44+
@property
45+
def short_name(self) -> str:
46+
return str(self.compiler.value)
47+
48+
@property
49+
def full_name(self) -> str:
50+
if self.compiler == Compiler.GCC:
51+
return self.short_name
52+
53+
return f"{self.short_name}-{self.version}"
54+
55+
def to_dict(self) -> Dict[str, Union[str, int]]:
56+
return {
57+
"name": self.short_name,
58+
"fullname": self.full_name,
59+
"version": self.version,
60+
}
61+
62+
63+
@dataclasses.dataclass
64+
class BuildConfig:
65+
arch: Arch
66+
toolchain: Toolchain
67+
kernel: str = "LATEST"
68+
run_veristat: bool = False
69+
parallel_tests: bool = False
70+
build_release: bool = False
71+
72+
@property
73+
def runs_on(self) -> List[str]:
74+
if is_managed_repo():
75+
return DEFAULT_SELF_HOSTED_RUNNER_TAGS + [self.arch.value]
76+
return [DEFAULT_RUNNER]
77+
78+
@property
79+
def build_runs_on(self) -> List[str]:
80+
if is_managed_repo():
81+
# Build s390x on x86_64
82+
return DEFAULT_SELF_HOSTED_RUNNER_TAGS + [
83+
self.arch.value == "s390x" and Arch.X86_64.value or self.arch.value,
84+
]
85+
return [DEFAULT_RUNNER]
86+
87+
@property
88+
def tests(self) -> Dict[str, Any]:
89+
tests_list = [
90+
"test_progs",
91+
"test_progs_parallel",
92+
"test_progs_no_alu32",
93+
"test_progs_no_alu32_parallel",
94+
"test_verifier",
95+
]
96+
97+
if self.arch.value != "s390x":
98+
tests_list.append("test_maps")
99+
100+
if self.toolchain.version >= 18:
101+
tests_list.append("test_progs_cpuv4")
102+
103+
if not self.parallel_tests:
104+
tests_list = [test for test in tests_list if not test.endswith("parallel")]
105+
106+
return {"include": [generate_test_config(test) for test in tests_list]}
107+
108+
def to_dict(self) -> Dict[str, Any]:
109+
return {
110+
"arch": self.arch.value,
111+
"toolchain": self.toolchain.to_dict(),
112+
"kernel": self.kernel,
113+
"run_veristat": self.run_veristat,
114+
"parallel_tests": self.parallel_tests,
115+
"build_release": self.build_release,
116+
"runs_on": self.runs_on,
117+
"tests": self.tests,
118+
"build_runs_on": self.build_runs_on,
119+
}
120+
121+
122+
def is_managed_repo() -> bool:
123+
return (
124+
os.environ["GITHUB_REPOSITORY_OWNER"] == MANAGED_OWNER
125+
and os.environ["GITHUB_REPOSITORY"] in MANAGED_REPOS
126+
)
127+
128+
129+
def set_output(name, value):
130+
"""Write an output variable to the GitHub output file."""
131+
with open(os.getenv("GITHUB_OUTPUT"), "a", encoding="utf-8") as file:
132+
file.write(f"{name}={value}\n")
133+
134+
135+
def generate_test_config(test: str) -> Dict[str, Union[str, int]]:
136+
"""Create the configuration for the provided test."""
137+
is_parallel = test.endswith("_parallel")
138+
config = {
139+
"test": test,
140+
"continue_on_error": is_parallel,
141+
# While in experimental mode, parallel jobs may get stuck
142+
# anywhere, including in user space where the kernel won't detect
143+
# a problem and panic. We add a second layer of (smaller) timeouts
144+
# here such that if we get stuck in a parallel run, we hit this
145+
# timeout and fail without affecting the overall job success (as
146+
# would be the case if we hit the job-wide timeout). For
147+
# non-experimental jobs, 360 is the default which will be
148+
# superseded by the overall workflow timeout (but we need to
149+
# specify something).
150+
"timeout_minutes": 30 if is_parallel else 360,
151+
}
152+
return config
153+
154+
155+
if __name__ == "__main__":
156+
matrix = [
157+
BuildConfig(
158+
arch=Arch.X86_64,
159+
toolchain=Toolchain(compiler=Compiler.GCC, version=DEFAULT_LLVM_VERSION),
160+
run_veristat=True,
161+
parallel_tests=True,
162+
),
163+
BuildConfig(
164+
arch=Arch.X86_64,
165+
toolchain=Toolchain(compiler=Compiler.LLVM, version=DEFAULT_LLVM_VERSION),
166+
build_release=True,
167+
),
168+
BuildConfig(
169+
arch=Arch.X86_64,
170+
toolchain=Toolchain(compiler=Compiler.LLVM, version=18),
171+
build_release=True,
172+
),
173+
BuildConfig(
174+
arch=Arch.AARCH64,
175+
toolchain=Toolchain(compiler=Compiler.GCC, version=DEFAULT_LLVM_VERSION),
176+
),
177+
# BuildConfig(
178+
# arch=Arch.AARCH64,
179+
# toolchain=Toolchain(
180+
# compiler=Compiler.LLVM,
181+
# version=DEFAULT_LLVM_VERSION
182+
# ),
183+
# ),
184+
BuildConfig(
185+
arch=Arch.S390X,
186+
toolchain=Toolchain(compiler=Compiler.GCC, version=DEFAULT_LLVM_VERSION),
187+
),
188+
]
189+
190+
# Outside of those repositories we only run on x86_64
191+
if not is_managed_repo():
192+
matrix = [config for config in matrix if config.arch == Arch.X86_64]
193+
194+
json_matrix = json.dumps({"include": [config.to_dict() for config in matrix]})
195+
print(json_matrix)
196+
set_output("build_matrix", json_matrix)

.github/scripts/tar-artifact.sh

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#!/bin/bash
2+
3+
set -eux
4+
5+
# Assumptions:
6+
# - $(pwd) is the root of kernel repo we're tarring
7+
# - zstd is installed by default in the runner images
8+
9+
if [ ! -d "${KBUILD_OUTPUT:-}" ]; then
10+
echo "KBUILD_OUTPUT must be a directory"
11+
exit 1
12+
fi
13+
14+
arch="${1}"
15+
toolchain="${2}"
16+
17+
# Convert a platform (as returned by uname -m) to the kernel
18+
# arch (as expected by ARCH= env).
19+
platform_to_kernel_arch() {
20+
case $1 in
21+
s390x)
22+
echo "s390"
23+
;;
24+
aarch64)
25+
echo "arm64"
26+
;;
27+
riscv64)
28+
echo "riscv"
29+
;;
30+
x86_64)
31+
echo "x86"
32+
;;
33+
*)
34+
echo "$1"
35+
;;
36+
esac
37+
}
38+
39+
# Remove intermediate object files that we have no use for. Ideally
40+
# we'd just exclude them from tar below, but it does not provide
41+
# options to express the precise constraints.
42+
find tools/testing/selftests/ -name "*.o" -a ! -name "*.bpf.o" -print0 | \
43+
xargs --null --max-args=10000 rm
44+
45+
# Strip debug information, which is excessively large (consuming
46+
# bandwidth) while not actually being used (the kernel does not use
47+
# DWARF to symbolize stacktraces).
48+
"${arch}"-linux-gnu-strip --strip-debug "${KBUILD_OUTPUT}"/vmlinux
49+
50+
image_name=$(make ARCH="$(platform_to_kernel_arch "${arch}")" -s image_name)
51+
kbuild_output_file_list=(
52+
".config"
53+
"${image_name}"
54+
"include/config/auto.conf"
55+
"include/generated/autoconf.h"
56+
"vmlinux"
57+
)
58+
59+
# While we are preparing the tarball, move $KBUILD_OUTPUT to a tmp
60+
# location just in case it's inside the repo root
61+
tmp=$(mktemp -d)
62+
mv "${KBUILD_OUTPUT}" "${tmp}"
63+
stashed_kbuild_output=${tmp}/$(basename "${KBUILD_OUTPUT}")
64+
65+
# Note: ${local_kbuild_output} must point to ./kbuild-output because
66+
# of the tar command at the bottom.
67+
local_kbuild_output=$(realpath kbuild-output)
68+
mkdir -p "${local_kbuild_output}"
69+
70+
for file in "${kbuild_output_file_list[@]}"; do
71+
mkdir -p "$(dirname "${local_kbuild_output}/${file}")"
72+
cp -a "${stashed_kbuild_output}/${file}" "${local_kbuild_output}/${file}"
73+
done
74+
75+
additional_file_list=()
76+
if [[ -n "${ARCHIVE_MAKE_HELPERS}" ]]; then
77+
# Package up a bunch of additional infrastructure to support running
78+
# 'make kernelrelease' and bpf tool checks later on.
79+
mapfile -t additional_file_list < <(find . -iname Makefile)
80+
additional_file_list+=(
81+
"scripts/"
82+
"tools/testing/selftests/bpf/"
83+
"tools/include/"
84+
"tools/bpf/bpftool/"
85+
)
86+
fi
87+
88+
mkdir -p selftests
89+
cp -r tools/testing/selftests/bpf selftests
90+
if [[ -n "${BUILD_SCHED_EXT_SELFTESTS}" ]]; then
91+
cp -r tools/testing/selftests/sched_ext selftests
92+
fi
93+
94+
tar -cf - \
95+
kbuild-output \
96+
"${additional_file_list[@]}" \
97+
--exclude '*.cmd' \
98+
--exclude '*.d' \
99+
--exclude '*.h' \
100+
--exclude '*.output' \
101+
selftests/ \
102+
| zstd -T0 -19 -o "vmlinux-${arch}-${toolchain}.tar.zst"
103+
104+
# Cleanup and restore the original KBUILD_OUTPUT
105+
# We have to put KBUILD_OUTPUT back to its original location for actions/cache
106+
rm -rf "${local_kbuild_output}"
107+
mv "${stashed_kbuild_output}" "${KBUILD_OUTPUT}"

0 commit comments

Comments
 (0)