Add tcp latency test over virtio-net

This commit is contained in:
jiangjianfeng
2024-10-12 02:09:58 +00:00
committed by Tate, Hongliang Tian
parent e78303b01a
commit 090149eed7
14 changed files with 102 additions and 9 deletions

View File

@ -154,7 +154,7 @@ impl NetworkDevice {
.rx_buffers
.remove(token as usize)
.ok_or(VirtioNetError::WrongToken)?;
rx_buffer.set_packet_len(len as usize);
rx_buffer.set_packet_len(len as usize - size_of::<VirtioNetHdr>());
// FIXME: Ideally, we can reuse the returned buffer without creating new buffer.
// But this requires locking device to be compatible with smoltcp interface.
let rx_pool = RX_BUFFER_POOL.get().unwrap();
@ -180,6 +180,8 @@ impl NetworkDevice {
self.send_queue.notify();
}
debug!("send packet, token = {}, len = {}", token, packet.len());
debug_assert!(self.tx_buffers[token as usize].is_none());
self.tx_buffers[token as usize] = Some(tx_buffer);

View File

@ -7,6 +7,7 @@ mod unbound;
pub use bound::{BoundTcpSocket, BoundUdpSocket};
pub(crate) use bound::{BoundTcpSocketInner, BoundUdpSocketInner, TcpProcessResult};
pub use event::SocketEventObserver;
pub use smoltcp::socket::tcp::State as TcpState;
pub use unbound::{
UnboundTcpSocket, UnboundUdpSocket, TCP_RECV_BUF_LEN, TCP_SEND_BUF_LEN, UDP_RECV_PAYLOAD_LEN,
UDP_SEND_PAYLOAD_LEN,

View File

@ -4,7 +4,7 @@ use alloc::sync::Weak;
use aster_bigtcp::{
errors::tcp::{RecvError, SendError},
socket::SocketEventObserver,
socket::{SocketEventObserver, TcpState},
wire::IpEndpoint,
};
@ -68,6 +68,9 @@ impl ConnectedStream {
Ok(Err(e)) => Err(e),
Err(RecvError::Finished) => Ok(0),
Err(RecvError::InvalidState) => {
if self.before_established() {
return_errno_with_message!(Errno::EAGAIN, "the connection is not established");
}
return_errno_with_message!(Errno::ECONNRESET, "the connection is reset")
}
}
@ -86,6 +89,9 @@ impl ConnectedStream {
Ok(Ok(sent_bytes)) => Ok(sent_bytes),
Ok(Err(e)) => Err(e),
Err(SendError::InvalidState) => {
if self.before_established() {
return_errno_with_message!(Errno::EAGAIN, "the connection is not established");
}
// FIXME: `EPIPE` is another possibility, which means that the socket is shut down
// for writing. In that case, we should also trigger a `SIGPIPE` if `MSG_NOSIGNAL`
// is not specified.
@ -135,4 +141,20 @@ impl ConnectedStream {
pub(super) fn set_observer(&self, observer: Weak<dyn SocketEventObserver>) {
self.bound_socket.set_observer(observer)
}
/// Returns whether the connection is before established.
///
/// Note that a newly accepted socket may not yet be in the [`TcpState::Established`] state.
/// The accept syscall only verifies that a connection request is incoming by ensuring
/// that the backlog socket is not in the [`TcpState::Listen`] state.
/// However, the socket might still be waiting for further ACKs to complete the establishment process.
/// Therefore, it could be in either the [`TcpState::SynSent`] or [`TcpState::SynReceived`] states.
/// We must wait until the socket reaches the established state before it can send and receive data.
///
/// FIXME: Should we check established state in accept or here?
fn before_established(&self) -> bool {
self.bound_socket.raw_with(|socket| {
socket.state() == TcpState::SynSent || socket.state() == TcpState::SynReceived
})
}
}

View File

@ -265,13 +265,18 @@ impl StreamSocket {
return_errno_with_message!(Errno::EINVAL, "the socket is not listening");
};
listen_stream.try_accept().map(|connected_stream| {
let accepted = listen_stream.try_accept().map(|connected_stream| {
listen_stream.update_io_events(&self.pollee);
let remote_endpoint = connected_stream.remote_endpoint();
let accepted_socket = Self::new_connected(connected_stream);
(accepted_socket as _, remote_endpoint.into())
})
});
drop(state);
poll_ifaces();
accepted
}
fn try_recv(