mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 14:16:47 +00:00
refactor(mm): 优化内存管理模块代码结构 (#1181)
- 将 `MmioBuddyMemPool` 中的 `free_regions` 从数组改为 `Vec`, 降低初始化的栈内存使用 - 移除不必要的 `LinkedList` 依赖,使用 `Vec` 替代 Signed-off-by: longjin <longjin@DragonOS.org>
This commit is contained in:
parent
1032474cbf
commit
6ac8e1f0cd
@ -40,6 +40,9 @@ impl MemBlockManager {
|
||||
pub const MIN_MEMBLOCK_ADDR: PhysAddr = PhysAddr::new(0);
|
||||
#[allow(dead_code)]
|
||||
pub const MAX_MEMBLOCK_ADDR: PhysAddr = PhysAddr::new(usize::MAX);
|
||||
|
||||
/// 由于这个函数只在全局调用,因此不需要担心栈上溢出问题
|
||||
#[allow(clippy::large_stack_frames)]
|
||||
const fn new() -> Self {
|
||||
Self {
|
||||
inner: SpinLock::new(InnerMemBlockManager {
|
||||
|
@ -5,9 +5,7 @@ use crate::mm::page::{PAGE_1G_SHIFT, PAGE_4K_SHIFT};
|
||||
use crate::mm::{MMArch, MemoryManagementArch};
|
||||
use crate::process::ProcessManager;
|
||||
|
||||
use alloc::{collections::LinkedList, vec::Vec};
|
||||
use core::mem;
|
||||
use core::mem::MaybeUninit;
|
||||
use alloc::vec::Vec;
|
||||
use core::sync::atomic::{AtomicBool, Ordering};
|
||||
use log::{debug, error, info, warn};
|
||||
use system_error::SystemError;
|
||||
@ -43,25 +41,18 @@ pub enum MmioResult {
|
||||
pub struct MmioBuddyMemPool {
|
||||
pool_start_addr: VirtAddr,
|
||||
pool_size: usize,
|
||||
free_regions: [SpinLock<MmioFreeRegionList>; MMIO_BUDDY_REGION_COUNT as usize],
|
||||
free_regions: Vec<SpinLock<MmioFreeRegionList>>,
|
||||
}
|
||||
|
||||
impl MmioBuddyMemPool {
|
||||
#[inline(never)]
|
||||
fn new() -> Self {
|
||||
let mut free_regions: [MaybeUninit<SpinLock<MmioFreeRegionList>>;
|
||||
MMIO_BUDDY_REGION_COUNT as usize] = unsafe { MaybeUninit::uninit().assume_init() };
|
||||
for i in 0..MMIO_BUDDY_REGION_COUNT {
|
||||
free_regions[i as usize] = MaybeUninit::new(SpinLock::new(MmioFreeRegionList::new()));
|
||||
let mut free_regions: Vec<SpinLock<MmioFreeRegionList>> =
|
||||
Vec::with_capacity(MMIO_BUDDY_REGION_COUNT as usize);
|
||||
|
||||
for _ in 0..MMIO_BUDDY_REGION_COUNT {
|
||||
free_regions.push(SpinLock::new(MmioFreeRegionList::new()));
|
||||
}
|
||||
let free_regions = unsafe {
|
||||
mem::transmute::<
|
||||
[core::mem::MaybeUninit<
|
||||
crate::libs::spinlock::SpinLock<crate::mm::mmio_buddy::MmioFreeRegionList>,
|
||||
>; MMIO_BUDDY_REGION_COUNT as usize],
|
||||
[SpinLock<MmioFreeRegionList>; MMIO_BUDDY_REGION_COUNT as usize],
|
||||
>(free_regions)
|
||||
};
|
||||
|
||||
let pool = MmioBuddyMemPool {
|
||||
pool_start_addr: MMArch::MMIO_BASE,
|
||||
@ -70,7 +61,6 @@ impl MmioBuddyMemPool {
|
||||
};
|
||||
|
||||
assert!(pool.pool_start_addr.data() % PAGE_1G_SIZE == 0);
|
||||
debug!("MMIO buddy pool init: created");
|
||||
|
||||
let mut vaddr_base = MMArch::MMIO_BASE;
|
||||
let mut remain_size = MMArch::MMIO_SIZE;
|
||||
@ -122,6 +112,7 @@ impl MmioBuddyMemPool {
|
||||
/// @return Ok(i32) 返回0
|
||||
///
|
||||
/// @return Err(SystemError) 返回错误码
|
||||
#[inline(never)]
|
||||
fn give_back_block(&self, vaddr: VirtAddr, exp: u32) -> Result<i32, SystemError> {
|
||||
// 确保内存对齐,低位都要为0
|
||||
if (vaddr.data() & ((1 << exp) - 1)) != 0 {
|
||||
@ -178,13 +169,13 @@ impl MmioBuddyMemPool {
|
||||
}
|
||||
// 没有恰好符合要求的内存块
|
||||
// 注意:exp对应的链表list_guard已上锁【注意避免死锁问题】
|
||||
if list_guard.num_free == 0 {
|
||||
if list_guard.free_count() == 0 {
|
||||
// 找到最小符合申请范围的内存块
|
||||
// 将大的内存块依次分成小块内存,直到能够满足exp大小,即将exp+1分成两块exp
|
||||
for e in exp + 1..MMIO_BUDDY_MAX_EXP + 1 {
|
||||
let pop_list: &mut SpinLockGuard<MmioFreeRegionList> =
|
||||
&mut self.free_regions[exp2index(e)].lock();
|
||||
if pop_list.num_free == 0 {
|
||||
if pop_list.free_count() == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -232,7 +223,7 @@ impl MmioBuddyMemPool {
|
||||
break;
|
||||
}
|
||||
// 判断是否获得了exp大小的内存块
|
||||
if list_guard.num_free > 0 {
|
||||
if list_guard.free_count() > 0 {
|
||||
match self.pop_block(list_guard) {
|
||||
Ok(ret) => return Ok(ret),
|
||||
Err(err) => return Err(err),
|
||||
@ -283,7 +274,7 @@ impl MmioBuddyMemPool {
|
||||
}
|
||||
|
||||
//判断是否获得了exp大小的内存块
|
||||
if list_guard.num_free > 0 {
|
||||
if list_guard.free_count() > 0 {
|
||||
match self.pop_block(list_guard) {
|
||||
Ok(ret) => return Ok(ret),
|
||||
Err(err) => return Err(err),
|
||||
@ -325,8 +316,7 @@ impl MmioBuddyMemPool {
|
||||
region: MmioBuddyAddrRegion,
|
||||
list_guard: &mut SpinLockGuard<MmioFreeRegionList>,
|
||||
) {
|
||||
list_guard.list.push_back(region);
|
||||
list_guard.num_free += 1;
|
||||
list_guard.list.push(region);
|
||||
}
|
||||
|
||||
/// @brief 根据地址和内存块大小,计算伙伴块虚拟内存的地址
|
||||
@ -365,7 +355,6 @@ impl MmioBuddyMemPool {
|
||||
.extract_if(|x| x.vaddr == buddy_vaddr)
|
||||
.collect();
|
||||
if element.len() == 1 {
|
||||
list_guard.num_free -= 1;
|
||||
return Ok(element.pop().unwrap());
|
||||
}
|
||||
|
||||
@ -386,8 +375,7 @@ impl MmioBuddyMemPool {
|
||||
list_guard: &mut SpinLockGuard<MmioFreeRegionList>,
|
||||
) -> Result<MmioBuddyAddrRegion, MmioResult> {
|
||||
if !list_guard.list.is_empty() {
|
||||
list_guard.num_free -= 1;
|
||||
return Ok(list_guard.list.pop_back().unwrap());
|
||||
return Ok(list_guard.list.pop().unwrap());
|
||||
}
|
||||
return Err(MmioResult::ISEMPTY);
|
||||
}
|
||||
@ -412,22 +400,22 @@ impl MmioBuddyMemPool {
|
||||
high_list_guard: &mut SpinLockGuard<MmioFreeRegionList>,
|
||||
) -> Result<MmioResult, MmioResult> {
|
||||
// 至少要两个内存块才能合并
|
||||
if list_guard.num_free <= 1 {
|
||||
if list_guard.free_count() <= 1 {
|
||||
return Err(MmioResult::EINVAL);
|
||||
}
|
||||
loop {
|
||||
if list_guard.num_free <= 1 {
|
||||
if list_guard.free_count() <= 1 {
|
||||
break;
|
||||
}
|
||||
// 获取内存块
|
||||
let vaddr: VirtAddr = list_guard.list.back().unwrap().vaddr;
|
||||
let vaddr: VirtAddr = list_guard.list.last().unwrap().vaddr;
|
||||
// 获取伙伴内存块
|
||||
match self.pop_buddy_block(vaddr, exp, list_guard) {
|
||||
Err(err) => {
|
||||
return Err(err);
|
||||
}
|
||||
Ok(buddy_region) => {
|
||||
let region: MmioBuddyAddrRegion = list_guard.list.pop_back().unwrap();
|
||||
let region: MmioBuddyAddrRegion = list_guard.list.pop().unwrap();
|
||||
let copy_region = region.clone();
|
||||
// 在两块内存都被取出之后才进行合并
|
||||
match self.merge_blocks(region, buddy_region, exp, high_list_guard) {
|
||||
@ -593,17 +581,17 @@ impl MmioBuddyAddrRegion {
|
||||
/// @brief 空闲页数组结构体
|
||||
#[derive(Debug, Default)]
|
||||
pub struct MmioFreeRegionList {
|
||||
/// 存储mmio_buddy的地址链表
|
||||
list: LinkedList<MmioBuddyAddrRegion>,
|
||||
/// 空闲块的数量
|
||||
num_free: i64,
|
||||
/// 存储mmio_buddy的地址数组
|
||||
list: Vec<MmioBuddyAddrRegion>,
|
||||
}
|
||||
impl MmioFreeRegionList {
|
||||
#[allow(dead_code)]
|
||||
fn new() -> Self {
|
||||
return MmioFreeRegionList {
|
||||
..Default::default()
|
||||
};
|
||||
const fn new() -> Self {
|
||||
Self { list: Vec::new() }
|
||||
}
|
||||
|
||||
fn free_count(&self) -> usize {
|
||||
return self.list.len();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user