Skip to content

Commit

Permalink
feat: query host page size
Browse files Browse the repository at this point in the history
Define global variable with host page size and
update it at the very beginning of the main function
in Firecracker. This way data types which rely on
specific host page size can adapt to it.

Signed-off-by: Egor Lazarchuk <[email protected]>
  • Loading branch information
ShadowCurse committed Jan 2, 2025
1 parent 846cdef commit 7f614b1
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 4 deletions.
5 changes: 5 additions & 0 deletions src/firecracker/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use seccomp::FilterError;
use seccompiler::BpfThreadMap;
use utils::arg_parser::{ArgParser, Argument};
use utils::validators::validate_instance_id;
use vmm::arch::host_page_size;
use vmm::builder::StartMicrovmError;
use vmm::logger::{
debug, error, info, LoggerConfig, ProcessTimeReporter, StoreMetric, LOGGER, METRICS,
Expand Down Expand Up @@ -108,6 +109,10 @@ fn main_exec() -> Result<(), MainError> {
// Initialize the logger.
LOGGER.init().map_err(MainError::SetLogger)?;

// First call to this function updates the value to current
// host page size.
_ = host_page_size();

// We need this so that we can reset terminal to canonical mode if panic occurs.
let stdin = io::stdin();

Expand Down
18 changes: 16 additions & 2 deletions src/vmm/src/arch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// SPDX-License-Identifier: Apache-2.0

use std::fmt;
use std::sync::LazyLock;

use log::warn;
use serde::{Deserialize, Serialize};

/// Module for aarch64 related functionality.
Expand Down Expand Up @@ -55,8 +57,20 @@ pub struct InitrdConfig {
/// Default page size for the guest OS.
pub const GUEST_PAGE_SIZE: usize = 4096;

/// Default page size for the host OS.
pub const HOST_PAGE_SIZE: usize = 4096;
/// Get the size of the host page size.
pub fn host_page_size() -> usize {
/// Default page size for the host OS.
static PAGE_SIZE: LazyLock<usize> = LazyLock::new(|| {
// # Safety: Value always valid
let r = unsafe { libc::sysconf(libc::_SC_PAGESIZE) };
usize::try_from(r).unwrap_or_else(|_| {
warn!("Could not get host page size with sysconf, assuming default 4K host pages");
4096
})
});

*PAGE_SIZE
}

impl fmt::Display for DeviceType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Expand Down
5 changes: 3 additions & 2 deletions src/vmm/src/devices/virtio/iov_deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::os::fd::AsRawFd;
use libc::{c_int, c_void, iovec, off_t, size_t};
use memfd;

use crate::arch::HOST_PAGE_SIZE;
use crate::arch::host_page_size;

#[derive(Debug, thiserror::Error, displaydoc::Display)]
pub enum IovDequeError {
Expand Down Expand Up @@ -93,7 +93,6 @@ unsafe impl<const L: u16> Send for IovDeque<L> {}

impl<const L: u16> IovDeque<L> {
const BYTES: usize = L as usize * std::mem::size_of::<iovec>();
const _ASSERT: () = assert!(Self::BYTES % HOST_PAGE_SIZE == 0);

/// Create a [`memfd`] object that represents a single physical page
fn create_memfd() -> Result<memfd::Memfd, IovDequeError> {
Expand Down Expand Up @@ -153,6 +152,8 @@ impl<const L: u16> IovDeque<L> {

/// Create a new [`IovDeque`] that can hold memory described by a single VirtIO queue.
pub fn new() -> Result<Self, IovDequeError> {
assert!(Self::BYTES % host_page_size() == 0);

let memfd = Self::create_memfd()?;
let raw_memfd = memfd.as_file().as_raw_fd();
let buffer = Self::allocate_ring_buffer_memory()?;
Expand Down

0 comments on commit 7f614b1

Please sign in to comment.