@@ -9,9 +9,10 @@ use std::sync::{Arc, Mutex};
9
9
10
10
use serde:: { Deserialize , Serialize } ;
11
11
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 } ;
14
14
use crate :: devices:: virtio:: device:: DeviceState ;
15
+ use crate :: devices:: virtio:: iovec:: ParsedDescriptorChain ;
15
16
use crate :: devices:: virtio:: persist:: { PersistError as VirtioStateError , VirtioDeviceState } ;
16
17
use crate :: devices:: virtio:: queue:: FIRECRACKER_MAX_QUEUE_SIZE ;
17
18
use crate :: devices:: virtio:: TYPE_NET ;
@@ -31,6 +32,23 @@ pub struct NetConfigSpaceState {
31
32
guest_mac : Option < MacAddr > ,
32
33
}
33
34
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
+
34
52
/// Information about the network device that are saved
35
53
/// at snapshot.
36
54
#[ derive( Debug , Clone , Serialize , Deserialize ) ]
@@ -43,6 +61,7 @@ pub struct NetState {
43
61
pub mmds_ns : Option < MmdsNetworkStackState > ,
44
62
config_space : NetConfigSpaceState ,
45
63
virtio_state : VirtioDeviceState ,
64
+ rx_buffers_state : RxBufferState ,
46
65
}
47
66
48
67
/// Auxiliary structure for creating a device when resuming from a snapshot.
@@ -85,6 +104,7 @@ impl Persist<'_> for Net {
85
104
guest_mac : self . guest_mac ,
86
105
} ,
87
106
virtio_state : VirtioDeviceState :: from_device ( self ) ,
107
+ rx_buffers_state : RxBufferState :: from_rx_buffers ( & self . rx_buffer ) ,
88
108
}
89
109
}
90
110
@@ -137,6 +157,14 @@ impl Persist<'_> for Net {
137
157
. map_err ( NetPersistError :: TapSetOffload ) ?;
138
158
139
159
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 ) ;
140
168
}
141
169
142
170
Ok ( net)
0 commit comments