Skip to content

fix(virtio): implement stream credit accounting in UdsVsock - #543

Open
Lencerf wants to merge 1 commit into
google:mainfrom
Lencerf:fix/uds-vsock-credit
Open

Lencerf wants to merge 1 commit into
google:mainfrom
Lencerf:fix/uds-vsock-credit

Conversation

@Lencerf

@Lencerf Lencerf commented Nov 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implement Virtio v1.4 Sec 5.10.6.3 (Buffer Space Management) stream flow-control credit accounting in UdsVsock:

  • Peer credit tracking (tx_cnt, peer_buf_alloc, peer_fwd_cnt):
    • Track peer_buf_alloc and peer_fwd_cnt from incoming REQUEST, RESPONSE, RW, CREDIT_UPDATE, CREDIT_REQUEST, and SHUTDOWN headers.
    • Compute peer_free = peer_buf_alloc.saturating_sub((tx_cnt - peer_fwd_cnt).0), cap RX virtqueue RW payload reads to peer_free, and advance tx_cnt by each transmitted payload length.
    • Drive process_rx_data whenever incoming packets update peer credit so host-to-guest transfers stalled at peer_free == 0 immediately resume on edge-triggered mio sockets, while still observing host socket EOF when peer_free == 0.
  • CREDIT_REQUEST handling:
    • Respond to VsockOp::CREDIT_REQUEST with VsockOp::CREDIT_UPDATE carrying current fwd_cnt and buf_alloc (deferring until an RX descriptor is available if the RX virtqueue is temporarily empty, and replying with RST for unknown connections).
  • Unsolicited CREDIT_UPDATE on unidirectional guest TX:
    • Track last_fwd_cnt across outgoing packets and emit an unsolicited VsockOp::CREDIT_UPDATE once unacknowledged guest TX bytes reach half of buf_alloc, preventing unidirectional guest-to-host streams from stalling.

Testing

  • cargo +nightly fmt --check
  • cargo test -p alioth virtio::dev::vsock (13 unit tests in uds_vsock_test.rs, including new tests for CREDIT_REQUEST, RX peer_free flow control & resumption, unidirectional TX > buf_alloc / 96 KiB credit replenishment, and u32 counter wrap-around)
  • cargo clippy --all-targets -- -D warnings
  • cargo clippy --all-targets --target x86_64-unknown-linux-gnu -- -D warnings

Track per-connection stream buffer credit (`tx_cnt`, `fwd_cnt`,
`last_fwd_cnt`, `peer_buf_alloc`, and `peer_fwd_cnt`) per Virtio v1.4
Sec 5.10.6.3:

- Update peer credit from incoming `REQUEST`, `RESPONSE`, `RW`,
  `CREDIT_UPDATE`, `CREDIT_REQUEST`, and `SHUTDOWN` headers.
- Cap `RW` payload reads on the RX virtqueue to `peer_free` and resume
  stalled host-to-guest transfers when incoming packets replenish peer
  credit on edge-triggered UDS sockets, while still observing socket EOF
  when `peer_free` is zero.
- Answer `CREDIT_REQUEST` with `CREDIT_UPDATE` (or `RST` for unknown
  connections), deferring `CREDIT_UPDATE` if the RX queue has no
  available descriptors.
- Emit unsolicited `CREDIT_UPDATE` packets once unacknowledged guest TX
  bytes reach half of `buf_alloc` so unidirectional guest-to-host
  streams do not stall.

Signed-off-by: Changyuan Lyu <changyuanl@google.com>
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 42955384191

Coverage increased (+0.5%) to 44.151%

Details

  • Coverage increased (+0.5%) from the base build.
  • Patch coverage: 15 uncovered changes across 1 file (201 of 216 lines covered, 93.06%).
  • 2 coverage regressions across 1 file.

Uncovered Changes

File Changed Covered %
alioth/src/virtio/dev/vsock/uds_vsock.rs 216 201 93.06%

Coverage Regressions

2 previously-covered lines in 1 file lost coverage.

File Lines Losing Coverage Coverage
alioth/src/virtio/dev/vsock/uds_vsock.rs 2 82.85%

Coverage Stats

Coverage Status
Relevant Lines: 16608
Covered Lines: 7121
Line Coverage: 42.88%
Relevant Branches: 1788
Covered Branches: 1001
Branch Coverage: 55.98%
Branches in Coverage %: Yes
Coverage Strength: 924.9 hits per line

💛 - Coveralls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants