Skip to content

Commit feb4bc1

Browse files
committed
fix: use temporary buffer for loading vmstate file
In commit e7504ae ("refactor: cleanup vmm::snapshot module"), firecracker started reading the snapshot vmstate file in a single pass instead of first loading it into a Vec and then deserializing. This seems to have caused some performance regression due to the deserializer doing many successive reads, resulting in many read(2) syscalls. Fix this by going back to first reading the snapshot file into a buffer, and then deserializing from slice instead. Signed-off-by: Patrick Roy <[email protected]>
1 parent 57ea0a3 commit feb4bc1

File tree

19 files changed

+117
-46
lines changed

19 files changed

+117
-46
lines changed

src/vmm/src/arch/aarch64/regs.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,9 @@ mod tests {
547547
let mut buf = vec![0; 10000];
548548

549549
Snapshot::new(&v).save(&mut buf.as_mut_slice()).unwrap();
550-
let restored: Aarch64RegisterVec = Snapshot::load(&mut buf.as_slice()).unwrap().data;
550+
let restored: Aarch64RegisterVec = Snapshot::load_without_crc_check(buf.as_slice())
551+
.unwrap()
552+
.data;
551553

552554
for (old, new) in v.iter().zip(restored.iter()) {
553555
assert_eq!(old, new);
@@ -576,7 +578,7 @@ mod tests {
576578

577579
// Total size of registers according IDs are 16 + 16 = 32,
578580
// but actual data size is 8 + 16 = 24.
579-
Snapshot::<Aarch64RegisterVec>::load(&mut buf.as_slice()).unwrap_err();
581+
Snapshot::<Aarch64RegisterVec>::load_without_crc_check(buf.as_slice()).unwrap_err();
580582
}
581583

582584
#[test]
@@ -598,7 +600,7 @@ mod tests {
598600
Snapshot::new(v).save(&mut buf.as_mut_slice()).unwrap();
599601

600602
// 4096 bit wide registers are not supported.
601-
Snapshot::<Aarch64RegisterVec>::load(&mut buf.as_slice()).unwrap_err();
603+
Snapshot::<Aarch64RegisterVec>::load_without_crc_check(buf.as_slice()).unwrap_err();
602604
}
603605

604606
#[test]

src/vmm/src/arch/x86_64/vm.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,9 @@ mod tests {
321321
Snapshot::new(state)
322322
.save(&mut snapshot_data.as_mut_slice())
323323
.unwrap();
324-
let restored_state: VmState = Snapshot::load(&mut snapshot_data.as_slice()).unwrap().data;
324+
let restored_state: VmState = Snapshot::load_without_crc_check(snapshot_data.as_slice())
325+
.unwrap()
326+
.data;
325327

326328
vm.restore_state(&restored_state).unwrap();
327329
}

src/vmm/src/device_manager/pci_mngr.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,9 @@ mod tests {
659659
// object and calling default_vmm() is the easiest way to create one.
660660
let vmm = default_vmm();
661661
let device_manager_state: device_manager::DevicesState =
662-
Snapshot::load(&mut buf.as_slice()).unwrap().data;
662+
Snapshot::load_without_crc_check(buf.as_slice())
663+
.unwrap()
664+
.data;
663665
let vm_resources = &mut VmResources::default();
664666
let restore_args = PciDevicesConstructorArgs {
665667
vm: vmm.vm.clone(),

src/vmm/src/device_manager/persist.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,9 @@ mod tests {
680680
let mut event_manager = EventManager::new().expect("Unable to create EventManager");
681681
let vmm = default_vmm();
682682
let device_manager_state: device_manager::DevicesState =
683-
Snapshot::load(&mut buf.as_slice()).unwrap().data;
683+
Snapshot::load_without_crc_check(buf.as_slice())
684+
.unwrap()
685+
.data;
684686
let vm_resources = &mut VmResources::default();
685687
let restore_args = MMIODevManagerConstructorArgs {
686688
mem: vmm.vm.guest_memory(),

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@ mod tests {
196196
mem: guest_mem,
197197
restored_from_file: true,
198198
},
199-
&Snapshot::load(&mut mem.as_slice()).unwrap().data,
199+
&Snapshot::load_without_crc_check(mem.as_slice())
200+
.unwrap()
201+
.data,
200202
)
201203
.unwrap();
202204

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,9 @@ mod tests {
223223
// Restore the block device.
224224
let restored_block = VirtioBlock::restore(
225225
BlockConstructorArgs { mem: guest_mem },
226-
&Snapshot::load(&mut mem.as_slice()).unwrap().data,
226+
&Snapshot::load_without_crc_check(mem.as_slice())
227+
.unwrap()
228+
.data,
227229
)
228230
.unwrap();
229231

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,9 @@ mod tests {
175175
mem: guest_mem,
176176
mmds: mmds_ds,
177177
},
178-
&Snapshot::load(&mut mem.as_slice()).unwrap().data,
178+
&Snapshot::load_without_crc_check(mem.as_slice())
179+
.unwrap()
180+
.data,
179181
) {
180182
Ok(restored_net) => {
181183
// Test that virtio specific fields are the same.

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

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,13 @@ mod tests {
366366
mem,
367367
is_activated: true,
368368
};
369-
let restored_queue =
370-
Queue::restore(ca, &Snapshot::load(&mut bytes.as_slice()).unwrap().data).unwrap();
369+
let restored_queue = Queue::restore(
370+
ca,
371+
&Snapshot::load_without_crc_check(bytes.as_slice())
372+
.unwrap()
373+
.data,
374+
)
375+
.unwrap();
371376

372377
assert_eq!(restored_queue, queue);
373378
}
@@ -380,7 +385,9 @@ mod tests {
380385
let state = VirtioDeviceState::from_device(&dummy);
381386
Snapshot::new(&state).save(&mut mem.as_mut_slice()).unwrap();
382387

383-
let restored_state: VirtioDeviceState = Snapshot::load(&mut mem.as_slice()).unwrap().data;
388+
let restored_state: VirtioDeviceState = Snapshot::load_without_crc_check(mem.as_slice())
389+
.unwrap()
390+
.data;
384391
assert_eq!(restored_state, state);
385392
}
386393

@@ -419,7 +426,9 @@ mod tests {
419426
};
420427
let restored_mmio_transport = MmioTransport::restore(
421428
restore_args,
422-
&Snapshot::load(&mut buf.as_slice()).unwrap().data,
429+
&Snapshot::load_without_crc_check(buf.as_slice())
430+
.unwrap()
431+
.data,
423432
)
424433
.unwrap();
425434

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ mod tests {
9292
let guest_mem = create_virtio_mem();
9393
let restored = Entropy::restore(
9494
EntropyConstructorArgs { mem: guest_mem },
95-
&Snapshot::load(&mut mem.as_slice()).unwrap().data,
95+
&Snapshot::load_without_crc_check(mem.as_slice())
96+
.unwrap()
97+
.data,
9698
)
9799
.unwrap();
98100

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,9 @@ pub(crate) mod tests {
180180

181181
Snapshot::new(&state).save(&mut mem.as_mut_slice()).unwrap();
182182

183-
let restored_state: VsockState = Snapshot::load(&mut mem.as_slice()).unwrap().data;
183+
let restored_state: VsockState = Snapshot::load_without_crc_check(mem.as_slice())
184+
.unwrap()
185+
.data;
184186
let mut restored_device = Vsock::restore(
185187
VsockConstructorArgs {
186188
mem: ctx.mem.clone(),

0 commit comments

Comments
 (0)