feat: 释放slab中的空闲页面到buddy (#932)

* patch: 释放slab中的空闲页面到buddy

* 校验释放的slab_page的起始地址与大小 & SCAllcator增加空闲块计数器
This commit is contained in:
Jomo
2024-10-12 00:57:16 +08:00
committed by GitHub
parent 79eda4bcf9
commit 53629ac383
6 changed files with 80 additions and 19 deletions

View File

@ -51,7 +51,7 @@ impl KernelAllocator {
return Ok(NonNull::from(slice));
}
unsafe fn free_in_buddy(&self, ptr: *mut u8, layout: Layout) {
pub(super) unsafe fn free_in_buddy(&self, ptr: *mut u8, layout: Layout) {
// 由于buddy分配的页数量是2的幂因此释放的时候也需要按照2的幂向上取整。
let count = (page_align_up(layout.size()) / MMArch::PAGE_SIZE).next_power_of_two();
let page_frame_count = PageFrameCount::new(count);

View File

@ -4,12 +4,16 @@ use alloc::boxed::Box;
use log::debug;
use slabmalloc::*;
use crate::{arch::MMArch, mm::MemoryManagementArch, KERNEL_ALLOCATOR};
// 全局slab分配器
pub(crate) static mut SLABALLOCATOR: Option<SlabAllocator> = None;
// slab初始化状态
pub(crate) static mut SLABINITSTATE: AtomicBool = AtomicBool::new(false);
static SLAB_CALLBACK: SlabCallback = SlabCallback;
/// slab分配器实际为一堆小的allocator可以在里面装4K的page
/// 利用这些allocator可以为对象分配不同大小的空间
pub(crate) struct SlabAllocator {
@ -52,7 +56,7 @@ impl SlabAllocator {
) -> Result<(), AllocationError> {
if let Some(nptr) = NonNull::new(ptr) {
self.zone
.deallocate(nptr, layout)
.deallocate(nptr, layout, &SLAB_CALLBACK)
.expect("Couldn't deallocate");
return Ok(());
} else {
@ -80,3 +84,13 @@ pub unsafe fn slab_usage() -> SlabUsage {
SlabUsage::new(0, 0)
}
}
/// 归还slab_page给buddy的回调
pub struct SlabCallback;
impl CallBack for SlabCallback {
unsafe fn free_slab_page(&self, base_addr: *mut u8, size: usize) {
assert_eq!(base_addr as usize & (MMArch::PAGE_SIZE - 1), 0); // 确认地址4k对齐
assert_eq!(size, MMArch::PAGE_SIZE); // 确认释放的slab_page大小
KERNEL_ALLOCATOR.free_in_buddy(base_addr, Layout::from_size_align_unchecked(size, 1));
}
}