diff --git a/kernel/src/mm/memblock.rs b/kernel/src/mm/memblock.rs index ae586146..07f487c2 100644 --- a/kernel/src/mm/memblock.rs +++ b/kernel/src/mm/memblock.rs @@ -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 { diff --git a/kernel/src/mm/mmio_buddy.rs b/kernel/src/mm/mmio_buddy.rs index 0487072b..ad0cd727 100644 --- a/kernel/src/mm/mmio_buddy.rs +++ b/kernel/src/mm/mmio_buddy.rs @@ -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; MMIO_BUDDY_REGION_COUNT as usize], + free_regions: Vec>, } impl MmioBuddyMemPool { #[inline(never)] fn new() -> Self { - let mut free_regions: [MaybeUninit>; - 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> = + 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, - >; MMIO_BUDDY_REGION_COUNT as usize], - [SpinLock; 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 { // 确保内存对齐,低位都要为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 = &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, ) { - 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, ) -> Result { 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, ) -> Result { // 至少要两个内存块才能合并 - 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, - /// 空闲块的数量 - num_free: i64, + /// 存储mmio_buddy的地址数组 + list: Vec, } 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(); } }