Skip to content

Commit d1bef09

Browse files
ShadowCursebchalios
andcommitted
feat(net): use readv for reading frames from TAP device
Right now, we are performing two copies for writing a frame from the TAP device into guest memory: - read the frame into an internal array held by the Net device - copy that array into a buffers of a DescriptorChain. In order to avoid this double copy we can use the readv system call to read directly from the TAP device into the buffers described by DescriptorChain. The main challenge with this is that DescriptorChain objects describe memory that is at least 65562 bytes long when guest TSO4, TSO6 or UFO are enabled or 1526 otherwise and parsing the chain includes overhead which we pay even if the frame we are receiving is much smaller than these sizes. PR #4748 reduced the overheads involved with parsing DescriptorChain objects. To further avoid this overhead, move the parsing of DescriptorChain objects out of the hot path of process_rx() where we are actually receiving a frame into process_rx_queue_event() where we get the notification that the guest added new buffers for network RX. Co-authored-by: Babis Chalios <[email protected]> Signed-off-by: Egor Lazarchuk <[email protected]>
1 parent 1f95ca8 commit d1bef09

File tree

10 files changed

+596
-211
lines changed

10 files changed

+596
-211
lines changed

resources/seccomp/aarch64-unknown-linux-musl.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
"syscall": "writev",
3333
"comment": "Used by the VirtIO net device to write to tap"
3434
},
35+
{
36+
"syscall": "readv",
37+
"comment": "Used by the VirtIO net device to read from tap"
38+
},
3539
{
3640
"syscall": "fsync"
3741
},

resources/seccomp/x86_64-unknown-linux-musl.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
"syscall": "writev",
3333
"comment": "Used by the VirtIO net device to write to tap"
3434
},
35+
{
36+
"syscall": "readv",
37+
"comment": "Used by the VirtIO net device to read from tap"
38+
},
3539
{
3640
"syscall": "fsync"
3741
},

src/vmm/benches/queue.rs

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,50 +10,9 @@ use std::num::Wrapping;
1010

1111
use criterion::{criterion_group, criterion_main, Criterion};
1212
use vm_memory::GuestAddress;
13-
use vmm::devices::virtio::queue::{VIRTQ_DESC_F_NEXT, VIRTQ_DESC_F_WRITE};
14-
use vmm::devices::virtio::test_utils::VirtQueue;
13+
use vmm::devices::virtio::test_utils::{set_dtable_many_chains, set_dtable_one_chain, VirtQueue};
1514
use vmm::test_utils::single_region_mem;
1615

17-
/// Create one chain with n descriptors
18-
/// Descriptor buffers will leave at the offset of 2048 bytes
19-
/// to leave some room for queue objects.
20-
/// We don't really care about sizes of descriptors,
21-
/// so pick 1024.
22-
fn set_dtable_one_chain(rxq: &VirtQueue, n: usize) {
23-
let desc_size = 1024;
24-
for i in 0..n {
25-
rxq.dtable[i].set(
26-
(2048 + desc_size * i) as u64,
27-
desc_size as u32,
28-
VIRTQ_DESC_F_WRITE | VIRTQ_DESC_F_NEXT,
29-
(i + 1) as u16,
30-
);
31-
}
32-
rxq.dtable[n - 1].flags.set(VIRTQ_DESC_F_WRITE);
33-
rxq.dtable[n - 1].next.set(0);
34-
rxq.avail.ring[0].set(0);
35-
rxq.avail.idx.set(n as u16);
36-
}
37-
38-
/// Create n chains with 1 descriptors each
39-
/// Descriptor buffers will leave at the offset of 2048 bytes
40-
/// to leave some room for queue objects.
41-
/// We don't really care about sizes of descriptors,
42-
/// so pick 1024.
43-
fn set_dtable_many_chains(rxq: &VirtQueue, n: usize) {
44-
let desc_size = 1024;
45-
for i in 0..n {
46-
rxq.dtable[i].set(
47-
(2048 + desc_size * i) as u64,
48-
desc_size as u32,
49-
VIRTQ_DESC_F_WRITE,
50-
0,
51-
);
52-
rxq.avail.ring[i].set(i as u16);
53-
}
54-
rxq.avail.idx.set(n as u16);
55-
}
56-
5716
pub fn queue_benchmark(c: &mut Criterion) {
5817
let mem = single_region_mem(65562);
5918
let rxq = VirtQueue::new(GuestAddress(0), &mem, 256);

0 commit comments

Comments
 (0)