Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,32 @@ The stick's controller is no longer pinned per machine (the `@boot` place), so
which spare a row claims is decided at boot. Which bench a row runs on is still
not declared, and the harness has nothing to refuse it by.

The T14's `00:0d.0` [8086:9a13] is a spare under both boot layouts. Off the
stick, `00:14.0` is the boot controller. Off the NVMe (#1095), no xHCI is. The
AMD row claims the spare and its fault arm runs:
`iommu: DMA FAULT owner=process unit3 stream=00:0d.0 addr=0x0000000050200000`,
1 GiB past the grant at `0x10200000`. `klogd_hosted` then reds on
`must_be_clean`. The fault ran on each of PR #1074's four stick boots
(sessions 2–5), and `klogd_hosted` red on every one judged (sessions 2–4;
[sessions 2 and 3](https://github.com/ToyOSOrg/evidence/tree/b1c036144b4c8a39415cb60145a823d0c0d2d652/r3)).
The same happened on its NVMe landing boot (head 094323f29,
[evidence](https://github.com/ToyOSOrg/evidence/tree/3cb575aadca9e85f33b4c5690c7e1ea4ca15822f/r8)).

Four more rows red on that boot by this record's mechanism, because they are
AMD-bench rows judged against a T14 readback:
- `amdvi_usbd_drives_its_own_entry`: `test_rs_usbd_spare_vector` finds no
MSI-X on the T14's MSI-only xHCI;
- `idle_entered`: "this row runs on the AMD bench";
- `amdvi_translates_the_boot_controller` and
`amdvi_remaps_the_boot_controller`: no AMD-Vi unit is translating.

The boot's two other reds have records of their own:
`i219_messages_on_its_msi_vector` (`issues/i219-msi-passes-only-when-the-network-sends-it-a-frame.md`)
and `hda_tone` (`issues/the-t14-tone-underran-one-period-once-in-nine-boots.md`).

**Owner**: the metal harness (`tests/common/metal.rs`, and the row table in
`tests/toyos.rs`).

**Exit**: every metal row declares the machines it runs on, by the SMBIOS
identity the machine's record carries. A selection run on one bench takes no
row that is not declared for it, and says which rows it left out.
49 changes: 49 additions & 0 deletions issues/the-t14-tone-underran-one-period-once-in-nine-boots.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
status: open
kind: defect
opened: 2026-10-28
---

# The T14 tone underran one period once in nine boots

`hda_tone` reds when soundserver fills a period the tone client had not
covered (`tests/common/audio.rs`'s `tone_on_metal`). On one T14 `testcases`
boot it read `underruns=1 starve_max=1` in the stream's first 2 s stats
window (11.772–13.773 s of a stream that closed at 14.977 s): one isolated
period, somewhere in that window. The second window and `hda_tone_resampled`
in that boot read 0.

Distinct T14 boots judged for this row:
- 7 of PR #1074's branch. Four are stick boots of earlier revisions on older
mains, and three are NVMe boots. The NVMe three include the red one (head
094323f29) and the same image booted again 24 minutes later.
- 2 of main 370d7d9f6 alone, NVMe.

If both trees underran at one rate, the red would land on a branch boot 7
times in 9 (3 in 5 counting NVMe boots alone), so the counts attribute it to
neither.
([landing boot](https://github.com/ToyOSOrg/evidence/tree/3cb575aadca9e85f33b4c5690c7e1ea4ca15822f/r8),
[every boot's judgement](https://github.com/ToyOSOrg/evidence/tree/9d0ed9325f33f34ba7714fe68ca1261129c27f0a/r9))

There is no candidate cause. The samples cross a shared-memory ring.
soundserver counts an underrun only once a client is streaming, that is once
it has delivered (`ClientStream::is_streaming`). The one pipe on the path is
the signal bell, and after delivery `signal_clients` (`system/soundserver/src/mix.rs`)
rings it once per mix wake. It drops every error but `Gone`, and a bell
refused for memory would be dropped too. But neither tree can refuse that
write for memory in a stream this short:
- on main 370d7d9f6, a pipe holds its page from its first write;
- with #1074, a pipe that has held a byte needs another frame only when its
held bytes cross a frame's 4096 bytes (`kernel/pure/pipe.rs`'s `wants`, and
`consume` restarts a drained pipe at its frame's start). That takes about
4096 bells, and this stream rang at most about 1400 (one per mix wake,
871 + 515).

**Owner**: soundserver and the hda driver.

**Exit**: soundserver's underrun record names the period, how late the
client's fill was and how late the device's completion was. A recurrence
then names its cause, and the fix lands. The record does not close on a
count of clean boots. At the observed 1 in 9, 26 consecutive clean boots
are needed to exclude that rate with 95 % confidence, and about 300 to
bound it under 1 in 100.