Skip to content

Commit 667aba4

Browse files
bchaliosShadowCurse
andcommitted
net: support serializing RxBuffer
Now, that we pre-process the buffers that guest provides for performing RX, we need to save them in the VM state snapshot file, for networking to work correctly post snapshot resume. Implement Persist for RxBuffers and and plug them in the (de)serialization logic of the network device. Co-authored-by: Egor Lazarchuk <[email protected]> Signed-off-by: Babis Chalios <[email protected]>
1 parent 5d718d4 commit 667aba4

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

src/vmm/src/devices/virtio/iovec.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use std::io::ErrorKind;
55

66
use libc::{c_void, iovec, size_t};
7+
use serde::{Deserialize, Serialize};
78
#[cfg(not(kani))]
89
use smallvec::SmallVec;
910
use vm_memory::bitmap::Bitmap;
@@ -218,7 +219,7 @@ impl IoVecBuffer {
218219
}
219220
}
220221

221-
#[derive(Debug)]
222+
#[derive(Debug, Clone, Serialize, Deserialize)]
222223
pub struct ParsedDescriptorChain {
223224
pub head_index: u16,
224225
pub length: u32,
@@ -233,9 +234,9 @@ pub struct ParsedDescriptorChain {
233234
#[derive(Debug)]
234235
pub struct IoVecBufferMut {
235236
// container of the memory regions included in this IO vector
236-
vecs: IovDeque,
237+
pub vecs: IovDeque,
237238
// Total length of the IoVecBufferMut
238-
len: usize,
239+
pub len: usize,
239240
}
240241

241242
impl IoVecBufferMut {

src/vmm/src/devices/virtio/net/persist.rs

+30-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ use std::sync::{Arc, Mutex};
99

1010
use serde::{Deserialize, Serialize};
1111

12-
use super::device::Net;
13-
use super::{TapError, NET_NUM_QUEUES};
12+
use super::device::{Net, RxBuffers};
13+
use super::{TapError, NET_NUM_QUEUES, RX_INDEX};
1414
use crate::devices::virtio::device::DeviceState;
15+
use crate::devices::virtio::iovec::ParsedDescriptorChain;
1516
use crate::devices::virtio::persist::{PersistError as VirtioStateError, VirtioDeviceState};
1617
use crate::devices::virtio::queue::FIRECRACKER_MAX_QUEUE_SIZE;
1718
use crate::devices::virtio::TYPE_NET;
@@ -31,6 +32,23 @@ pub struct NetConfigSpaceState {
3132
guest_mac: Option<MacAddr>,
3233
}
3334

35+
/// Information about the parsed RX buffers
36+
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
37+
pub struct RxBufferState {
38+
// Number of iovecs we have parsed from the guest
39+
parsed_descriptor_chains_nr: u16,
40+
deferred_descriptor: Option<ParsedDescriptorChain>,
41+
}
42+
43+
impl RxBufferState {
44+
fn from_rx_buffers(rx_buffer: &RxBuffers) -> Self {
45+
RxBufferState {
46+
parsed_descriptor_chains_nr: rx_buffer.parsed_descriptors.len().try_into().unwrap(),
47+
deferred_descriptor: rx_buffer.deferred_descriptor.clone(),
48+
}
49+
}
50+
}
51+
3452
/// Information about the network device that are saved
3553
/// at snapshot.
3654
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -43,6 +61,7 @@ pub struct NetState {
4361
pub mmds_ns: Option<MmdsNetworkStackState>,
4462
config_space: NetConfigSpaceState,
4563
virtio_state: VirtioDeviceState,
64+
rx_buffers_state: RxBufferState,
4665
}
4766

4867
/// Auxiliary structure for creating a device when resuming from a snapshot.
@@ -85,6 +104,7 @@ impl Persist<'_> for Net {
85104
guest_mac: self.guest_mac,
86105
},
87106
virtio_state: VirtioDeviceState::from_device(self),
107+
rx_buffers_state: RxBufferState::from_rx_buffers(&self.rx_buffer),
88108
}
89109
}
90110

@@ -137,6 +157,14 @@ impl Persist<'_> for Net {
137157
.map_err(NetPersistError::TapSetOffload)?;
138158

139159
net.device_state = DeviceState::Activated(constructor_args.mem);
160+
161+
// Recreate `Net::rx_buffer`. We do it by re-parsing the RX queue. We're temporarily
162+
// rolling back `next_avail` in the RX queue and call `parse_rx_descriptors`.
163+
net.queues[RX_INDEX].next_avail -= state.rx_buffers_state.parsed_descriptor_chains_nr;
164+
net.parse_rx_descriptors();
165+
net.rx_buffer
166+
.deferred_descriptor
167+
.clone_from(&state.rx_buffers_state.deferred_descriptor);
140168
}
141169

142170
Ok(net)

0 commit comments

Comments
 (0)