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
41 changes: 36 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ members = [
"lib/ieee80211",
"lib/input",
"lib/inspect",
"lib/link",
"lib/logkeeper-api",
"lib/logstream",
"lib/manifest",
Expand Down Expand Up @@ -101,13 +102,14 @@ members = [
"system/fileserver",
"system/grants",
"system/host",
"system/i219",
"system/i219/driver",
"system/inspect",
"system/logkeeper",
"system/logout",
"system/netstack",
"system/netstack/dhcp",
"system/netstack/dns",
"system/netstack/i219",
"system/netstack/ip",
"system/netstack/mdns",
"system/netstack/node",
Expand Down Expand Up @@ -144,6 +146,7 @@ members = [
"system/usbd/xhci",
"system/vdagent",
"system/vdagent/bridge",
"system/virtio-net",
"tests/guest/hangupholder",
"tests/guest/inputsink",
"tests/guest/kernelprobe",
Expand Down
1 change: 1 addition & 0 deletions build/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3257,6 +3257,7 @@ mod tests {
"tests/images/launchcase.toml",
"tests/images/floorcase.toml",
"tests/images/libccase.toml",
"tests/images/linkcase.toml",
"tests/images/sessioncase.toml",
"tests/images/metalcase.toml",
"tests/images/metaldevicecase.toml",
Expand Down
3 changes: 3 additions & 0 deletions build/ci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ const KERNEL_SIM: &str = "kernel-sim";
/// The kernel's models, which [`Part::Models`] tests beside their controls.
const MODELS: [&str; 2] = [KERNEL_LOOM, KERNEL_SIM];
const BLOCKRING: &str = "toyos-blockring";
const LINK: &str = "toyos-link";
const PROCLIFE: &str = "toyos-proclife";
/// The SDK package, whose `transport` module carries its own controls.
const SDK: &str = "toyos";
Expand Down Expand Up @@ -752,6 +753,8 @@ pub(crate) const CONTROLS: &[Control] = &[
red(BLOCKRING, "mutate-no-reissue-after-loss", None, &[
Fails("model::tests::what_a_flush_calls_durable_is_on_the_medium"),
]),
// The link's one: a full ring's want swapped `Relaxed`, a wake lost.
red(LINK, "mutate-want-relaxed", Some("ends_loom"), &[Fails("a_full_ring_is_never_left_asleep_on_room_it_has")]),
red(SDK, "transport-publish-relaxed", Some("transport_loom"), &[
Fails("a_published_entry_is_read_whole"),
Fails("a_published_byte_is_read_as_written"),
Expand Down
27 changes: 21 additions & 6 deletions images/system.toml
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,29 @@ drives = ["pci:04:03:*"]
receives = ["sound-output"]
syscap = ["rt"]

# netstack holds the NIC's PCI function and drives it: the virtqueues, the register
# window and the interrupt are its own, and the kernel keeps only the claim.
# Named by class, vendor and device rather than by slot, so one row finds the card
# wherever firmware put it.
# The network stack, over the link a NIC driver brings on `link`; it claims no
# device. It serves once the first driver says hello, and leaves a machine
# none says hello on within 30 s.
[programs.netstack]
service = true
serves = ["netstack"]
devices = ["pci:02:00:00/1af4:1041"]
serves = ["netstack", "link"]

# The NIC drivers: one process per function a row's parts match, by class,
# vendor and device rather than by slot, holding that function alone and
# bringing its link to netstack, which keeps every connection across a
# link's end. virtio's is started again when it ends other than by exit 0.
[programs.virtio-net]
drives = ["pci:02:00:00/1af4:1041"]
receives = ["link"]
restart = true

# The I219, the T14's onboard NIC, and the 82574, which QEMU's `e1000e` models.
# Not started again: its start resets the part, and over a ring a link change
# left it that reset is not known to be safe
# (`issues/no-machine-has-read-an-intel-nic-across-a-link-change.md`).
[programs.i219]
drives = ["pci:02:00:00/8086:15fc", "pci:02:00:00/8086:10d3"]
receives = ["link"]

# The shared clipboard with QEMU's host: one process per virtio-serial
# function the kernel does not drive (the kernel's console is `1af4:1043` too),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ opened: 2026-10-09

# A link that goes and returns inside one pass of the Intel driver is reported as no change

`toyos-i219`'s `begin_pass` (`system/netstack/i219/src/lib.rs`) reads the link only on
`toyos-i219`'s `begin_pass` (`system/i219/driver/src/lib.rs`) reads the link only on
a pass that acknowledged `LSC`, and answers `link_changed: self.link !=
before`: the state after the pass compared with the state before it. `LSC` is
one bit, so a link that went down and came back at the same speed and duplex
before one pass acknowledged it is read as the link it was, and the pass
answers no change. `Nic::begin_pass` (`system/netstack/src/i219.rs`) hands
netstack a link only where that is true, so `main`'s `link_up` stays true and
no pass tells the name's responder it had no link.
answers no change. The driver's pass writes the link's word only when the
link differs from the one it last said (`lib/link/src/driver.rs`), and
netstack tells the node only of a change in whether it is up
(`system/netstack/src/link.rs`), so no pass tells the name's responder it had
no link.

RFC 6762 §8 asks for probing and announcing whenever a responder "receives an indication of a network interface "Link Change"
event". The part gave that indication, the `LSC` cause, and the driver held
Expand Down
2 changes: 1 addition & 1 deletion issues/every-driver-is-still-in-the-kernel.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The owner's target is that `virtio` does not appear anywhere in the kernel. The
strongest check on it is not the driver files but the ABI: no syscall name may
carry a NIC, GPU or audio device operation. `rg '^pub const SYS_(NIC|GPU|AUDIO|HDA)_'
sdk/abi/src/syscall.rs` is the check, and it finds none: the three `SYS_NIC_*`
names went with the virtio NIC driver, which is `system/netstack/src/virtio_net.rs`
names went with the virtio NIC driver, which is `system/virtio-net/src/nic.rs`
now, the four `SYS_GPU_*` names with virtio-gpu's, which is the
compositor's (`system/compositor/virtio-gpu`), and `SYS_HDA_BIND` with the
kernel's HDA stub. The kernel's virtio code left is its console's, and it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ opened: 2026-09-23

# `EXTCNF_CTRL` bit 7 is read as manageability's MDIO ownership on a MAC where it gates the PHY's automatic configuration

`system/netstack/i219/src/regs.rs`'s `extcnf::MDIO_MNG_OWNERSHIP` names bit 7 of
`system/i219/driver/src/regs.rs`'s `extcnf::MDIO_MNG_OWNERSHIP` names bit 7 of
`EXTCNF_CTRL` after the 82574's §4.5.2, and `phy::Others`, the
`SoftwareFlagStoodBeside*` refusals and exit codes 73 to 75 read it that way on
the T14 too. The PCH's own datasheet (631120, rev 002, §8.2.4) calls bit 7
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ result (`ok`, `MISSING` or `unreachable`). At evidence commit
success or failure: it never reads out the ULP configuration it met, so a
clean probe cannot tell an armed hand-off from an unarmed one.

**Owner**: the I219 driver (`system/netstack/i219/`).
**Owner**: the I219 driver (`system/i219/driver/`).

**Exit**, in order:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ its control `transport-want-relaxed` of `toyos`.

**Exit**: a test on the fork's `toyos` branch in which a model that deadlocks
with a `loom::sync::Arc` live prints loom's `deadlock` message and its test
fails without an abort, and that stream model holds its state in loom's `Arc`.
fails without an abort, and that stream model and `lib/link/tests/ends_loom.rs`
hold their state in loom's `Arc`.
23 changes: 15 additions & 8 deletions issues/netstack-drives-one-card.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@ opened: 2026-10-12

# netstack drives one card

netstack opens the first of `CARDS` the supervisor endowed, and no other
(`system/netstack/src/main.rs`, `main`). It opens it behind `Card`, an enum
of its in-process drivers (`system/netstack/src/card.rs`). Its node is one
interface with one DHCP client (`system/netstack/node/src/lib.rs`). So a
machine with a wired and a wireless link uses only one of them. [ip] already
netstack opens the first link a NIC driver brings, and no other: a hello with
another address, or with that address while its link is alive, is refused
`OneLink` (`system/netstack/src/main.rs`'s loop).
Its node is one interface with one DHCP client, made with the first link's
address (`system/netstack/node/src/lib.rs`). So a machine with a wired and a
wireless link uses only one of them, whichever driver says hello first.

Because the node needs that address, netstack serves nothing before a
driver's hello: every client waits for it, and on a machine with no NIC
driver for 30 s (`LINK_BOUND`, `system/netstack/src/main.rs`), after which
netstack leaves and a client hears it gone. [ip] already
routes over several interfaces, the lower index winning a tie
(`system/netstack/ip/src/lib.rs`).

Expand All @@ -23,12 +29,13 @@ That reverses part of `issues/first-match-selection-that-remains.md`
dropped" and that "Neither is a defect today". Under ruling 3 a second NIC
dropped is this defect.

Owner: P5 of `issues/there-is-no-wifi.md`, after the LAN track's stage 3
moves the drivers out (`issues/the-lan-is-not-yet-production-grade.md`).
Owner: P5 of `issues/there-is-no-wifi.md`. The drivers are out: each is a
process of its own over a link (`toyos-link`).

**Exit**:
- one interface per link, each with its own DHCP client, lease and mDNS
responder, under one host name;
responder, under one host name, and a node that serves before any link,
so `LINK_BOUND` goes;
- links ranked wired before wireless, then by arrival;
- a guest with two virtio NICs in which the first's link is set off over
QMP, and traffic leaves on the second;
Expand Down
34 changes: 0 additions & 34 deletions issues/netstack-ends-for-the-boot-on-a-nic-it-cannot-drive-on.md

This file was deleted.

27 changes: 0 additions & 27 deletions issues/netstack-is-never-told-the-machine-stops.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ opened: 2026-10-12

# netstack's latency under a receive batch of more than 64 frames is unmeasured

`Node::receive` takes at most the card's ring in one batch (`Card::receive`,
`system/netstack/src/card.rs`): `toyos_i219::RX_RING - 1`, 999 frames, on the
I219, and the queue's 256 on virtio. Before pull request #861 it took 64. Every
`Node::receive` takes at most the link's receive ring in one batch, 256
frames whatever the driver (`toyos_link::layout::RX_DEPTH`,
`system/netstack/src/link.rs`). Before the drivers left netstack it took the
card's ring, 999 frames on the I219, and before pull request #861, 64. Every
frame of a batch reaches the stack under one `now`, read before the batch
(`system/netstack/src/main.rs`'s loop), and the deadlines that are due, the
transmit opportunity and the clients' answers run only after the batch's last
Expand Down
Loading