Skip to content

Commit

Permalink
Merge branch 'firecracker-microvm:main' into allow-snapshot-tap-changes
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewla authored Jan 23, 2025
2 parents 232a604 + a2a3484 commit 40eb957
Show file tree
Hide file tree
Showing 9 changed files with 24 additions and 89 deletions.
6 changes: 0 additions & 6 deletions docs/hugepages.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
# Backing Guest Memory by Huge Pages

> [!WARNING]
>
> Support is currently in **developer preview**. See
> [this section](RELEASE_POLICY.md#developer-preview-features) for more info.
Firecracker supports backing the guest memory of a VM by 2MB hugetlbfs pages.
This can be enabled by setting the `huge_pages` field of `PUT` or `PATCH`
requests to the `/machine-config` endpoint to `2M`.
Expand Down Expand Up @@ -44,7 +39,6 @@ Currently, hugetlbfs support is mutually exclusive with the following
Firecracker features:

- Memory Ballooning via the [Balloon Device](./ballooning.md)
- Initrd

## FAQ

Expand Down
8 changes: 4 additions & 4 deletions src/vmm/src/devices/virtio/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -803,10 +803,11 @@ mod verification {
const GUEST_MEMORY_BASE: u64 = 512;

// We size our guest memory to fit a properly aligned queue, plus some wiggles bytes
// to make sure we not only test queues where all segments are consecutively aligned.
// to make sure we not only test queues where all segments are consecutively aligned (at least
// for those proofs that use a completely arbitrary queue structure).
// We need to give at least 16 bytes of buffer space for the descriptor table to be
// able to change its address, as it is 16-byte aligned.
const GUEST_MEMORY_SIZE: usize = QUEUE_END as usize + 30;
const GUEST_MEMORY_SIZE: usize = (QUEUE_END - QUEUE_BASE_ADDRESS) as usize + 30;

fn guest_memory(memory: *mut u8) -> ProofGuestMemory {
// Ideally, we'd want to do
Expand Down Expand Up @@ -876,8 +877,7 @@ mod verification {
const USED_RING_BASE_ADDRESS: u64 =
AVAIL_RING_BASE_ADDRESS + 6 + 2 * FIRECRACKER_MAX_QUEUE_SIZE as u64 + 2;

/// The address of the first byte after the queue. Since our queue starts at guest physical
/// address 0, this is also the size of the memory area occupied by the queue.
/// The address of the first byte after the queue (which starts at QUEUE_BASE_ADDRESS).
/// Note that the used ring structure has size 6 + 8 * FIRECRACKER_MAX_QUEUE_SIZE
const QUEUE_END: u64 = USED_RING_BASE_ADDRESS + 6 + 8 * FIRECRACKER_MAX_QUEUE_SIZE as u64;

Expand Down
19 changes: 1 addition & 18 deletions src/vmm/src/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};

use crate::cpu_config::templates::CustomCpuTemplate;
use crate::device_manager::persist::SharedDeviceType;
use crate::logger::{info, log_dev_preview_warning};
use crate::logger::info;
use crate::mmds;
use crate::mmds::data_store::{Mmds, MmdsVersion};
use crate::mmds::ns::MmdsNetworkStack;
Expand Down Expand Up @@ -246,10 +246,6 @@ impl VmResources {
&mut self,
update: &MachineConfigUpdate,
) -> Result<(), MachineConfigError> {
if update.huge_pages.is_some() && update.huge_pages != Some(HugePageConfig::None) {
log_dev_preview_warning("Huge pages support", None);
}

let updated = self.machine_config.update(update)?;

// The VM cannot have a memory size smaller than the target size
Expand All @@ -268,13 +264,6 @@ impl VmResources {
if self.balloon.get().is_some() && updated.huge_pages != HugePageConfig::None {
return Err(MachineConfigError::BalloonAndHugePages);
}

if self.boot_source.config.initrd_path.is_some()
&& updated.huge_pages != HugePageConfig::None
{
return Err(MachineConfigError::InitrdAndHugePages);
}

self.machine_config = updated;

Ok(())
Expand Down Expand Up @@ -341,12 +330,6 @@ impl VmResources {
&mut self,
boot_source_cfg: BootSourceConfig,
) -> Result<(), BootSourceConfigError> {
if boot_source_cfg.initrd_path.is_some()
&& self.machine_config.huge_pages != HugePageConfig::None
{
return Err(BootSourceConfigError::HugePagesAndInitRd);
}

self.boot_source = BootSource {
builder: Some(BootConfig::new(&boot_source_cfg)?),
config: boot_source_cfg,
Expand Down
2 changes: 0 additions & 2 deletions src/vmm/src/vmm_config/boot_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ pub enum BootSourceConfigError {
InvalidInitrdPath(io::Error),
/// The kernel command line is invalid: {0}
InvalidKernelCommandLine(String),
/// Firecracker's huge pages support is incompatible with initrds.
HugePagesAndInitRd,
}

/// Holds the kernel specification (both configuration as well as runtime details).
Expand Down
2 changes: 0 additions & 2 deletions src/vmm/src/vmm_config/machine_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ pub enum MachineConfigError {
KernelVersion,
/// Firecracker's huge pages support is incompatible with memory ballooning.
BalloonAndHugePages,
/// Firecracker's huge pages support is incompatible with initrds.
InitrdAndHugePages,
}

/// Describes the possible (huge)page configurations for a microVM's memory.
Expand Down
14 changes: 0 additions & 14 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,20 +498,6 @@ def uvm_plain_debug(microvm_factory, guest_kernel_6_1_debug, rootfs_rw):
return microvm_factory.build(guest_kernel_6_1_debug, rootfs_rw)


@pytest.fixture
def uvm_with_initrd(
microvm_factory, guest_kernel_linux_5_10, record_property, artifact_dir
):
"""
See file:../docs/initrd.md
"""
fs = artifact_dir / "initramfs.cpio"
record_property("rootfs", fs.name)
uvm = microvm_factory.build(guest_kernel_linux_5_10)
uvm.initrd_file = fs
yield uvm


@pytest.fixture
def vcpu_count():
"""Return default vcpu_count. Use indirect parametrization to override."""
Expand Down
5 changes: 2 additions & 3 deletions tests/integration_tests/functional/test_net.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,8 @@ def test_tap_offload(uvm_any):
)

# Try to send a UDP message from host with UDP offload enabled
cmd = f"ip netns exec {vm.ssh.netns} python3 ./host_tools/udp_offload.py {vm.ssh.host} {port}"
utils.check_output(cmd)
vm.netns.check_output(f"python3 ./host_tools/udp_offload.py {vm.ssh.host} {port}")

# Check that the server received the message
ret = vm.ssh.run(f"cat {out_filename}")
ret = vm.ssh.run(f"sync ; cat {out_filename}")
assert ret.stdout == message, f"{ret.stdout=} {ret.stderr=}"
38 changes: 0 additions & 38 deletions tests/integration_tests/performance/test_huge_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,41 +251,3 @@ def test_negative_huge_pages_plus_balloon(uvm_plain):
match="Machine config error: Firecracker's huge pages support is incompatible with memory ballooning.",
):
uvm_plain.basic_config(huge_pages=HugePagesConfig.HUGETLBFS_2MB)


def test_negative_huge_pages_plus_initrd(uvm_with_initrd):
"""Tests that huge pages and initrd cannot be used together"""
uvm_with_initrd.jailer.daemonize = False
uvm_with_initrd.spawn()
uvm_with_initrd.memory_monitor = None

# Ensure setting huge pages and then telling FC to boot an initrd does not work
with pytest.raises(
RuntimeError,
match="Boot source error: Firecracker's huge pages support is incompatible with initrds.",
):
# `basic_config` first does a PUT to /machine-config, which will apply the huge pages configuration,
# and then a PUT to /boot-source, which will register the initrd
uvm_with_initrd.basic_config(
boot_args="console=ttyS0 reboot=k panic=1 pci=off",
use_initrd=True,
huge_pages=HugePagesConfig.HUGETLBFS_2MB,
add_root_device=False,
vcpu_count=1,
)

# Ensure telling FC about the initrd first and then setting huge pages doesn't work
# This first does a PUT to /machine-config to reset the huge pages configuration, before doing a
# PUT to /boot-source to register the initrd
uvm_with_initrd.basic_config(
huge_pages=HugePagesConfig.NONE,
boot_args="console=ttyS0 reboot=k panic=1 pci=off",
use_initrd=True,
)
with pytest.raises(
RuntimeError,
match="Machine config error: Firecracker's huge pages support is incompatible with initrds.",
):
uvm_with_initrd.api.machine_config.patch(
huge_pages=HugePagesConfig.HUGETLBFS_2MB
)
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""Tests for initrd."""
import pytest

from framework.microvm import Serial
from framework.microvm import HugePagesConfig, Serial

INITRD_FILESYSTEM = "rootfs"


def test_microvm_initrd_with_serial(uvm_with_initrd):
@pytest.fixture
def uvm_with_initrd(microvm_factory, guest_kernel, record_property, artifact_dir):
"""
See file:../docs/initrd.md
"""
fs = artifact_dir / "initramfs.cpio"
record_property("rootfs", fs.name)
uvm = microvm_factory.build(guest_kernel)
uvm.initrd_file = fs
yield uvm


@pytest.mark.parametrize("huge_pages", HugePagesConfig)
def test_microvm_initrd_with_serial(uvm_with_initrd, huge_pages):
"""
Test that a boot using initrd successfully loads the root filesystem.
"""
Expand All @@ -21,6 +35,7 @@ def test_microvm_initrd_with_serial(uvm_with_initrd):
vcpu_count=1,
boot_args="console=ttyS0 reboot=k panic=1 pci=off",
use_initrd=True,
huge_pages=huge_pages,
)

vm.start()
Expand Down

0 comments on commit 40eb957

Please sign in to comment.