From 83dfcf30e69c9661044929e67527381530633893 Mon Sep 17 00:00:00 2001 From: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> Date: Thu, 15 Oct 2026 10:54:52 -0700 Subject: [PATCH 1/3] Add weekly MSHV 6.18 test and benchmark workflow Add WeeklyMshv618.yml, which runs the mshv3 build-test, examples, and benchmarks on the hld-azlinux3-mshv-6.18-{amd,intel} pools every Monday. A failure opens or updates a release-blocking issue labeled area/ci-periodics-mshv-6.18. Add an optional mshv_kernel input to dep_build_test, dep_run_examples, and dep_benchmarks. It selects the hld-azlinux3-mshv-- pool. Callers that omit it keep the existing pools. The run keeps hypervisor mshv3, so it uses the mshv3 feature, Justfile recipes, and Rust cache keys. Both pools run Azure Linux 3. Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> --- .github/workflows/WeeklyMshv618.yml | 101 +++++++++++++++++++++++++ .github/workflows/dep_benchmarks.yml | 7 +- .github/workflows/dep_build_test.yml | 7 +- .github/workflows/dep_run_examples.yml | 7 +- docs/github-labels.md | 1 + 5 files changed, 120 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/WeeklyMshv618.yml diff --git a/.github/workflows/WeeklyMshv618.yml b/.github/workflows/WeeklyMshv618.yml new file mode 100644 index 0000000000..3773d85bab --- /dev/null +++ b/.github/workflows/WeeklyMshv618.yml @@ -0,0 +1,101 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json + +name: Weekly MSHV 6.18 + +# Runs the mshv3 tests, examples and benchmarks on the Azure Linux 3 pools with +# the MSHV 6.18 kernel. PRs test only the default mshv3 pools. + +on: + # TODO: remove before merging. Runs this workflow on its own PR. + pull_request: + paths: + - '.github/workflows/WeeklyMshv618.yml' + schedule: + - cron: '0 3 * * 1' # Runs at 03:00 UTC every Monday + workflow_dispatch: # Allow manual triggering + +permissions: + contents: read + +jobs: + build-guests: + strategy: + fail-fast: false + matrix: + config: [debug, release] + uses: ./.github/workflows/dep_build_guests.yml + secrets: inherit + with: + arch: X64 + config: ${{ matrix.config }} + + build-test: + needs: build-guests + permissions: + # checkout in the called workflow + contents: read + # pull goldens from GHCR in the called workflow + packages: read + strategy: + fail-fast: false + matrix: + cpu_vendor: [amd, intel] + config: [debug, release] + uses: ./.github/workflows/dep_build_test.yml + secrets: inherit + with: + hypervisor: mshv3 + mshv_kernel: "6.18" + cpu_vendor: ${{ matrix.cpu_vendor }} + arch: X64 + config: ${{ matrix.config }} + + run-examples: + needs: build-guests + strategy: + fail-fast: false + matrix: + cpu_vendor: [amd, intel] + config: [debug, release] + uses: ./.github/workflows/dep_run_examples.yml + secrets: inherit + with: + hypervisor: mshv3 + mshv_kernel: "6.18" + cpu_vendor: ${{ matrix.cpu_vendor }} + arch: X64 + config: ${{ matrix.config }} + + benchmarks: + needs: build-guests + strategy: + fail-fast: false + matrix: + cpu_vendor: [amd, intel] + uses: ./.github/workflows/dep_benchmarks.yml + secrets: inherit + with: + hypervisor: mshv3 + mshv_kernel: "6.18" + cpu_vendor: ${{ matrix.cpu_vendor }} + arch: X64 + + # The first label is the de-duplication key used by notify-ci-failure.sh, so + # these failures share one release-blocking issue. That label must exist in + # the repo or `gh issue create` fails. + notify-failure: + runs-on: ubuntu-latest + needs: [build-guests, build-test, run-examples, benchmarks] + if: always() && github.event_name != 'pull_request' && (needs.build-guests.result == 'failure' || needs.build-test.result == 'failure' || needs.run-examples.result == 'failure' || needs.benchmarks.result == 'failure') + permissions: + # Job-level permissions replace the workflow-level grant, so checkout needs contents:read here. + contents: read + issues: write + steps: + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Notify Weekly MSHV 6.18 Failure + run: ./dev/notify-ci-failure.sh --title="Weekly MSHV 6.18 Failure - ${{ github.run_number }}" --labels="area/ci-periodics-mshv-6.18,area/ci-periodics,area/testing,lifecycle/needs-review,release-blocker" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/dep_benchmarks.yml b/.github/workflows/dep_benchmarks.yml index d767f1f330..a488c42360 100644 --- a/.github/workflows/dep_benchmarks.yml +++ b/.github/workflows/dep_benchmarks.yml @@ -31,6 +31,11 @@ on: description: CPU architecture for the build, X64 or arm64 (passed from caller matrix) required: true type: string + mshv_kernel: + description: MSHV kernel of the Azure Linux 3 pool, for example 6.18. Empty selects the default mshv3 pool. + required: false + type: string + default: "" baseline_ref: description: >- Commit to measure these results against. When set, its benchmarks run @@ -57,7 +62,7 @@ jobs: runs-on: ${{ fromJson(inputs.arch == 'X64' && format('["self-hosted", "{0}", "X64", "1ES.Pool=hld-{1}-{2}", "JobId=run-benchmarks-{3}-{4}-{5}"]', inputs.hypervisor == 'hyperv-ws2025' && 'Windows' || 'Linux', - inputs.hypervisor == 'hyperv-ws2025' && 'win2025' || inputs.hypervisor == 'mshv3' && 'azlinux3-mshv' || inputs.hypervisor, + inputs.hypervisor == 'hyperv-ws2025' && 'win2025' || inputs.hypervisor == 'mshv3' && format('azlinux3-mshv{0}', inputs.mshv_kernel != '' && format('-{0}', inputs.mshv_kernel) || '') || inputs.hypervisor, inputs.cpu_vendor, github.run_id, github.run_number, diff --git a/.github/workflows/dep_build_test.yml b/.github/workflows/dep_build_test.yml index e7e407efe0..9119421cad 100644 --- a/.github/workflows/dep_build_test.yml +++ b/.github/workflows/dep_build_test.yml @@ -26,6 +26,11 @@ on: description: CPU architecture for the build (passed from caller matrix) required: true type: string + mshv_kernel: + description: MSHV kernel of the Azure Linux 3 pool, for example 6.18. Empty selects the default mshv3 pool. + required: false + type: string + default: "" full_aarch64: description: >- When "true", also run the single-driver tests on aarch64. PRs leave @@ -61,7 +66,7 @@ jobs: runs-on: ${{ fromJson(inputs.arch == 'X64' && format('["self-hosted", "{0}", "X64", "1ES.Pool=hld-{1}-{2}", "JobId=build-and-test-{3}-{4}-{5}-{6}"]', inputs.hypervisor == 'hyperv-ws2025' && 'Windows' || 'Linux', - inputs.hypervisor == 'hyperv-ws2025' && 'win2025' || inputs.hypervisor == 'mshv3' && 'azlinux3-mshv' || inputs.hypervisor, + inputs.hypervisor == 'hyperv-ws2025' && 'win2025' || inputs.hypervisor == 'mshv3' && format('azlinux3-mshv{0}', inputs.mshv_kernel != '' && format('-{0}', inputs.mshv_kernel) || '') || inputs.hypervisor, inputs.cpu_vendor, inputs.config, github.run_id, diff --git a/.github/workflows/dep_run_examples.yml b/.github/workflows/dep_run_examples.yml index d4aa45c264..7609953c3f 100644 --- a/.github/workflows/dep_run_examples.yml +++ b/.github/workflows/dep_run_examples.yml @@ -26,6 +26,11 @@ on: description: CPU architecture for the build (passed from caller matrix) required: true type: string + mshv_kernel: + description: MSHV kernel of the Azure Linux 3 pool, for example 6.18. Empty selects the default mshv3 pool. + required: false + type: string + default: "" env: CARGO_TERM_COLOR: always @@ -45,7 +50,7 @@ jobs: runs-on: ${{ fromJson(inputs.arch == 'X64' && format('["self-hosted", "{0}", "X64", "1ES.Pool=hld-{1}-{2}", "JobId=run-examples-{3}-{4}-{5}-{6}"]', inputs.hypervisor == 'hyperv-ws2025' && 'Windows' || 'Linux', - inputs.hypervisor == 'hyperv-ws2025' && 'win2025' || inputs.hypervisor == 'mshv3' && 'azlinux3-mshv' || inputs.hypervisor, + inputs.hypervisor == 'hyperv-ws2025' && 'win2025' || inputs.hypervisor == 'mshv3' && format('azlinux3-mshv{0}', inputs.mshv_kernel != '' && format('-{0}', inputs.mshv_kernel) || '') || inputs.hypervisor, inputs.cpu_vendor, inputs.config, github.run_id, diff --git a/docs/github-labels.md b/docs/github-labels.md index 810d02a9f0..9dfe8a8e1c 100644 --- a/docs/github-labels.md +++ b/docs/github-labels.md @@ -63,6 +63,7 @@ In addition to **kind/*** labels, we use optional **area/*** labels to specify t - **area/API** - Related to the API or public interface. - **area/ci-periodics** - Applied to issues that track failures from scheduled (periodic) CI jobs. These issues are opened automatically by the CI failure notifier (`dev/notify-ci-failure.sh`). - **area/ci-periodics-aarch64** - De-duplication label for failures from the daily aarch64 workflow (`.github/workflows/DailyArm64.yml`). It keeps those failures on their own dedicated, release-blocking issue instead of sharing the general `area/ci-periodics` issue. +- **area/ci-periodics-mshv-6.18** - De-duplication label for failures from the weekly MSHV 6.18 workflow (`.github/workflows/WeeklyMshv618.yml`). It keeps those failures on their own release-blocking issue. - **area/dependencies** - Concerns dependencies or related components. This label is different from **kind/dependencies**, which should only used for PRs. - **area/documentation** - Related to documentation updates or improvements. - **area/infrastructure** - Concerns infrastructure rather than core functionality. From aeb172b2f163a7d7a196ebc1c47c1ded2ac3b62f Mon Sep 17 00:00:00 2001 From: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> Date: Thu, 15 Oct 2026 12:10:21 -0700 Subject: [PATCH 2/3] Benchmark MSHV 6.18 daily instead of weekly Move the MSHV 6.18 benchmarks from WeeklyMshv618.yml to a separate DailyBenchmarks.yml job. Daily runs measure 6.6 and 6.18 on the same commit, in the same mode, at about the same time. A separate job keeps a 6.18 failure from cancelling the existing fail-fast matrix. Name benchmark artifacts benchmarks__-_ when mshv_kernel is set, so 6.18 results do not collide with the 6.6 artifacts in the same run. bench-report reads the new label as its own hypervisor, so 6.6 results never match a 6.18 baseline. Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> --- .github/workflows/DailyBenchmarks.yml | 20 ++++++++++++++++++-- .github/workflows/WeeklyMshv618.yml | 23 +++++------------------ .github/workflows/dep_benchmarks.yml | 9 +++++---- docs/benchmarking-hyperlight.md | 2 +- 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/.github/workflows/DailyBenchmarks.yml b/.github/workflows/DailyBenchmarks.yml index abf63cfd1b..9ece6a5ad8 100644 --- a/.github/workflows/DailyBenchmarks.yml +++ b/.github/workflows/DailyBenchmarks.yml @@ -38,11 +38,27 @@ jobs: cpu_vendor: ${{ matrix.cpu_vendor }} arch: ${{ matrix.arch }} + # mshv3 on the MSHV 6.18 kernel pools. A separate job, so a failure here + # cannot cancel the matrix above. + benchmarks-mshv-6-18: + needs: [build-guests] + strategy: + fail-fast: false + matrix: + cpu_vendor: [amd, intel] + uses: ./.github/workflows/dep_benchmarks.yml + secrets: inherit + with: + hypervisor: mshv3 + mshv_kernel: "6.18" + cpu_vendor: ${{ matrix.cpu_vendor }} + arch: X64 + # File a GitHub issue if any job fails. notify-failure: runs-on: ubuntu-latest - needs: [build-guests, benchmarks] - if: always() && (needs.build-guests.result == 'failure' || needs.benchmarks.result == 'failure') + needs: [build-guests, benchmarks, benchmarks-mshv-6-18] + if: always() && (needs.build-guests.result == 'failure' || needs.benchmarks.result == 'failure' || needs.benchmarks-mshv-6-18.result == 'failure') permissions: issues: write steps: diff --git a/.github/workflows/WeeklyMshv618.yml b/.github/workflows/WeeklyMshv618.yml index 3773d85bab..8efa70f9b9 100644 --- a/.github/workflows/WeeklyMshv618.yml +++ b/.github/workflows/WeeklyMshv618.yml @@ -2,8 +2,9 @@ name: Weekly MSHV 6.18 -# Runs the mshv3 tests, examples and benchmarks on the Azure Linux 3 pools with -# the MSHV 6.18 kernel. PRs test only the default mshv3 pools. +# Runs the mshv3 tests and examples on the Azure Linux 3 pools with the MSHV +# 6.18 kernel. PRs test only the default mshv3 pools. DailyBenchmarks.yml +# benchmarks these pools. on: # TODO: remove before merging. Runs this workflow on its own PR. @@ -66,27 +67,13 @@ jobs: arch: X64 config: ${{ matrix.config }} - benchmarks: - needs: build-guests - strategy: - fail-fast: false - matrix: - cpu_vendor: [amd, intel] - uses: ./.github/workflows/dep_benchmarks.yml - secrets: inherit - with: - hypervisor: mshv3 - mshv_kernel: "6.18" - cpu_vendor: ${{ matrix.cpu_vendor }} - arch: X64 - # The first label is the de-duplication key used by notify-ci-failure.sh, so # these failures share one release-blocking issue. That label must exist in # the repo or `gh issue create` fails. notify-failure: runs-on: ubuntu-latest - needs: [build-guests, build-test, run-examples, benchmarks] - if: always() && github.event_name != 'pull_request' && (needs.build-guests.result == 'failure' || needs.build-test.result == 'failure' || needs.run-examples.result == 'failure' || needs.benchmarks.result == 'failure') + needs: [build-guests, build-test, run-examples] + if: always() && github.event_name != 'pull_request' && (needs.build-guests.result == 'failure' || needs.build-test.result == 'failure' || needs.run-examples.result == 'failure') permissions: # Job-level permissions replace the workflow-level grant, so checkout needs contents:read here. contents: read diff --git a/.github/workflows/dep_benchmarks.yml b/.github/workflows/dep_benchmarks.yml index a488c42360..3df209031b 100644 --- a/.github/workflows/dep_benchmarks.yml +++ b/.github/workflows/dep_benchmarks.yml @@ -5,9 +5,10 @@ # Artifact upload: # Benchmark results are uploaded as workflow artifacts named # benchmarks___, kept for as long as GitHub -# allows so that a later run can still be compared against them. Reading -# them is left to whoever wants a report, so that a comparison covers every -# configuration at once. +# allows so that a later run can still be compared against them. A set +# mshv_kernel joins the hypervisor, as in benchmarks_Linux_mshv3-6.18_amd. +# Reading them is left to whoever wants a report, so that a comparison +# covers every configuration at once. name: Run Benchmarks @@ -136,7 +137,7 @@ jobs: - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: benchmarks_${{ runner.os }}_${{ inputs.hypervisor }}_${{ inputs.cpu_vendor }} + name: benchmarks_${{ runner.os }}_${{ inputs.hypervisor }}${{ inputs.mshv_kernel != '' && format('-{0}', inputs.mshv_kernel) || '' }}_${{ inputs.cpu_vendor }} path: ./target/criterion/ if-no-files-found: error # The longest GitHub keeps an artifact, so that a run stays readable diff --git a/docs/benchmarking-hyperlight.md b/docs/benchmarking-hyperlight.md index dfa8c3012e..4ccb6adbb4 100644 --- a/docs/benchmarking-hyperlight.md +++ b/docs/benchmarking-hyperlight.md @@ -5,7 +5,7 @@ Hyperlight uses the [Criterion](https://bheisler.github.io/criterion.rs/book/ind ## When Benchmarks are run 1. Daily (scheduled) - - Benchmarks run daily via `DailyBenchmarks.yml`. Results are stored as workflow artifacts with 90-day retention, and are what pull requests are compared against. + - Benchmarks run daily via `DailyBenchmarks.yml`. Results are stored as workflow artifacts with 90-day retention, and are what pull requests are compared against. The daily run also benchmarks mshv3 on the MSHV 6.18 kernel pools, as `benchmarks_Linux_mshv3-6.18_`. ``` sandboxes/create_sandbox From d784c30009c149dd8a0d0bacd10a401e2142e12d Mon Sep 17 00:00:00 2001 From: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> Date: Thu, 15 Oct 2026 12:12:26 -0700 Subject: [PATCH 3/3] Remove temporary PR trigger from WeeklyMshv618.yml Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> --- .github/workflows/WeeklyMshv618.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/WeeklyMshv618.yml b/.github/workflows/WeeklyMshv618.yml index 8efa70f9b9..13ece032d9 100644 --- a/.github/workflows/WeeklyMshv618.yml +++ b/.github/workflows/WeeklyMshv618.yml @@ -7,10 +7,6 @@ name: Weekly MSHV 6.18 # benchmarks these pools. on: - # TODO: remove before merging. Runs this workflow on its own PR. - pull_request: - paths: - - '.github/workflows/WeeklyMshv618.yml' schedule: - cron: '0 3 * * 1' # Runs at 03:00 UTC every Monday workflow_dispatch: # Allow manual triggering