Skip to content

Commit 4901d80

Browse files
committed
feat(memory): 优化内存分配器性能并改进TLB刷新策略
1 parent 39249f2 commit 4901d80

File tree

3 files changed

+40
-8
lines changed

3 files changed

+40
-8
lines changed

kernel/src/memory/frame/buddy.rs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ impl<const MAX_ORDER: usize> BuddyAllocator<MAX_ORDER> {
6969
/// Set the bitmap for the allocator.
7070
pub fn set_bitmap(&mut self, bitmap: &'static mut [u64]) {
7171
self.bitmap = bitmap;
72-
// Clear bitmap
73-
for x in self.bitmap.iter_mut() {
74-
*x = 0;
72+
// Faster clear using write_bytes
73+
unsafe {
74+
core::ptr::write_bytes(self.bitmap.as_mut_ptr(), 0, self.bitmap.len());
7575
}
7676
}
7777

@@ -245,8 +245,31 @@ impl<const MAX_ORDER: usize> BuddyAllocator<MAX_ORDER> {
245245
pub unsafe fn add_region(&mut self, start: PhysFrame<Size4KiB>, end: PhysFrame<Size4KiB>) {
246246
let mut current = start;
247247
while current < end {
248-
self.add_frame(current);
249-
current += 1;
248+
let current_addr = current.start_address().as_u64();
249+
let end_addr = end.start_address().as_u64();
250+
let remaining_frames = (end_addr - current_addr) / 4096;
251+
252+
// Find the largest power-of-two block that fits and is aligned
253+
let mut order = 0;
254+
while order < MAX_ORDER - 1 {
255+
let next_order = order + 1;
256+
let size_frames = 1 << next_order;
257+
let size_bytes = 4096 * size_frames;
258+
259+
// Check alignment
260+
if !current_addr.is_multiple_of(size_bytes) {
261+
break;
262+
}
263+
// Check size
264+
if size_frames > remaining_frames {
265+
break;
266+
}
267+
order = next_order;
268+
}
269+
270+
self.total_frames += 1 << order;
271+
self.merge_block(current, order);
272+
current += 1 << order;
250273
}
251274
}
252275

kernel/src/memory/heap.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,13 @@ impl talc::OomHandler for KernelOomHandler {
5454
.page_table
5555
.map_to(page, frame, flags, &mut frame_allocator)
5656
.map_err(|_| ())?
57-
.flush();
57+
.ignore();
5858
}
5959
}
6060

61+
// Flush TLB once after expanding heap
62+
x86_64::instructions::tlb::flush_all();
63+
6164
drop(ms_lock);
6265

6366
unsafe {
@@ -103,10 +106,13 @@ pub fn init_heap(
103106
.ok_or(MapToError::FrameAllocationFailed)?;
104107
let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE | PageTableFlags::NO_EXECUTE;
105108
unsafe {
106-
mapper.map_to(page, frame, flags, frame_allocator)?.flush();
109+
mapper.map_to(page, frame, flags, frame_allocator)?.ignore();
107110
}
108111
}
109112

113+
// Flush TLB once after initial heap mapping
114+
x86_64::instructions::tlb::flush_all();
115+
110116
unsafe {
111117
ALLOCATOR
112118
.lock()

kernel/src/memory/paging/vmm.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,15 @@ impl MemorySet {
222222
.page_table
223223
.map_to(page, phys_frame, flags, &mut frame_allocator)
224224
{
225-
Ok(t) => t.flush(),
225+
Ok(t) => t.ignore(),
226226
Err(MapToError::PageAlreadyMapped(_)) => continue,
227227
Err(_) => return Err("Failed to map page"),
228228
}
229229
}
230230
}
231+
232+
// Flush TLB once after all mappings are done
233+
x86_64::instructions::tlb::flush_all();
231234
Ok(())
232235
}
233236
}

0 commit comments

Comments
 (0)