Commit 06352a90 by PLN (Algolia)

fix-ardour-rt: patch the readers too, or a correct rig reports itself broken

The four patches fixed both WRITERS of Ardour's scheduling policy. Nothing
touched the readers, and that is the half that bites after the fix lands:

  - `parvagues-protect --check` demands SCHED_FIFO of every target, so
    Ardour at prio 0 would read UNPROTECTED forever and check() would exit
    non-zero by design. Its exit code is what the gate, the Bridge and
    gig-up believe, so a green rig would have shown a red Ardour all night
    while burying the one signal worth having: is scsynth really covered?
  - `perf-audio` still printed "Set Ardour (PID …) to real-time priority
    80" and the same for every child, while deliberately doing neither.

check() now reads the target's own prio out of the TARGETS row, so prio 0
means "want the OOM shield, leave scheduling alone" and prints
`sched=SCHED_OTHER (oom shield only, by design)`. prio > 0 is untouched:
scsynth/90, sclang/85 and pipewire/95 are judged exactly as before.

Verified on copies of both root files, not on the originals:

  - all 8 patches apply, both files still bash -n clean
  - second --apply says "already applied" (the predicate had to name Ardour;
    perf-audio says "real-time priority 80" about aseqdump too, which this
    fix leaves alone, so the loose grep could never have been true)
  - verdict truth table 8/8, including the two rows that matter: a shielded
    Ardour on SCHED_OTHER is ok, and an UNSHIELDED one is still a fault
  - the patched check() run against the live processes prints
    `ok ardour[615285] oom_score_adj=-1000 sched=SCHED_OTHER (oom shield
    only, by design)` where the old one would have said UNPROTECTED, and
    still flags scsynth and sclang, which are genuinely uncovered right now

Same shape as this morning's preload bug, one file over: the emitter changed
and the checker did not, so the checker lied. It is worth saying once more
that it did not merely miss a fault — it invented one.
parent 9d41b501
......@@ -137,10 +137,54 @@ PERF_OLD_CHILD=' chrt -f -p 79 $child'
PERF_NEW_CHILD=' # NOT chrt, same reason as the parent above. 2026-09-24.
: # (was: chrt -f -p 79 $child)'
# The four patches above fix the two WRITERS. These fix the READERS, which is the
# half that bites later: after the writers change, anything still asserting the old
# truth reports a correct rig as broken. Found 2026-09-24 by reading check() before
# applying, the same morning the preload emitter and its checker disagreed the same
# way.
PROTECT_OLD_LOCAL=' local bad=0 found=0 name pid adj pids'
PROTECT_NEW_LOCAL=' local bad=0 found=0 name pid adj pids prio'
PROTECT_OLD_CHECK=' if [ "$adj" != "$OOM_TARGET" ] || [ "$S_POL" != "SCHED_FIFO" ]; then
echo "UNPROTECTED $name[$pid] oom_score_adj=$adj sched=${S_POL:-none} (want $OOM_TARGET / SCHED_FIFO)"
bad=1
else
echo "ok $name[$pid] oom_score_adj=$adj sched=$S_POL/${S_PRIO}"
fi'
PROTECT_NEW_CHECK=' # What "protected" MEANS depends on the target'"'"'s own prio. A prio of 0 is
# a deliberate OOM-shield-only target (Ardour, since 2026-09-24), so
# demanding SCHED_FIFO of it would report UNPROTECTED forever about a
# CORRECT rig - and this function'"'"'s exit code is what the gate, the Bridge
# and gig-up believe. A checker that cannot read what the sweep writes is
# worse than no checker: it does not merely miss a fault, it invents one.
prio="${t#*:}"; prio="${prio%%:*}"
if [ "$adj" != "$OOM_TARGET" ] \
|| { [ "${prio:-0}" -gt 0 ] && [ "$S_POL" != "SCHED_FIFO" ]; }; then
if [ "${prio:-0}" -gt 0 ]; then
echo "UNPROTECTED $name[$pid] oom_score_adj=$adj sched=${S_POL:-none} (want $OOM_TARGET / SCHED_FIFO)"
else
echo "UNPROTECTED $name[$pid] oom_score_adj=$adj (want $OOM_TARGET; scheduling deliberately left alone)"
fi
bad=1
elif [ "${prio:-0}" -eq 0 ]; then
echo "ok $name[$pid] oom_score_adj=$adj sched=${S_POL:-OTHER} (oom shield only, by design)"
else
echo "ok $name[$pid] oom_score_adj=$adj sched=$S_POL/${S_PRIO}"
fi'
PERF_OLD_ECHO_MAIN=' echo "✓ Set Ardour (PID $ARDOUR) to real-time priority 80"'
PERF_NEW_ECHO_MAIN=' echo "✓ Shielded Ardour (PID $ARDOUR): oom -1000, ionice rt, memlock - NO realtime promotion, by design (2026-09-24)"'
PERF_OLD_ECHO_CHILD=' echo " ✓ Set Ardour child (PID $child) to priority 79"'
PERF_NEW_ECHO_CHILD=' echo " ✓ Shielded Ardour child (PID $child): ionice rt, no realtime promotion"'
# ------------------------------------------------------------------ helpers ----
applied_already() {
grep -qF '"ardour:0:' "$PROTECT" 2>/dev/null \
&& ! grep -qE '^\s*chrt -f -p 80 \$ARDOUR\s*$' "$PERFAUD" 2>/dev/null
&& ! grep -qE '^\s*chrt -f -p 80 \$ARDOUR\s*$' "$PERFAUD" 2>/dev/null \
&& grep -qF 'oom shield only, by design' "$PROTECT" 2>/dev/null \
&& ! grep -qF 'Set Ardour (PID $ARDOUR) to real-time priority 80' "$PERFAUD" 2>/dev/null
}
# patch_file FILE then pairs of OLD NEW on stdin-free args
......@@ -211,10 +255,14 @@ fi
echo " $PROTECT"
patch_one "$PROTECT" "$PROTECT_OLD_GUARD" "$PROTECT_NEW_GUARD" "prio-0 guard" || exit 1
patch_one "$PROTECT" "$PROTECT_OLD_TARGET" "$PROTECT_NEW_TARGET" "ardour 80 -> 0" || exit 1
patch_one "$PROTECT" "$PROTECT_OLD_LOCAL" "$PROTECT_NEW_LOCAL" "check(): declare prio" || exit 1
patch_one "$PROTECT" "$PROTECT_OLD_CHECK" "$PROTECT_NEW_CHECK" "check(): prio 0 wants no FIFO" || exit 1
echo
echo " $PERFAUD"
patch_one "$PERFAUD" "$PERF_OLD_MAIN" "$PERF_NEW_MAIN" "ardour chrt 80" || exit 1
patch_one "$PERFAUD" "$PERF_OLD_CHILD" "$PERF_NEW_CHILD" "ardour children chrt 79" || exit 1
patch_one "$PERFAUD" "$PERF_OLD_ECHO_MAIN" "$PERF_NEW_ECHO_MAIN" "stop claiming FIFO/80" || exit 1
patch_one "$PERFAUD" "$PERF_OLD_ECHO_CHILD" "$PERF_NEW_ECHO_CHILD" "stop claiming FIFO/79" || exit 1
echo
if [ "$MODE" = dry ]; then
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment