pre-poweroff-load.sh runs the same mixed, deterministic workload before every poweroff, so each observation carries identical bus exposure in both the use_ecam=1 phase and the use_ecam=0 counter-proof. It records one line per run (use_ecam, srcversion, blocks, warns, spd_ok) and keeps the full per-run output beside it, then powers the machine off by itself. Two runs of 2026-08-09 are included: without them the log is a claim.
155 lines
5.2 KiB
Bash
Executable File
155 lines
5.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# pre-poweroff-load.sh - fixed SMBus load protocol for the A5 hang observation
|
|
# window (TODO.md E1), fully automatic: runs the load, saves observations,
|
|
# powers the machine off.
|
|
#
|
|
# Mixed, deterministic workload so that every poweroff in the window carries
|
|
# the same, high and *diverse* bus exposure - both in the use_ecam=1 phase and
|
|
# in the use_ecam=0 counter-proof phase. Each 3-minute block:
|
|
#
|
|
# 1. software effect (~2760 SMBus writes/s, steady stream) ~100 s
|
|
# 2. rapid hw/sw switch burst (6 alternations back-to-back:
|
|
# one-shot config-write bursts + apply latches) ~20 s
|
|
# 3. hardware effect (engine-side, bus quiet) ~30 s
|
|
# 4. full SPD dump of all 4 DIMMs via ee1004 (reads +
|
|
# page-selects) + serial integrity check ~30 s
|
|
#
|
|
# Effects rotate through fixed lists, so run N of phase A and run N of phase B
|
|
# execute the identical sequence.
|
|
#
|
|
# End of run: kernel-journal warnings and run context are saved to a per-run
|
|
# file in tools/pre-poweroff-runs/, one summary line is appended to
|
|
# pre-poweroff-load.log, and - only with --poweroff - the machine POWERS OFF
|
|
# (15 s grace, Ctrl-C to abort). The last software effect is left running into
|
|
# the poweroff on purpose: exposure should cover the shutdown path too; the
|
|
# systemd boot scene restores the normal LED state at next boot.
|
|
#
|
|
# The one exception: an SPD serial mismatch saves everything and does NOT
|
|
# power off - investigate before shutting down.
|
|
#
|
|
# Usage: sudo ./pre-poweroff-load.sh [minutes] [--poweroff]
|
|
# (default 30 minutes, in 3-min blocks; re-execs itself under sudo if
|
|
# started as a plain user; powers off at the end ONLY with --poweroff)
|
|
|
|
set -eu
|
|
|
|
[ "$(id -u)" -eq 0 ] || exec sudo "$0" "$@"
|
|
|
|
MINUTES=30
|
|
POWEROFF=0
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--poweroff) POWEROFF=1 ;;
|
|
*) MINUTES="$arg" ;;
|
|
esac
|
|
done
|
|
BLOCKS=$(((MINUTES + 2) / 3))
|
|
DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
LOG="$DIR/pre-poweroff-load.log"
|
|
RUNDIR="$DIR/pre-poweroff-runs"
|
|
START="$(date '+%Y-%m-%d %H:%M:%S')"
|
|
RUNFILE="$RUNDIR/$(date '+%Y%m%d-%H%M').log"
|
|
|
|
ANIMS=(aurora wave_rainbow plasma ripple gradient_pulse fire)
|
|
FX=(respiro arcobaleno cometa battito ciclico lampeggio)
|
|
# SPD EEPROMs at 0x50/0x52 (ee1004); i2c bus numbers depend on module load
|
|
# order, so discover them instead of hardcoding bus IDs.
|
|
mapfile -t EEPROMS < <(ls /sys/bus/i2c/devices/*-005[02]/eeprom 2>/dev/null | sort)
|
|
[ "${#EEPROMS[@]}" -eq 4 ] || { echo "ERROR: expected 4 SPD EEPROMs, found ${#EEPROMS[@]}"; exit 1; }
|
|
|
|
MODE="$(cat /sys/module/i2c_imc_skylake/parameters/use_ecam 2>/dev/null || echo '?')"
|
|
SRCV="$(cat /sys/module/i2c_imc_skylake/srcversion 2>/dev/null || echo '?')"
|
|
|
|
mkdir -p "$RUNDIR"
|
|
|
|
spd_serials() {
|
|
local e
|
|
for e in "${EEPROMS[@]}"; do
|
|
dd if="$e" bs=1 skip=325 count=4 2>/dev/null | xxd -p
|
|
done
|
|
}
|
|
|
|
echo "== pre-poweroff load: ${BLOCKS} blocks (~$((BLOCKS * 3)) min), use_ecam=${MODE}, srcversion=${SRCV}"
|
|
if [ "$POWEROFF" -eq 1 ]; then
|
|
echo "== POWERS OFF at the end. Run file: ${RUNFILE}"
|
|
else
|
|
echo "== no poweroff at the end (use --poweroff). Run file: ${RUNFILE}"
|
|
fi
|
|
|
|
REF_SERIALS="$(spd_serials)"
|
|
echo "== SPD serial reference: $(echo "$REF_SERIALS" | tr '\n' ' ')"
|
|
|
|
SPD_BAD=0
|
|
for ((b = 0; b < BLOCKS; b++)); do
|
|
anim="${ANIMS[b % ${#ANIMS[@]}]}"
|
|
fx="${FX[b % ${#FX[@]}]}"
|
|
echo "-- block $((b + 1))/${BLOCKS}: anim=${anim} fx=${fx}"
|
|
|
|
furyrs anim "$anim"
|
|
sleep 100
|
|
|
|
# rapid hw/sw alternation burst
|
|
for ((i = 0; i < 3; i++)); do
|
|
furyrs effect "${FX[(b + i) % ${#FX[@]}]}"
|
|
sleep 2
|
|
furyrs anim "${ANIMS[(b + i) % ${#ANIMS[@]}]}"
|
|
sleep 2
|
|
done
|
|
|
|
furyrs effect "$fx"
|
|
sleep 30
|
|
|
|
# full SPD dump (reads + ee1004 page-selects) + integrity check
|
|
for e in "${EEPROMS[@]}"; do
|
|
dd if="$e" bs=64 2>/dev/null >/dev/null
|
|
done
|
|
if [ "$(spd_serials)" != "$REF_SERIALS" ]; then
|
|
SPD_BAD=1
|
|
echo "!! SPD SERIAL MISMATCH in block $((b + 1)) - stopping, will NOT power off"
|
|
break
|
|
fi
|
|
done
|
|
|
|
# leave a steady software effect running into the poweroff
|
|
furyrs anim "${ANIMS[0]}"
|
|
|
|
# Only warning-and-up: the dev_dbg per-transfer traffic is not an anomaly.
|
|
WARNS="$(journalctl -k -p warning --since "$START" --no-pager 2>/dev/null | grep -i 'i2c-imc' || true)"
|
|
N="$(printf '%s' "$WARNS" | grep -c . || true)"
|
|
|
|
{
|
|
echo "start: ${START}"
|
|
echo "end: $(date '+%Y-%m-%d %H:%M:%S')"
|
|
echo "use_ecam: ${MODE}"
|
|
echo "srcversion: ${SRCV}"
|
|
echo "blocks: ${BLOCKS}"
|
|
echo "spd_ok: $((1 - SPD_BAD))"
|
|
echo "spd_serials_ref:"
|
|
echo "$REF_SERIALS"
|
|
echo "driver_warnings: ${N}"
|
|
[ "$N" -gt 0 ] && echo "$WARNS"
|
|
} >"$RUNFILE"
|
|
|
|
echo "$(date '+%Y-%m-%d %H:%M') use_ecam=${MODE} srcversion=${SRCV} blocks=${BLOCKS} warns=${N} spd_ok=$((1 - SPD_BAD))" >>"$LOG"
|
|
[ -n "${SUDO_UID:-}" ] && chown "$SUDO_UID:${SUDO_GID:-$SUDO_UID}" "$RUNFILE" "$LOG" "$RUNDIR"
|
|
sync
|
|
|
|
if [ "$SPD_BAD" -ne 0 ]; then
|
|
echo "== SPD integrity FAILED - observations in ${RUNFILE} - NOT powering off."
|
|
exit 1
|
|
fi
|
|
if [ "$N" -gt 0 ]; then
|
|
echo "== ${N} driver warning(s) - SIGNAL, saved in ${RUNFILE}:"
|
|
echo "$WARNS"
|
|
else
|
|
echo "== clean run, no driver warnings."
|
|
fi
|
|
|
|
if [ "$POWEROFF" -eq 1 ]; then
|
|
echo "== powering off in 15 s (Ctrl-C to abort) ..."
|
|
sleep 15
|
|
systemctl poweroff
|
|
else
|
|
echo "== done, NOT powering off (pass --poweroff to shut down at the end)."
|
|
fi
|