Skip to content

aarch64: interrupts:timer_interrupt_running intermittently reads the global tick counter as not advancing (~2% on -cpu cortex-a72) #644

Description

@ryanbreen

Summary

One boot in the 50-boot service-sequence battery on fix/prb-producer-custody (branch tip
f4ec3e60 plus the gate-tolerance-removal change) failed the aggregate boot-test score on a
single test:

[TEST:interrupts:timer_interrupt_running:FAIL:timer tick counter not advancing - interrupts not firing]
[TESTS_COMPLETE:107/107:FAILED:1]
[BOOT_TESTS:FAIL:1]

Classifier verdict, verbatim from the gate census:

BOOT_TEST_FAIL — boot test failure: [TEST:interrupts:timer_interrupt_running:FAIL:timer tick counter not advancing - interrupts not firing] (qemu_status=0)

BOOT_TEST_FAIL is a hard-failing bucket and has been one since it was introduced, so this red
is independent of the #635 tolerance removal that the same run was proving.

What the boot actually did

The boot was otherwise healthy and completed the whole service sequence:

  • [init] Boot script completed, [spawn] path='/bin/bounce', 15 heartbeats after it
  • all 107 boot tests ran; exactly one failed
  • zero [INSTRUCTION_ABORT], zero [DATA_ABORT], zero KERNEL PANIC
  • zero [RESUME_PC_REFUSED:], zero [RET_DISPATCH_REFUSED:]
  • ctx596_divergence=2 (reported, not gated)

Four other timer tests PASSED in the same boot, on both sides of the failure:

225:[TEST:timer:timer_init:PASS]
248:[TEST:timer:timer_ticks:PASS]
255:[TEST:timer:timer_delay:PASS]
259:[TEST:timer:timer_monotonic:PASS]
270:[TEST:interrupts:timer_interrupt_running:FAIL:...]
352:[TEST:timer:timer_quantum_reset_aarch64:PASS]

So the global tick counter demonstrably advanced elsewhere in this same boot.

What the test measures

kernel/src/test_framework/registry.rs:3244 (test_timer_interrupt_running): read
crate::time::timer::get_ticks(), busy-spin until timer::rdtsc() has advanced
(timer::frequency_hz() * 15) / 1000 counter ticks, read get_ticks() again, and fail if the
second read is not strictly greater. TICKS is one global AtomicU64 incremented from the timer
interrupt stub (kernel/src/time/timer.rs:65).

Two mechanisms are consistent with the evidence and NEITHER is verified here:

  1. the ~15 ms window really passed with no timer interrupt landing on any CPU;
  2. the window was much shorter than 15 ms of real time because frequency_hz() returned a value
    that made wait_ticks small (at the limit, freq == 0 makes wait_ticks == 0 and the spin
    exits immediately, which fails deterministically).

Distinguishing them needs the actual ticks_before/ticks_after/freq/wait_ticks values,
which the test does not currently emit.

Reproduction and rate

  • ./docker/qemu/run-aarch64-service-sequence-gate.sh --rebuild (25 boots per profile,
    -M virt,gic-version=3 -smp 4 -m 512, IOPS throttle 2000, 45 s timeout)
  • occurred on -cpu cortex-a72 boot 10; -cpu max was 25/25 GREEN
  • ./docker/qemu/run-aarch64-boot-test-strict.sh on the same kernel and the same
    -cpu cortex-a72 -smp 4 profile was 20/20 immediately afterwards

Observed rate on this kernel: 1 occurrence in 45 cortex-a72 boots (~2%), 0 in 25 max boots.

Preserved serial

docs/planning/t3g-prb/serials/prb-stage3-ss-gate-cortexa72-boot10-timer-not-advancing-20260823T115457Z.txt

Not established here

Whether this signature is branch-caused or pre-existing is NOT established by this run. It does
not appear in any serial preserved in this repository before today, but no prior campaign
preserved a green boot's serial either, so absence is not evidence. Settling it needs a
same-profile baseline soak (-cpu cortex-a72 -smp 4, IOPS 2000) on main at the same boot count.

Related

Same family of symptom as #536 (timer:timer_delay reading as failed under load), but a
different test and a different field signature.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions