2 个版本
0.1.1 | 2022年10月24日 |
---|---|
0.1.0 | 2022年4月14日 |
#240 在 模拟器
每月 315 次下载
用于 nydus-service
56KB
974 行
dbs-分配器
设计
Dragonball Sandbox中的资源管理器需要管理和分配沙盒(虚拟机)的各种资源,例如内存映射I/O地址空间、端口I/O地址空间、旧式中断号、MSI/MSI-X向量、设备实例ID等。dbs-分配器crate旨在帮助资源管理器跟踪和分配这些类型的资源。
主要组件包括
- 约束:用于声明资源分配约束的结构体。
#[derive(Copy, Clone, Debug)]
pub struct Constraint {
/// Size of resource to allocate.
pub size: u64,
/// Lower boundary for resource allocation.
pub min: u64,
/// Upper boundary for resource allocation.
pub max: u64,
/// Alignment for allocated resource.
pub align: u64,
/// Policy for resource allocation.
pub policy: AllocPolicy,
}
- IntervalTree:一个针对VMM资源管理专门实现的区间树。
pub struct IntervalTree<T> {
pub(crate) root: Option<Node<T>>,
}
pub fn allocate(&mut self, constraint: &Constraint) -> Option<Range>
pub fn free(&mut self, key: &Range) -> Option<T>
pub fn insert(&mut self, key: Range, data: Option<T>) -> Self
pub fn update(&mut self, key: &Range, data: T) -> Option<T>
pub fn delete(&mut self, key: &Range) -> Option<T>
pub fn get(&self, key: &Range) -> Option<NodeState<&T>>
使用方法
区间树的概念可能看起来很复杂,但使用dbs-分配器进行资源分配和释放既简单又直接。您可以通过以下步骤来分配您的VMM资源。
// 1. To start with, we should create an interval tree for some specific resouces and give maximum address/id range as root node. The range here could be address range, id range, etc.
let mut resources_pool = IntervalTree::new();
resources_pool.insert(Range::new(MIN_RANGE, MAX_RANGE), None);
// 2. Next, create a constraint with the size for your resource, you could also assign the maximum, minimum and alignment for the constraint. Then we could use the constraint to allocate the resource in the range we previously decided. Interval Tree will give you the appropriate range.
let mut constraint = Constraint::new(SIZE);
let mut resources_range = self.resources_pool.allocate(&constraint);
// 3. Then we could use the resource range to let other crates like vm-pci / vm-device to create and maintain the device
let mut device = Device::create(resources_range, ..)
示例
我们将展示如何使用dbs-分配器从PCI设备ID池中分配未使用的PCI设备ID以及如何分配内存地址的示例。
use dbs_allocator::{Constraint, IntervalTree, Range};
// Init a dbs-allocator IntervalTree
let mut pci_device_pool = IntervalTree::new();
// Init PCI device id pool with the range 0 to 255
pci_device_pool.insert(Range::new(0x0u8, 0xffu8), None);
// Construct a constraint with size 1 and alignment 1 to ask for an ID.
let mut constraint = Constraint::new(1u64).align(1u64);
// Get an ID from the pci_device_pool
let mut id = pci_device_pool.allocate(&constraint).map(|e| e.min as u8);
// Pass the ID generated from dbs-allocator to vm-pci specified functions to create pci devices
let mut pci_device = PciDevice::new(id as u8, ..);
use dbs_allocator::{Constraint, IntervalTree, Range};
// Init a dbs-allocator IntervalTree
let mut mem_pool = IntervalTree::new();
// Init memory address from GUEST_MEM_START to GUEST_MEM_END
mem_pool.insert(Range::new(GUEST_MEM_START, GUEST_MEM_END), None);
// Construct a constraint with size, maximum addr and minimum address of memory region to ask for an memory allocation range.
let constraint = Constraint::new(region.len())
.min(region.start_addr().raw_value())
.max(region.last_addr().raw_value());
// Get the memory allocation range from the pci_device_pool
let mem_range = mem_pool.allocate(&constraint).unwrap();
// Update the mem_range in IntervalTree with memory region info
mem_pool.update(&mem_range, region);
// After allocation, we can use the memory range to do mapping and other memory related work.
...
许可证
本项目采用Apache许可证,版本2.0。
依赖项
~270–720KB
~17K SLoC