mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
virtio-devices: net: Report correct used length on TX and ctrl
The virtio spec says the used-ring length is bytes the device wrote to device writable descriptors. The net TX descriptors are device readable only (the device wrote nothing back) so the length needs to be 0. On the ctrl queue the number of bytes reported was wrongly the size of the status descriptor not the number of bytes written (the descriptor is permitted to be larger). Signed-off-by: Rob Bradford <rbradford@meta.com>
This commit is contained in:
@@ -174,12 +174,10 @@ impl CtrlQueue {
|
||||
.map_err(|e| Error::GuestMemory(GuestMemoryError::IOError(e)))?,
|
||||
)
|
||||
.map_err(Error::GuestMemory)?;
|
||||
// Per virtio spec 2.6.8, used_len is the number of bytes written
|
||||
// to device-writable descriptors. Only the status byte is written.
|
||||
let len = status_desc.len();
|
||||
|
||||
// Per the virtio spec the used length is bytes the device wrote
|
||||
// to device-writable descriptors; here just the 1-byte ack.
|
||||
queue
|
||||
.add_used(desc_chain.memory(), desc_chain.head_index(), len)
|
||||
.add_used(desc_chain.memory(), desc_chain.head_index(), 1)
|
||||
.map_err(Error::QueueAddUsed)?;
|
||||
|
||||
if !queue
|
||||
|
||||
@@ -97,7 +97,7 @@ impl TxVirtio {
|
||||
next_desc = desc_chain.next();
|
||||
}
|
||||
|
||||
let len = if iovecs.is_empty() {
|
||||
let bytes_sent = if iovecs.is_empty() {
|
||||
0
|
||||
} else {
|
||||
// SAFETY: FFI call with correct arguments
|
||||
@@ -129,7 +129,7 @@ impl TxVirtio {
|
||||
self.counter_bytes += Wrapping(result as u64 - vnet_hdr_len() as u64);
|
||||
self.counter_frames += Wrapping(1);
|
||||
|
||||
result as u32
|
||||
result as u64
|
||||
};
|
||||
|
||||
// For the sake of simplicity (similar to the RX rate limiting), we always
|
||||
@@ -137,11 +137,14 @@ impl TxVirtio {
|
||||
// limit, and simply stop processing oncoming `avail_desc` if any.
|
||||
if let Some(rate_limiter) = rate_limiter {
|
||||
rate_limit_reached = !rate_limiter.consume(1, TokenType::Ops)
|
||||
|| !rate_limiter.consume(len as u64, TokenType::Bytes);
|
||||
|| !rate_limiter.consume(bytes_sent, TokenType::Bytes);
|
||||
}
|
||||
|
||||
// TX descriptors are device-readable only; the device wrote
|
||||
// nothing back to guest memory, so per the virtio spec the used
|
||||
// length is 0.
|
||||
queue
|
||||
.add_used(desc_chain.memory(), desc_chain.head_index(), len)
|
||||
.add_used(desc_chain.memory(), desc_chain.head_index(), 0)
|
||||
.map_err(NetQueuePairError::QueueAddUsed)?;
|
||||
|
||||
if !queue
|
||||
|
||||
Reference in New Issue
Block a user