diff options
author | Jakub Staron <jstaron@google.com> | 2019-04-24 10:55:25 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-06-05 07:28:54 +0000 |
commit | a3411eaac1ad3d51d5282d1462d6764ad539ce13 (patch) | |
tree | 7a9898280f1cd8c78dcdfac6893189ed42419d76 /resources | |
parent | 127453d7eccdb6a903d0855fabb8f0935be90882 (diff) | |
download | crosvm-a3411eaac1ad3d51d5282d1462d6764ad539ce13.tar crosvm-a3411eaac1ad3d51d5282d1462d6764ad539ce13.tar.gz crosvm-a3411eaac1ad3d51d5282d1462d6764ad539ce13.tar.bz2 crosvm-a3411eaac1ad3d51d5282d1462d6764ad539ce13.tar.lz crosvm-a3411eaac1ad3d51d5282d1462d6764ad539ce13.tar.xz crosvm-a3411eaac1ad3d51d5282d1462d6764ad539ce13.tar.zst crosvm-a3411eaac1ad3d51d5282d1462d6764ad539ce13.zip |
crosvm: virtio-pmem device
Adds support for virtio-pmem device as an alternative for virtio-blk. Exposing disk image to guest as virtio-blk device results in both guest and host independently caching the disk I/O. Using virtio-pmem device allows to mount disk image as direct access (DAX) in the guest and thus bypass the guest cache. This will reduce memory foodprint of the VMs. BUG=None TEST=cargo test TEST=Boot patched termina kernel in crosvm; mount virtio-pmem device as DAX and run xfstests. Change-Id: I935fc8fc7527f79e5169f07ec7927e4ea4fa6027 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1605517 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Zach Reizner <zachr@chromium.org> Commit-Queue: Jakub StaroĊ <jstaron@google.com>
Diffstat (limited to 'resources')
-rw-r--r-- | resources/src/address_allocator.rs | 75 | ||||
-rw-r--r-- | resources/src/lib.rs | 2 |
2 files changed, 71 insertions, 6 deletions
diff --git a/resources/src/address_allocator.rs b/resources/src/address_allocator.rs index 45927e0..11978ee 100644 --- a/resources/src/address_allocator.rs +++ b/resources/src/address_allocator.rs @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +use std::cmp; use std::collections::HashMap; use crate::{Alloc, Error, Result}; @@ -63,18 +64,29 @@ impl AddressAllocator { }) } - /// Allocates a range of addresses from the managed region with an optional tag. - /// Returns allocated_address. (allocated_address, size, tag) can be retrieved - /// through the `get` method. - pub fn allocate(&mut self, size: u64, alloc: Alloc, tag: String) -> Result<u64> { + /// Allocates a range of addresses from the managed region with an optional tag + /// and minimal alignment. Returns allocated_address. (allocated_address, size, tag) + /// can be retrieved through the `get` method. + pub fn allocate_with_align( + &mut self, + size: u64, + alloc: Alloc, + tag: String, + alignment: u64, + ) -> Result<u64> { + let alignment = cmp::max(self.alignment, alignment); + if self.allocs.contains_key(&alloc) { return Err(Error::ExistingAlloc(alloc)); } if size == 0 { return Err(Error::AllocSizeZero); } - let align_adjust = if self.next_addr % self.alignment != 0 { - self.alignment - (self.next_addr % self.alignment) + if !alignment.is_power_of_two() { + return Err(Error::BadAlignment); + } + let align_adjust = if self.next_addr % alignment != 0 { + alignment - (self.next_addr % alignment) } else { 0 }; @@ -95,6 +107,10 @@ impl AddressAllocator { Ok(addr) } + pub fn allocate(&mut self, size: u64, alloc: Alloc, tag: String) -> Result<u64> { + self.allocate_with_align(size, alloc, tag, self.alignment) + } + /// Returns allocation associated with `alloc`, or None if no such allocation exists. pub fn get(&self, alloc: &Alloc) -> Option<&(u64, u64, String)> { self.allocs.get(alloc) @@ -180,4 +196,51 @@ mod tests { Some(&(0x1000, 0x110, String::from("bar0"))) ); } + + #[test] + fn allocate_with_alignment_allocator_alignment() { + let mut pool = AddressAllocator::new(0x1000, 0x10000, Some(0x100)).unwrap(); + assert_eq!( + pool.allocate_with_align(0x110, Alloc::Anon(0), String::from("bar0"), 0x1), + Ok(0x1000) + ); + assert_eq!( + pool.allocate_with_align(0x100, Alloc::Anon(1), String::from("bar1"), 0x1), + Ok(0x1200) + ); + } + + #[test] + fn allocate_with_alignment_custom_alignment() { + let mut pool = AddressAllocator::new(0x1000, 0x10000, Some(0x4)).unwrap(); + assert_eq!( + pool.allocate_with_align(0x110, Alloc::Anon(0), String::from("bar0"), 0x100), + Ok(0x1000) + ); + assert_eq!( + pool.allocate_with_align(0x100, Alloc::Anon(1), String::from("bar1"), 0x100), + Ok(0x1200) + ); + } + + #[test] + fn allocate_with_alignment_no_allocator_alignment() { + let mut pool = AddressAllocator::new(0x1000, 0x10000, None).unwrap(); + assert_eq!( + pool.allocate_with_align(0x110, Alloc::Anon(0), String::from("bar0"), 0x100), + Ok(0x1000) + ); + assert_eq!( + pool.allocate_with_align(0x100, Alloc::Anon(1), String::from("bar1"), 0x100), + Ok(0x1200) + ); + } + + #[test] + fn allocate_with_alignment_alignment_non_power_of_two() { + let mut pool = AddressAllocator::new(0x1000, 0x10000, None).unwrap(); + assert!(pool + .allocate_with_align(0x110, Alloc::Anon(0), String::from("bar0"), 200) + .is_err()); + } } diff --git a/resources/src/lib.rs b/resources/src/lib.rs index a49f998..c10608e 100644 --- a/resources/src/lib.rs +++ b/resources/src/lib.rs @@ -33,6 +33,8 @@ pub enum Alloc { PciBar { bus: u8, dev: u8, bar: u8 }, /// GPU render node region. GpuRenderNode, + /// Pmem device region with associated device index. + PmemDevice(usize), } #[derive(Debug, Eq, PartialEq)] |