Skip to content

Commit dd0771f

Browse files
authored
Merge pull request #1693 from Gelbpunkt/num_buffers_1
perf(virtio-net): Don't copy packets when num_buffers is 1
2 parents 3798d21 + bffc6a0 commit dd0771f

File tree

4 files changed

+28
-25
lines changed

4 files changed

+28
-25
lines changed

src/drivers/net/gem.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ impl NetworkDriver for GEMDriver {
340340
};
341341
trace!("BUFFER: {buffer:x?}");
342342
self.rx_buffer_consumed(index as usize);
343-
Some((RxToken::new(buffer.to_vec()), TxToken::new()))
343+
Some((RxToken::new(buffer.to_vec_in(DeviceAlloc)), TxToken::new()))
344344
}
345345
None => None,
346346
}

src/drivers/net/rtl8139.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#![allow(dead_code)]
44

55
use alloc::boxed::Box;
6+
use alloc::vec::Vec;
67
use core::mem;
78

89
use memory_addresses::VirtAddr;
@@ -17,6 +18,7 @@ use crate::drivers::error::DriverError;
1718
use crate::drivers::net::NetworkDriver;
1819
use crate::drivers::pci::PciDevice;
1920
use crate::executor::device::{RxToken, TxToken};
21+
use crate::mm::device_alloc::DeviceAlloc;
2022

2123
/// size of the receive buffer
2224
const RX_BUF_LEN: usize = 8192;
@@ -287,14 +289,18 @@ impl NetworkDriver for RTL8139Driver {
287289
let length = self.rx_peek_u16() - 4; // copy packet (but not the CRC)
288290
let pos = (self.rxpos + mem::size_of::<u16>()) % RX_BUF_LEN;
289291

292+
let mut vec_data = Vec::with_capacity_in(length as usize, DeviceAlloc);
293+
290294
// do we reach the end of the receive buffers?
291295
// in this case, we contact the two slices to one vec
292-
let vec_data = if pos + length as usize > RX_BUF_LEN {
296+
if pos + length as usize > RX_BUF_LEN {
293297
let first = &self.rxbuffer[pos..RX_BUF_LEN];
294298
let second = &self.rxbuffer[..length as usize - first.len()];
295-
[first, second].concat()
299+
300+
vec_data.extend_from_slice(first);
301+
vec_data.extend_from_slice(second);
296302
} else {
297-
(self.rxbuffer[pos..][..length.into()]).to_vec()
303+
vec_data.extend_from_slice(&self.rxbuffer[pos..][..length.into()]);
298304
};
299305

300306
self.consume_current_buffer();

src/drivers/net/virtio/mod.rs

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -305,13 +305,17 @@ impl NetworkDriver for VirtioNetDriver {
305305
}
306306

307307
fn receive_packet(&mut self) -> Option<(RxToken, TxToken)> {
308-
let mut buffer_tkn = self.recv_vqs.get_next()?;
309-
RxQueues::post_processing(&mut buffer_tkn)
310-
.inspect_err(|vnet_err| warn!("Post processing failed. Err: {vnet_err:?}"))
311-
.ok()?;
312-
let first_header = buffer_tkn.used_recv_buff.pop_front_downcast::<Hdr>()?;
313-
let first_packet = buffer_tkn.used_recv_buff.pop_front_vec()?;
314-
trace!("Header: {first_header:?}");
308+
let mut receive_single_packet = || {
309+
let mut buffer_tkn = self.recv_vqs.get_next()?;
310+
RxQueues::post_processing(&mut buffer_tkn)
311+
.inspect_err(|vnet_err| warn!("Post processing failed. Err: {vnet_err:?}"))
312+
.ok()?;
313+
let header = buffer_tkn.used_recv_buff.pop_front_downcast::<Hdr>()?;
314+
let packet = buffer_tkn.used_recv_buff.pop_front_vec()?;
315+
Some((header, packet))
316+
};
317+
318+
let (first_header, first_packet) = receive_single_packet()?;
315319

316320
// According to VIRTIO spec v1.2 sec. 5.1.6.3.2, "num_buffers will always be 1 if VIRTIO_NET_F_MRG_RXBUF is not negotiated."
317321
// Unfortunately, NVIDIA MLX5 does not comply with this requirement and we have to manually set the value to the correct one.
@@ -321,17 +325,11 @@ impl NetworkDriver for VirtioNetDriver {
321325
1
322326
};
323327

324-
let mut packets = Vec::with_capacity(num_buffers.into());
325-
packets.push(first_packet);
328+
let mut combined_packets = first_packet;
326329

327330
for _ in 1..num_buffers {
328-
let mut buffer_tkn = self.recv_vqs.get_next().unwrap();
329-
RxQueues::post_processing(&mut buffer_tkn)
330-
.inspect_err(|vnet_err| warn!("Post processing failed. Err: {vnet_err:?}"))
331-
.ok()?;
332-
let _header = buffer_tkn.used_recv_buff.pop_front_downcast::<Hdr>()?;
333-
let packet = buffer_tkn.used_recv_buff.pop_front_vec()?;
334-
packets.push(packet);
331+
let (_header, packet) = receive_single_packet()?;
332+
combined_packets.extend_from_slice(&packet);
335333
}
336334

337335
fill_queue(
@@ -340,9 +338,7 @@ impl NetworkDriver for VirtioNetDriver {
340338
self.recv_vqs.packet_size,
341339
);
342340

343-
let vec_data = packets.into_iter().flatten().collect();
344-
345-
Some((RxToken::new(vec_data), TxToken::new()))
341+
Some((RxToken::new(combined_packets), TxToken::new()))
346342
}
347343

348344
fn set_polling_mode(&mut self, value: bool) {

src/executor/device.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use crate::arch::kernel::mmio as hardware;
2323
use crate::drivers::net::NetworkDriver;
2424
#[cfg(feature = "pci")]
2525
use crate::drivers::pci as hardware;
26+
use crate::mm::device_alloc::DeviceAlloc;
2627

2728
/// Data type to determine the mac address
2829
#[derive(Debug, Clone)]
@@ -220,11 +221,11 @@ pub(crate) type RxHandle = usize;
220221

221222
#[doc(hidden)]
222223
pub(crate) struct RxToken {
223-
buffer: Vec<u8>,
224+
buffer: Vec<u8, DeviceAlloc>,
224225
}
225226

226227
impl RxToken {
227-
pub(crate) fn new(buffer: Vec<u8>) -> Self {
228+
pub(crate) fn new(buffer: Vec<u8, DeviceAlloc>) -> Self {
228229
Self { buffer }
229230
}
230231
}

0 commit comments

Comments
 (0)