diff --git a/src/devices/src/virtio/net/mod.rs b/src/devices/src/virtio/net/mod.rs index d3e7e9739..e0c51f3fd 100644 --- a/src/devices/src/virtio/net/mod.rs +++ b/src/devices/src/virtio/net/mod.rs @@ -19,16 +19,13 @@ mod unixgram; mod unixstream; mod worker; -fn vnet_hdr_len() -> usize { - mem::size_of::() -} +// https://docs.oasis-open.org/virtio/virtio/v1.1/csprd01/virtio-v1.1-csprd01.html#x1-2050006 +const VNET_HDR_LEN: usize = mem::size_of::(); // This initializes to all 0 the virtio_net_hdr part of a buf and return the length of the header -// https://docs.oasis-open.org/virtio/virtio/v1.1/csprd01/virtio-v1.1-csprd01.html#x1-2050006 fn write_virtio_net_hdr(buf: &mut [u8]) -> usize { - let len = vnet_hdr_len(); - buf[0..len].fill(0); - len + buf[0..VNET_HDR_LEN].fill(0); + VNET_HDR_LEN } pub use self::device::Net; diff --git a/src/devices/src/virtio/net/unixgram.rs b/src/devices/src/virtio/net/unixgram.rs index 04e230066..1ceb0722e 100644 --- a/src/devices/src/virtio/net/unixgram.rs +++ b/src/devices/src/virtio/net/unixgram.rs @@ -9,8 +9,22 @@ use std::path::PathBuf; use super::backend::{ConnectError, NetBackend, ReadError, WriteError}; use super::write_virtio_net_hdr; +#[cfg(target_os = "macos")] +use super::{MAX_BUFFER_SIZE, VNET_HDR_LEN}; const VFKIT_MAGIC: [u8; 4] = *b"VFKT"; +const DEFAULT_SOCKET_BUF_SIZE: usize = 7 * 1024 * 1024; + +// On macOS, with UNIX datagram sockets the send buffer is not used for queuing; +// it determines the maximum frame size. +// https://github.com/apple-oss-distributions/xnu/blob/f6217f891ac0bb64f3d375211650a4c1ff8ca1ea/bsd/kern/uipc_usrreq.c#L953 +#[cfg(target_os = "macos")] +const SOCKET_SNDBUF: usize = MAX_BUFFER_SIZE - VNET_HDR_LEN; + +#[cfg(not(target_os = "macos"))] +const SOCKET_SNDBUF: usize = DEFAULT_SOCKET_BUF_SIZE; + +const SOCKET_RCVBUF: usize = DEFAULT_SOCKET_BUF_SIZE; pub struct Unixgram { fd: OwnedFd, @@ -77,11 +91,11 @@ impl Unixgram { .map_err(ConnectError::SendingMagic)?; } - if let Err(e) = setsockopt(&fd, sockopt::SndBuf, &(7 * 1024 * 1024)) { - log::warn!("Failed to increase SO_SNDBUF (performance may be decreased): {e}"); + if let Err(e) = setsockopt(&fd, sockopt::SndBuf, &SOCKET_SNDBUF) { + log::warn!("Failed to set SO_SNDBUF: {e}"); } - if let Err(e) = setsockopt(&fd, sockopt::RcvBuf, &(7 * 1024 * 1024)) { - log::warn!("Failed to increase SO_SNDBUF (performance may be decreased): {e}"); + if let Err(e) = setsockopt(&fd, sockopt::RcvBuf, &SOCKET_RCVBUF) { + log::warn!("Failed to set SO_RCVBUF: {e}"); } log::debug!( diff --git a/src/devices/src/virtio/net/worker.rs b/src/devices/src/virtio/net/worker.rs index 222b781a0..05341df3c 100644 --- a/src/devices/src/virtio/net/worker.rs +++ b/src/devices/src/virtio/net/worker.rs @@ -8,7 +8,7 @@ use crate::virtio::{DeviceQueue, InterruptTransport}; use super::backend::{NetBackend, ReadError, WriteError}; use super::device::{FrontendError, RxError, TxError, VirtioNetBackend}; -use super::vnet_hdr_len; +use super::VNET_HDR_LEN; use std::os::fd::{AsRawFd, FromRawFd, OwnedFd}; use std::thread; @@ -202,7 +202,7 @@ impl NetWorker { pub(crate) fn process_backend_socket_writeable(&mut self) { match self .backend - .try_finish_write(vnet_hdr_len(), &self.tx_frame_buf[..self.tx_frame_len]) + .try_finish_write(VNET_HDR_LEN, &self.tx_frame_buf[..self.tx_frame_len]) { Ok(()) => self.process_tx_loop(), Err(WriteError::PartialWrite | WriteError::NothingWritten) => {} @@ -275,7 +275,7 @@ impl NetWorker { if self.backend.has_unfinished_write() && self .backend - .try_finish_write(vnet_hdr_len(), &self.tx_frame_buf[..self.tx_frame_len]) + .try_finish_write(VNET_HDR_LEN, &self.tx_frame_buf[..self.tx_frame_len]) .is_err() { log::trace!("Cannot process tx because of unfinished partial write!"); @@ -321,7 +321,7 @@ impl NetWorker { self.tx_frame_len = read_count; match self .backend - .write_frame(vnet_hdr_len(), &mut self.tx_frame_buf[..read_count]) + .write_frame(VNET_HDR_LEN, &mut self.tx_frame_buf[..read_count]) { Ok(()) => { self.tx_frame_len = 0;