Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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]>
ShadowCurse committed Nov 15, 2024
1 parent d5bb8b1 commit ddf2cfb
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
@@ -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,
@@ -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();

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

use std::fmt;

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

/// Module for aarch64 related functionality.
@@ -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 unsuccessfull 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 {
5 changes: 3 additions & 2 deletions src/vmm/src/devices/virtio/iov_deque.rs
Original file line number Diff line number Diff line change
@@ -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 {
@@ -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> {
@@ -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()?;

0 comments on commit ddf2cfb

Please sign in to comment.