核心对象概念分析

// newtype pattern,就是一个u64位的地址,在此基础上增加了一些utils方法
pub struct GuestAddress(pub u64);

use crate::{platform::MemoryMapping as SysUtilMmap}
pub struct MemoryMapping {
    mapping: SysUtilMmap,
}

// 底层会调用mmap分配内存,
// SysUtilMmap
pub struct MemoryMapping {
    addr: *mut u8,
    size: usize,
}

pub struct MemoryRegion {
    mapping: MemoryMapping,
    guest_base: GuestAddress,

    shared_obj: BackingObject,
    obj_offset: u64,
}

// 就是多个MemoryRegion,每一个MemoryRegion就是一个mmap,可以share memory,
// 也可以是file mapping
pub struct GuestMemory {
    regions: Arc<[MemoryRegion]>,
}

启动流程

Untitled

Linux Syscall

告诉内核这段内存使用hutgepage

pub fn use_hugepages(&self) -> Result<()> {
    const SZ_2M: usize = 2 * 1024 * 1024;

    // THP uses 2M pages, so use THP only on mappings that are at least
    // 2M in size.
    if self.size() < SZ_2M {
        return Ok(());
    }

    // This is safe because we call madvise with a valid address and size, and we check the
    // return value.
    let ret = unsafe {
        libc::madvise(
            self.as_ptr() as *mut libc::c_void,
            self.size(),
            libc::MADV_HUGEPAGE,
        )
    };
    if ret == -1 {
        Err(Error::SystemCallFailed(ErrnoError::last()))
    } else {
        Ok(())
    }
}

私有文件映射是不需要的,任何变更都只是在内存中,不用同步到文件,但是共享文件映射需要在unmap之前通过msync同步到文件中。

/// Calls msync with MS_SYNC on the mapping.
pub fn msync(&self) -> Result<()> {
    // This is safe since we use the exact address and length of a known
    // good memory mapping.
    let ret = unsafe {
        libc::msync(
            self.as_ptr() as *mut libc::c_void,
            self.size(),
            libc::MS_SYNC,
        )
    };
    if ret == -1 {
        return Err(Error::SystemCallFailed(ErrnoError::last()));
    }
    Ok(())
}

Rust编程技巧

pub struct MemoryMapping {
    addr: *mut u8,
    size: usize,
}

// Send and Sync aren't automatically inherited for the raw address pointer.
// Accessing that pointer is only done through the stateless interface which
// allows the object to be shared by multiple threads without a decrease in
// safety.
unsafe impl Send for MemoryMapping {}
unsafe impl Sync for MemoryMapping {}