Skip to content

Commit 73e215b

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 a2d1c9e commit 73e215b

File tree

19 files changed

+114
-44
lines changed

19 files changed

+114
-44
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
@@ -681,7 +681,9 @@ mod tests {
681681
let mut event_manager = EventManager::new().expect("Unable to create EventManager");
682682
let vmm = default_vmm();
683683
let device_manager_state: device_manager::DevicesState =
684-
Snapshot::load(&mut buf.as_slice()).unwrap().data;
684+
Snapshot::load_without_crc_check(buf.as_slice())
685+
.unwrap()
686+
.data;
685687
let vm_resources = &mut VmResources::default();
686688
let restore_args = MMIODevManagerConstructorArgs {
687689
mem: vmm.vm.guest_memory(),

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ pub struct BalloonConfig {
8080
}
8181

8282
/// BalloonStats holds statistics returned from the stats_queue.
83-
#[derive(Clone, Default, Debug, PartialEq, Eq, Serialize)]
83+
#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, Serialize)]
8484
#[serde(deny_unknown_fields)]
8585
pub struct BalloonStats {
8686
/// The target size of the balloon, in 4K pages.

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

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

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

0 commit comments

Comments
 (0)