Skip to content

Commit 2a7678d

Browse files
committed
Allocate multiple pages at once
1 parent 94c7a80 commit 2a7678d

File tree

4 files changed

+13
-21
lines changed

4 files changed

+13
-21
lines changed

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,6 @@ make test
9292
## TODO
9393

9494
- Stack size: figure out why stacks need to be so large when compiling in debug mode. Is Rust putting a ton of debug info on the stack?
95-
- Review/refactor kernel stack + guard page code
96-
- Replace `allocate_and_map_page` with `allocate_and_map_pages`, which accepts a `PageRange`, so we don't have to keep taking a bunch of locks in a loop.
9795
- Synchronization primitives
9896
- Mutex (not spinlock "mutex") that handles sleeping and waking
9997
- I like Linux's mutex where they store the current holder's task ID in an atomic variable

kernel/src/heap.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,8 @@ pub(crate) fn init() -> Result<(), MapToError<Size4KiB>> {
2626
Page::range_inclusive(heap_start_page, heap_end_page)
2727
};
2828

29-
for page in page_range {
30-
let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE;
31-
memory::allocate_and_map_page(page, flags)?;
32-
}
29+
let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE;
30+
memory::allocate_and_map_pages(page_range, flags)?;
3331

3432
unsafe {
3533
// `init() actually writes to the heap, which is why we can only

kernel/src/memory.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,18 @@ pub(crate) fn allocate_physical_frame<S: PageSize>() -> Option<PhysFrame<S>> {
8787
/// virtual page to the physical frame in the page table. Useful for
8888
/// initializing a virtual region that is known not to be backed by memory, like
8989
/// initializing the kernel heap.
90-
pub(crate) fn allocate_and_map_page(
91-
page: Page,
90+
pub(crate) fn allocate_and_map_pages(
91+
pages: impl Iterator<Item = Page>,
9292
flags: PageTableFlags,
9393
) -> Result<(), MapToError<Size4KiB>> {
94-
let frame = allocate_physical_frame::<Size4KiB>().ok_or(MapToError::FrameAllocationFailed)?;
9594
KERNEL_PHYSICAL_ALLOCATOR.with_lock(|allocator| {
9695
KERNEL_MAPPER.with_lock(|mapper| unsafe {
97-
mapper.map_to(page, frame, flags, allocator)?.flush();
96+
for page in pages {
97+
let frame = allocator
98+
.allocate_frame()
99+
.ok_or(MapToError::FrameAllocationFailed)?;
100+
mapper.map_to(page, frame, flags, allocator)?.flush();
101+
}
98102
Ok(())
99103
})
100104
})

kernel/src/sched/stack.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,16 @@ impl KernelStackAllocator<'_> {
6060
);
6161
let stack = KernelStack { start_addr };
6262

63-
// Allocate physical memory
64-
// let physical_size = KERNEL_STACK_SIZE_BYTES - memory::PAGE_SIZE;
65-
// let buffer = PhysicalBuffer::allocate_zeroed(physical_size)
66-
// .expect("failed to allocate PhysicalBuffer for kernel stack");
67-
6863
// Map the guard page as invalid
6964
unsafe {
7065
memory::map_guard_page(stack.guard_page())
7166
.expect("failed to map kernel stack guard page");
7267
}
7368

7469
// Map the physical memory into the virtual address space
75-
for page in stack.physically_mapped_pages() {
76-
let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE;
77-
memory::allocate_and_map_page(page, flags).expect("failed to map kernel stack page");
78-
}
70+
let pages = stack.physically_mapped_pages();
71+
let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE;
72+
memory::allocate_and_map_pages(pages, flags).expect("failed to map kernel stack pages");
7973

8074
// Zero out the memory
8175
unsafe {
@@ -86,8 +80,6 @@ impl KernelStackAllocator<'_> {
8680
Some(stack)
8781
}
8882

89-
// TODO: Instead of a free method, implement Drop for KernelStack that frees
90-
// itself. I'm just a bit wary about calling a Mutex with Drop.
9183
fn free(&mut self, stack: &KernelStack) {
9284
let stack_index = (stack.start_addr.as_u64() - KERNEL_STACK_START_VIRT_ADDR as u64)
9385
/ KERNEL_STACK_SIZE_BYTES as u64;

0 commit comments

Comments
 (0)