Skip to content

Commit d2d8dd6

Browse files
smoserslp
authored andcommitted
virtio/vsock: remove refused connections without waiting for the reaper
A host process connecting to a vsock port registered with krun_add_vsock_port2(..., listen=true) is accepted at the unix layer immediately, before the guest leg of the connection exists. If nothing in the guest listens on the port yet, the guest answers OP_RST within a few milliseconds. UnixProxy::release() returned ProxyRemoval::Deferred for that proxy, so it kept the accepted host socket alive until the reaper reclaimed it 5 s later. The host's read() blocked for that whole window before seeing EOF, even though the refusal was known almost immediately. Callers that probe for guest readiness therefore saw a cold start dominated by this one 5 s block, or by whatever per-probe timeout they had set. Deferred removal reserves a connection id the way TIME_WAIT does, which only makes sense once the connection existed. A proxy that never reached Connected has nothing in flight and is not registered with the muxer's epoll - that happens later, in update_peer_credit() - so drop it right away and let the host see EOF. Measured with the reproducer from the issue below, on libkrunfw 5.5.0, host kernel 6.18, x86_64 - time to the first successful round trip after VM start, by the caller's per-probe timeout: per-probe timeout before after none (block) 5338 ms 415 ms 2000 ms 2335 ms 398 ms 100 ms 435 ms 375 ms 10 ms 411 ms 379 ms Cold start no longer depends on the caller's probe deadline, and a caller that retries no longer accumulates proxies: 200 back-to-back refused connections retained 200 file descriptors for the reaper window before this change, and none after it. Warm round trips are unchanged at ~0.17 ms. Fixes: #684 Assisted-by: Claude Code: opus-5 Signed-off-by: Scott Moser <[email protected]> Signed-off-by: Sergio Lopez <[email protected]>
1 parent e77e9dc commit d2d8dd6

1 file changed

Lines changed: 9 additions & 1 deletion

File tree

  • src/devices/src/virtio/vsock

‎src/devices/src/virtio/vsock/unix.rs‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,15 @@ impl Proxy for UnixProxy {
534534
"release: id={}, tx_cnt={}, last_tx_cnt={}",
535535
self.id, self.tx_cnt, self.last_tx_cnt_sent
536536
);
537-
let remove_proxy = ProxyRemoval::Deferred;
537+
538+
// A connection that never reached Connected carries no data and is not
539+
// registered for polling yet, so there is nothing to reserve its id for.
540+
// Keeping it would leave the accepted host socket open, and its peer
541+
// blocked, until the reaper reclaims the proxy.
542+
let remove_proxy = match self.status {
543+
ProxyStatus::ReverseInit | ProxyStatus::Connecting => ProxyRemoval::Immediate,
544+
_ => ProxyRemoval::Deferred,
545+
};
538546

539547
ProxyUpdate {
540548
remove_proxy,

0 commit comments

Comments
 (0)