diff --git a/Cargo.lock b/Cargo.lock index 7efd309b20..0be5ad125d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -45,6 +45,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d39c09fbfba977f4842e1f6bdc48b979112b64f8886993a34e051bc5f3c5c288" +[[package]] +name = "align-address" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6c08a67736554282858203cd9b7ff53cf55f54c34e85689962748a350cbf0" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -456,6 +462,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "free-list" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d140bfddcc22e1f83bbc5d6930ec5713c62489cdd94b86c92852edfc1db96f2b" +dependencies = [ + "align-address 0.3.0", + "smallvec", +] + [[package]] name = "generic_once_cell" version = "0.1.1" @@ -530,7 +546,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa8da8546263459c84a24582eacf3b7b6d818a12f606e920bcfe5485235dac63" dependencies = [ - "align-address", + "align-address 0.1.0", "time", ] @@ -540,7 +556,7 @@ version = "0.7.0" dependencies = [ "aarch64", "ahash", - "align-address", + "align-address 0.1.0", "anstyle", "anyhow", "arm-gic", @@ -554,6 +570,7 @@ dependencies = [ "dyn-clone", "fdt", "float-cmp", + "free-list", "hashbrown", "hermit-dtb", "hermit-entry", diff --git a/Cargo.toml b/Cargo.toml index 6fc7dc9ee6..1ace093de3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,6 +80,7 @@ cfg-if = "1" crossbeam-utils = { version = "0.8", default-features = false } dyn-clone = "1.0" fdt = "0.1" +free-list = "0.3" hashbrown = { version = "0.14", default-features = false } hermit-entry = { version = "0.10", features = ["kernel"] } hermit-sync = "0.1" diff --git a/src/arch/x86_64/mm/physicalmem.rs b/src/arch/x86_64/mm/physicalmem.rs index 7cc2175396..ea7fface8e 100644 --- a/src/arch/x86_64/mm/physicalmem.rs +++ b/src/arch/x86_64/mm/physicalmem.rs @@ -1,7 +1,7 @@ -use core::alloc::AllocError; use core::sync::atomic::{AtomicUsize, Ordering}; use ::x86_64::structures::paging::{FrameAllocator, PhysFrame}; +use free_list::{AllocError, FreeList, PageLayout, PageRange}; use hermit_sync::InterruptTicketMutex; use multiboot::information::{MemoryType, Multiboot}; @@ -9,9 +9,8 @@ use crate::arch::x86_64::kernel::{get_fdt, get_limit, get_mbinfo}; use crate::arch::x86_64::mm::paging::{BasePageSize, PageSize}; use crate::arch::x86_64::mm::{MultibootMemory, PhysAddr, VirtAddr}; use crate::mm; -use crate::mm::freelist::{FreeList, FreeListEntry}; -static PHYSICAL_FREE_LIST: InterruptTicketMutex = +static PHYSICAL_FREE_LIST: InterruptTicketMutex> = InterruptTicketMutex::new(FreeList::new()); static TOTAL_MEMORY: AtomicUsize = AtomicUsize::new(0); @@ -45,12 +44,14 @@ fn detect_from_fdt() -> Result<(), ()> { VirtAddr(start_address) }; - let entry = FreeListEntry::new(start_address.as_usize(), end_address as usize); + let range = PageRange::new(start_address.as_usize(), end_address as usize).unwrap(); let _ = TOTAL_MEMORY.fetch_add( (end_address - start_address.as_u64()) as usize, Ordering::SeqCst, ); - PHYSICAL_FREE_LIST.lock().push(entry); + unsafe { + PHYSICAL_FREE_LIST.lock().deallocate(range).unwrap(); + } } assert!( @@ -84,15 +85,18 @@ fn detect_from_multiboot_info() -> Result<(), ()> { VirtAddr(m.base_address()) }; - let entry = FreeListEntry::new( + let range = PageRange::new( start_address.as_usize(), (m.base_address() + m.length()) as usize, - ); + ) + .unwrap(); let _ = TOTAL_MEMORY.fetch_add( (m.base_address() + m.length() - start_address.as_u64()) as usize, Ordering::SeqCst, ); - PHYSICAL_FREE_LIST.lock().push(entry); + unsafe { + PHYSICAL_FREE_LIST.lock().deallocate(range).unwrap(); + } } assert!( @@ -111,18 +115,25 @@ fn detect_from_limits() -> Result<(), ()> { // add gap for the APIC if limit > KVM_32BIT_GAP_START { - let entry = FreeListEntry::new(mm::kernel_end_address().as_usize(), KVM_32BIT_GAP_START); - PHYSICAL_FREE_LIST.lock().push(entry); + let range = + PageRange::new(mm::kernel_end_address().as_usize(), KVM_32BIT_GAP_START).unwrap(); + unsafe { + PHYSICAL_FREE_LIST.lock().deallocate(range).unwrap(); + } if limit > KVM_32BIT_GAP_START + KVM_32BIT_GAP_SIZE { - let entry = FreeListEntry::new(KVM_32BIT_GAP_START + KVM_32BIT_GAP_SIZE, limit); - PHYSICAL_FREE_LIST.lock().push(entry); + let range = PageRange::new(KVM_32BIT_GAP_START + KVM_32BIT_GAP_SIZE, limit).unwrap(); + unsafe { + PHYSICAL_FREE_LIST.lock().deallocate(range).unwrap(); + } TOTAL_MEMORY.store(limit - KVM_32BIT_GAP_SIZE, Ordering::SeqCst); } else { TOTAL_MEMORY.store(KVM_32BIT_GAP_START, Ordering::SeqCst); } } else { - let entry = FreeListEntry::new(mm::kernel_end_address().as_usize(), limit); - PHYSICAL_FREE_LIST.lock().push(entry); + let range = PageRange::new(mm::kernel_end_address().as_usize(), limit).unwrap(); + unsafe { + PHYSICAL_FREE_LIST.lock().deallocate(range).unwrap(); + } TOTAL_MEMORY.store(limit, Ordering::SeqCst); } @@ -150,10 +161,13 @@ pub fn allocate(size: usize) -> Result { BasePageSize::SIZE ); + let layout = PageLayout::from_size(size).unwrap(); + Ok(PhysAddr( PHYSICAL_FREE_LIST .lock() - .allocate(size, None)? + .allocate(layout)? + .start() .try_into() .unwrap(), )) @@ -163,10 +177,8 @@ pub struct FrameAlloc; unsafe impl FrameAllocator for FrameAlloc { fn allocate_frame(&mut self) -> Option> { - let addr = PHYSICAL_FREE_LIST - .lock() - .allocate(S::SIZE as usize, Some(S::SIZE as usize)) - .ok()? as u64; + let layout = PageLayout::from_size_align(S::SIZE as usize, S::SIZE as usize).unwrap(); + let addr = PHYSICAL_FREE_LIST.lock().allocate(layout).ok()?.start() as u64; Some(PhysFrame::from_start_address(x86_64::PhysAddr::new(addr)).unwrap()) } } @@ -187,10 +199,13 @@ pub fn allocate_aligned(size: usize, align: usize) -> Result = +static KERNEL_FREE_LIST: InterruptTicketMutex> = InterruptTicketMutex::new(FreeList::new()); pub fn init() { - let entry = FreeListEntry::new( + let range = PageRange::new( mm::kernel_end_address().as_usize(), kernel_heap_end().as_usize(), - ); - KERNEL_FREE_LIST.lock().push(entry); + ) + .unwrap(); + unsafe { + KERNEL_FREE_LIST.lock().deallocate(range).unwrap(); + } } pub fn allocate(size: usize) -> Result { @@ -28,10 +29,13 @@ pub fn allocate(size: usize) -> Result { BasePageSize::SIZE ); + let layout = PageLayout::from_size(size).unwrap(); + Ok(VirtAddr( KERNEL_FREE_LIST .lock() - .allocate(size, None)? + .allocate(layout)? + .start() .try_into() .unwrap(), )) @@ -54,10 +58,13 @@ pub fn allocate_aligned(size: usize, align: usize) -> Result