1*ceeb2e94Slaokengwt use klog_types::{AllocLogItem, LogSource}; 27b32f508SLoGin 340fe15e0SLoGin use crate::{ 440fe15e0SLoGin arch::mm::LockedFrameAllocator, 57b32f508SLoGin debug::klog::mm::mm_debug_log, 640fe15e0SLoGin libs::align::page_align_up, 740fe15e0SLoGin mm::{MMArch, MemoryManagementArch, VirtAddr}, 840fe15e0SLoGin }; 940fe15e0SLoGin 1040fe15e0SLoGin use core::{ 1140fe15e0SLoGin alloc::{AllocError, GlobalAlloc, Layout}, 1240fe15e0SLoGin intrinsics::unlikely, 1340fe15e0SLoGin ptr::NonNull, 1440fe15e0SLoGin }; 1540fe15e0SLoGin 16*ceeb2e94Slaokengwt use super::{ 17*ceeb2e94Slaokengwt page_frame::{FrameAllocator, PageFrameCount}, 18*ceeb2e94Slaokengwt slab::{slab_init_state, SLABALLOCATOR}, 19*ceeb2e94Slaokengwt }; 2040fe15e0SLoGin 2140fe15e0SLoGin /// 类kmalloc的分配器应当实现的trait 2240fe15e0SLoGin pub trait LocalAlloc { 2340fe15e0SLoGin unsafe fn local_alloc(&self, layout: Layout) -> *mut u8; 2440fe15e0SLoGin unsafe fn local_alloc_zeroed(&self, layout: Layout) -> *mut u8; 2540fe15e0SLoGin unsafe fn local_dealloc(&self, ptr: *mut u8, layout: Layout); 2640fe15e0SLoGin } 2740fe15e0SLoGin 2840fe15e0SLoGin pub struct KernelAllocator; 2940fe15e0SLoGin 3040fe15e0SLoGin impl KernelAllocator { 3140fe15e0SLoGin unsafe fn alloc_in_buddy(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { 3240fe15e0SLoGin // 计算需要申请的页数,向上取整 3340fe15e0SLoGin let count = (page_align_up(layout.size()) / MMArch::PAGE_SIZE).next_power_of_two(); 3440fe15e0SLoGin let page_frame_count = PageFrameCount::new(count); 3540fe15e0SLoGin let (phy_addr, allocated_frame_count) = LockedFrameAllocator 3640fe15e0SLoGin .allocate(page_frame_count) 3740fe15e0SLoGin .ok_or(AllocError)?; 3840fe15e0SLoGin 3940fe15e0SLoGin let virt_addr = unsafe { MMArch::phys_2_virt(phy_addr).ok_or(AllocError)? }; 4040fe15e0SLoGin if unlikely(virt_addr.is_null()) { 4140fe15e0SLoGin return Err(AllocError); 4240fe15e0SLoGin } 4340fe15e0SLoGin 4440fe15e0SLoGin let slice = unsafe { 4540fe15e0SLoGin core::slice::from_raw_parts_mut( 4640fe15e0SLoGin virt_addr.data() as *mut u8, 4740fe15e0SLoGin allocated_frame_count.data() * MMArch::PAGE_SIZE, 4840fe15e0SLoGin ) 4940fe15e0SLoGin }; 5040fe15e0SLoGin return Ok(NonNull::from(slice)); 5140fe15e0SLoGin } 5240fe15e0SLoGin 5340fe15e0SLoGin unsafe fn free_in_buddy(&self, ptr: *mut u8, layout: Layout) { 5440fe15e0SLoGin // 由于buddy分配的页数量是2的幂,因此释放的时候也需要按照2的幂向上取整。 5540fe15e0SLoGin let count = (page_align_up(layout.size()) / MMArch::PAGE_SIZE).next_power_of_two(); 5640fe15e0SLoGin let page_frame_count = PageFrameCount::new(count); 5740fe15e0SLoGin let phy_addr = MMArch::virt_2_phys(VirtAddr::new(ptr as usize)).unwrap(); 5840fe15e0SLoGin LockedFrameAllocator.free(phy_addr, page_frame_count); 5940fe15e0SLoGin } 6040fe15e0SLoGin } 6140fe15e0SLoGin 62453452ccSLoGin /// 为内核分配器实现LocalAlloc的trait 6340fe15e0SLoGin impl LocalAlloc for KernelAllocator { 6440fe15e0SLoGin unsafe fn local_alloc(&self, layout: Layout) -> *mut u8 { 65*ceeb2e94Slaokengwt if allocator_select_condition(layout) { 6640fe15e0SLoGin return self 6740fe15e0SLoGin .alloc_in_buddy(layout) 68b5b571e0SLoGin .map(|x| x.as_mut_ptr()) 69b5b571e0SLoGin .unwrap_or(core::ptr::null_mut()); 70*ceeb2e94Slaokengwt } else { 71*ceeb2e94Slaokengwt if let Some(ref mut slab) = SLABALLOCATOR { 72*ceeb2e94Slaokengwt return slab.allocate(layout); 73*ceeb2e94Slaokengwt }; 74*ceeb2e94Slaokengwt return core::ptr::null_mut(); 75*ceeb2e94Slaokengwt } 7640fe15e0SLoGin } 7740fe15e0SLoGin 7840fe15e0SLoGin unsafe fn local_alloc_zeroed(&self, layout: Layout) -> *mut u8 { 79*ceeb2e94Slaokengwt if allocator_select_condition(layout) { 8040fe15e0SLoGin return self 8140fe15e0SLoGin .alloc_in_buddy(layout) 8240fe15e0SLoGin .map(|x| { 8340fe15e0SLoGin let ptr: *mut u8 = x.as_mut_ptr(); 8440fe15e0SLoGin core::ptr::write_bytes(ptr, 0, x.len()); 8540fe15e0SLoGin ptr 8640fe15e0SLoGin }) 87b5b571e0SLoGin .unwrap_or(core::ptr::null_mut()); 88*ceeb2e94Slaokengwt } else { 89*ceeb2e94Slaokengwt if let Some(ref mut slab) = SLABALLOCATOR { 90*ceeb2e94Slaokengwt return slab.allocate(layout); 91*ceeb2e94Slaokengwt }; 92*ceeb2e94Slaokengwt return core::ptr::null_mut(); 93*ceeb2e94Slaokengwt } 9440fe15e0SLoGin } 9540fe15e0SLoGin 9640fe15e0SLoGin unsafe fn local_dealloc(&self, ptr: *mut u8, layout: Layout) { 97*ceeb2e94Slaokengwt if allocator_select_condition(layout) || ((ptr as usize) % 4096) == 0 { 98*ceeb2e94Slaokengwt self.free_in_buddy(ptr, layout) 99*ceeb2e94Slaokengwt } else if let Some(ref mut slab) = SLABALLOCATOR { 100*ceeb2e94Slaokengwt slab.deallocate(ptr, layout).unwrap() 101*ceeb2e94Slaokengwt } 10240fe15e0SLoGin } 10340fe15e0SLoGin } 10440fe15e0SLoGin 10540fe15e0SLoGin /// 为内核slab分配器实现GlobalAlloc特性 10640fe15e0SLoGin unsafe impl GlobalAlloc for KernelAllocator { 10740fe15e0SLoGin unsafe fn alloc(&self, layout: Layout) -> *mut u8 { 108453452ccSLoGin let r = self.local_alloc_zeroed(layout); 109*ceeb2e94Slaokengwt if allocator_select_condition(layout) { 110*ceeb2e94Slaokengwt alloc_debug_log(klog_types::LogSource::Buddy, layout, r); 111*ceeb2e94Slaokengwt } else { 112*ceeb2e94Slaokengwt alloc_debug_log(klog_types::LogSource::Slab, layout, r); 113*ceeb2e94Slaokengwt } 1147b32f508SLoGin return r; 11540fe15e0SLoGin } 11640fe15e0SLoGin 11740fe15e0SLoGin unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { 1187b32f508SLoGin let r = self.local_alloc_zeroed(layout); 119*ceeb2e94Slaokengwt if allocator_select_condition(layout) { 120*ceeb2e94Slaokengwt alloc_debug_log(klog_types::LogSource::Buddy, layout, r); 121*ceeb2e94Slaokengwt } else { 122*ceeb2e94Slaokengwt alloc_debug_log(klog_types::LogSource::Slab, layout, r); 123*ceeb2e94Slaokengwt } 1247b32f508SLoGin return r; 12540fe15e0SLoGin } 12640fe15e0SLoGin 12740fe15e0SLoGin unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { 128*ceeb2e94Slaokengwt if allocator_select_condition(layout) || ((ptr as usize) % 4096) == 0 { 129*ceeb2e94Slaokengwt dealloc_debug_log(klog_types::LogSource::Buddy, layout, ptr); 130*ceeb2e94Slaokengwt } else { 131*ceeb2e94Slaokengwt dealloc_debug_log(klog_types::LogSource::Slab, layout, ptr); 132*ceeb2e94Slaokengwt } 13340fe15e0SLoGin self.local_dealloc(ptr, layout); 13440fe15e0SLoGin } 13540fe15e0SLoGin } 13640fe15e0SLoGin 137*ceeb2e94Slaokengwt /// 判断选择buddy分配器还是slab分配器 138*ceeb2e94Slaokengwt fn allocator_select_condition(layout: Layout) -> bool { 139*ceeb2e94Slaokengwt layout.size() > 2048 || !slab_init_state() 140*ceeb2e94Slaokengwt } 141*ceeb2e94Slaokengwt 142*ceeb2e94Slaokengwt fn alloc_debug_log(source: LogSource, layout: Layout, ptr: *mut u8) { 143*ceeb2e94Slaokengwt mm_debug_log( 144*ceeb2e94Slaokengwt klog_types::AllocatorLogType::Alloc(AllocLogItem::new(layout, Some(ptr as usize), None)), 145*ceeb2e94Slaokengwt source, 146*ceeb2e94Slaokengwt ) 147*ceeb2e94Slaokengwt } 148*ceeb2e94Slaokengwt 149*ceeb2e94Slaokengwt fn dealloc_debug_log(source: LogSource, layout: Layout, ptr: *mut u8) { 150*ceeb2e94Slaokengwt mm_debug_log( 151*ceeb2e94Slaokengwt klog_types::AllocatorLogType::Free(AllocLogItem::new(layout, Some(ptr as usize), None)), 152*ceeb2e94Slaokengwt source, 153*ceeb2e94Slaokengwt ) 154*ceeb2e94Slaokengwt } 155*ceeb2e94Slaokengwt 15640314b30SXiaoye Zheng /// 为内核slab分配器实现Allocator特性 15740314b30SXiaoye Zheng // unsafe impl Allocator for KernelAllocator { 15840314b30SXiaoye Zheng // fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { 15940314b30SXiaoye Zheng // let memory = unsafe {self.local_alloc(layout)}; 16040314b30SXiaoye Zheng // if memory.is_null() { 16140314b30SXiaoye Zheng // Err(AllocError) 16240314b30SXiaoye Zheng // } else { 16340314b30SXiaoye Zheng // let slice = unsafe { core::slice::from_raw_parts_mut(memory, layout.size()) }; 16440314b30SXiaoye Zheng // Ok(unsafe { NonNull::new_unchecked(slice) }) 16540314b30SXiaoye Zheng // } 16640314b30SXiaoye Zheng // } 16740314b30SXiaoye Zheng 16840314b30SXiaoye Zheng // fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { 16940314b30SXiaoye Zheng // let memory = unsafe {self.local_alloc_zeroed(layout)}; 17040314b30SXiaoye Zheng // if memory.is_null() { 17140314b30SXiaoye Zheng // Err(AllocError) 17240314b30SXiaoye Zheng // } else { 17340314b30SXiaoye Zheng // let slice = unsafe { core::slice::from_raw_parts_mut(memory, layout.size()) }; 17440314b30SXiaoye Zheng // Ok(unsafe { NonNull::new_unchecked(slice) }) 17540314b30SXiaoye Zheng // } 17640314b30SXiaoye Zheng // } 17740314b30SXiaoye Zheng 17840314b30SXiaoye Zheng // unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) { 17940314b30SXiaoye Zheng // self.local_dealloc(ptr.cast().as_ptr(), layout); 18040314b30SXiaoye Zheng // } 18140314b30SXiaoye Zheng // } 18240314b30SXiaoye Zheng 18340fe15e0SLoGin /// 内存分配错误处理函数 184fba56231SLoGin #[cfg(target_os = "none")] 18540fe15e0SLoGin #[alloc_error_handler] 18640fe15e0SLoGin pub fn global_alloc_err_handler(layout: Layout) -> ! { 18740fe15e0SLoGin panic!("global_alloc_error, layout: {:?}", layout); 18840fe15e0SLoGin } 189