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 Nov 27, 2024
1 parent 589818c commit a75cd30
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 3 deletions.
3 changes: 3 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::update_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,8 @@ fn main_exec() -> Result<(), MainError> {
// Initialize the logger.
LOGGER.init().map_err(MainError::SetLogger)?;

update_host_page_size();

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

Expand Down
25 changes: 24 additions & 1 deletion src/vmm/src/arch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use std::fmt;

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

/// Module for aarch64 related functionality.
Expand Down Expand Up @@ -56,7 +57,29 @@ pub struct InitrdConfig {
pub const GUEST_PAGE_SIZE: usize = 4096;

/// Default page size for the host OS.
pub const HOST_PAGE_SIZE: usize = 4096;
static mut HOST_PAGE_SIZE: usize = 4096;

/// Updates the HOST_PAGE_SIZE global variable to the output of
/// sysconf(_SC_PAGESIZE). If call is unsuccessful the default
/// value of 4096 remains.
pub fn update_host_page_size() {
// # Safety:
// There is nothing unsafe here.
let r = unsafe { libc::sysconf(libc::_SC_PAGESIZE) };
if r < 0 {
warn!("Could not get host page size with sysconf, assuming default 4K host pages");
} else {
// # Safety:
// The value is checked.
unsafe { HOST_PAGE_SIZE = usize::try_from(r).unwrap() };
}
}

/// Get the size of the host page size.
pub fn host_page_size() -> usize {
// # Safety: Value always valid
unsafe { HOST_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 a75cd30

Please sign in to comment.