BPI-R64 hardpps soak — tickful (nohz=off), 5s pulses

1 Hz pulses5 s pulses
tickless (NO_HZ_IDLE)tickless, 1Hztickless, 5s
tickful (nohz=off)tickful, 1Hztickful, 5s

Cortex-A53 (BPI-R64), 12.5 MHz arch counter, u-blox GNSS timepulse into pps-gpio, in-kernel hardpps() disciplining CLOCK_REALTIME with STA_PPSTIME|STA_PPSFREQ|STA_PLL. Kernel: the timekeeping series (timekeeping branch) on 7.3-rc1 — including the idle-sleep bound while a slew is in flight and the proportional ntp_error correction — plus silent bench instrumentation (per-pulse ring captured in the PPS hardirq, drained to disk once a minute in the pulse's shadow). No distro userspace: a single static PID 1 sets the date from NMEA, binds hardpps, and sleeps. All periodic wakeup sources were disabled (vmstat, runtime-PM autosuspend, fair dl_server, ethernet not probed). Tickless cells boot NO_HZ_IDLE; tickful cells add nohz=off on the same kernel binary.

2465 pulses over 3.4 h. Steady state (|ntp_error| at pulse, after 60 min): median 1 ns, p95 16 ns, p99 1314 ns, max 105208 ns. Corrected pulse phase: median 0.4 µs, p95 3.9 µs.

Per-pulse snapshot ntp_error

Pulse arrival phase (corrected ts_real)

Discipline state

Tickless gap verification

ntp_error drain lifecycle

The proportional drain engages when accumulated ntp_error exceeds one minute's worth of ±1-dither delivery (~45 ns here), repays over ~10 s re-sized each second, hands back to the dither below threshold, and aborts mid-second if it overshoots zero.

PPS irq path latency

Counter value is stamped at exception vector entry; this measures entry to the timestamping snapshot in the pps-gpio hardirq — on tickless kernels the deferred timekeeping catch-up runs in between.

Methodology

This run is the test asked for on the list: hardpps on a tickless kernel driven by a real PPS source, with its real jitter and IRQ latency, and the CPU genuinely idle between pulses.

Data