Skip to content

Commit c5e5608

Browse files
committed
Merge branch 'bullhh-new_alloc' into next
2 parents 48bb7aa + 949450e commit c5e5608

4 files changed

Lines changed: 89 additions & 34 deletions

File tree

Cargo.lock

Lines changed: 12 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

modules/axalloc/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ tracking = ["dep:percpu", "dep:axbacktrace", "buddy-slab-allocator/tracking"]
1515
buddy-slab-allocator = {git = "https://github.com/arceos-hypervisor/buddy-slab-allocator.git", branch = "main", features = ["log"] }
1616
axbacktrace = { workspace = true, optional = true }
1717
axerrno.workspace = true
18-
cfg-if.workspace = true
1918
kspin.workspace = true
19+
kernel_guard.workspace = true
2020
log.workspace = true
2121
memory_addr.workspace = true
2222
percpu = { workspace = true, optional = true }

modules/axalloc/src/lib.rs

Lines changed: 73 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ use buddy_slab_allocator::{AllocResult, PageAllocator};
1616
use kspin::SpinNoIrq;
1717
use strum::{IntoStaticStr, VariantArray};
1818

19+
pub use buddy_slab_allocator::AddrTranslator;
20+
1921
// Page size can be configured from here
2022
const PAGE_SIZE: usize = 0x1000;
2123

@@ -78,7 +80,7 @@ impl fmt::Debug for Usages {
7880
/// This is an adapter around the allocator::GlobalAllocator that provides
7981
/// compatibility with the original axalloc API.
8082
pub struct GlobalAllocator {
81-
inner: buddy_slab_allocator::GlobalAllocator<PAGE_SIZE>,
83+
inner: SpinNoIrq<buddy_slab_allocator::GlobalAllocator<PAGE_SIZE>>,
8284
usages: SpinNoIrq<Usages>,
8385
}
8486

@@ -92,40 +94,50 @@ impl GlobalAllocator {
9294
/// Creates an empty [`GlobalAllocator`].
9395
pub const fn new() -> Self {
9496
Self {
95-
inner: buddy_slab_allocator::GlobalAllocator::<PAGE_SIZE>::new(),
97+
inner: SpinNoIrq::new(buddy_slab_allocator::GlobalAllocator::<PAGE_SIZE>::new()),
9698
usages: SpinNoIrq::new(Usages::new()),
9799
}
98100
}
99101

102+
/// Configure the address translator used by the underlying allocator so
103+
/// that it can reason about physical address ranges (e.g. low-memory
104+
/// regions below 4GiB).
105+
pub fn set_addr_translator(
106+
&self,
107+
translator: &'static dyn buddy_slab_allocator::AddrTranslator,
108+
) {
109+
self.inner.lock().set_addr_translator(translator);
110+
}
111+
100112
/// Returns the name of the allocator.
101113
pub const fn name(&self) -> &'static str {
102-
"buddy_slab_allocator"
114+
"buddy-slab-allocator"
103115
}
104116

105117
/// Initializes the allocator with the given region.
106118
pub fn init(&self, start_vaddr: usize, size: usize) {
107119
info!(
108-
"Initialize global memory allocator, addr:[{:#x}-{:#x})",
109-
start_vaddr, start_vaddr + size
120+
"Initialize global memory allocator, start_vaddr: {}, size: {}",
121+
start_vaddr, size
110122
);
111-
if let Err(e) = self.inner.init(start_vaddr, size) {
123+
if let Err(e) = self.inner.lock().init(start_vaddr, size) {
112124
panic!("Failed to initialize allocator: {:?}", e);
113125
}
114126
}
115127

116128
/// Add the given region to the allocator.
117129
pub fn add_memory(&self, start_vaddr: usize, size: usize) -> AllocResult {
118-
info!(
119-
"Add memory region to allocator, addr:[{:#x}-{:#x})",
120-
start_vaddr, start_vaddr + size
130+
info!(
131+
"Add memory region, start_vaddr: {}, size: {}",
132+
start_vaddr, size
121133
);
122-
self.inner.add_memory(start_vaddr, size)
134+
self.inner.lock().add_memory(start_vaddr, size)
123135
}
124136

125137
/// Allocate arbitrary number of bytes. Returns the left bound of the
126138
/// allocated region.
127139
pub fn alloc(&self, layout: Layout) -> AllocResult<NonNull<u8>> {
128-
let result = self.inner.alloc(layout);
140+
let result = self.inner.lock().alloc(layout);
129141
if let Ok(_ptr) = result {
130142
self.usages.lock().alloc(UsageKind::RustHeap, layout.size());
131143
}
@@ -137,7 +149,7 @@ impl GlobalAllocator {
137149
self.usages
138150
.lock()
139151
.dealloc(UsageKind::RustHeap, layout.size());
140-
self.inner.dealloc(pos, layout);
152+
self.inner.lock().dealloc(pos, layout);
141153
}
142154

143155
/// Allocates contiguous pages.
@@ -147,7 +159,22 @@ impl GlobalAllocator {
147159
alignment: usize,
148160
kind: UsageKind,
149161
) -> AllocResult<usize> {
150-
let result = self.inner.alloc_pages(num_pages, alignment);
162+
let result = self.inner.lock().alloc_pages(num_pages, alignment);
163+
if let Ok(_addr) = result {
164+
let size = num_pages * PAGE_SIZE;
165+
self.usages.lock().alloc(kind, size);
166+
}
167+
result
168+
}
169+
170+
/// Allocates contiguous low-memory pages (physical address < 4GiB).
171+
pub fn alloc_dma32_pages(
172+
&self,
173+
num_pages: usize,
174+
alignment: usize,
175+
kind: UsageKind,
176+
) -> AllocResult<usize> {
177+
let result = self.inner.lock().alloc_dma32_pages(num_pages, alignment);
151178
if let Ok(_addr) = result {
152179
let size = num_pages * PAGE_SIZE;
153180
self.usages.lock().alloc(kind, size);
@@ -157,13 +184,16 @@ impl GlobalAllocator {
157184

158185
/// Allocates contiguous pages starting from the given address.
159186
pub fn alloc_pages_at(
160-
&mut self,
187+
&self,
161188
start: usize,
162189
num_pages: usize,
163190
alignment: usize,
164191
kind: UsageKind,
165192
) -> AllocResult<usize> {
166-
let result = self.inner.alloc_pages_at(start, num_pages, alignment);
193+
let result = self
194+
.inner
195+
.lock()
196+
.alloc_pages_at(start, num_pages, alignment);
167197
if let Ok(_addr) = result {
168198
let size = num_pages * PAGE_SIZE;
169199
self.usages.lock().alloc(kind, size);
@@ -175,35 +205,35 @@ impl GlobalAllocator {
175205
pub fn dealloc_pages(&self, pos: usize, num_pages: usize, kind: UsageKind) {
176206
let size = num_pages * PAGE_SIZE;
177207
self.usages.lock().dealloc(kind, size);
178-
self.inner.dealloc_pages(pos, num_pages);
208+
self.inner.lock().dealloc_pages(pos, num_pages);
179209
}
180210

181211
/// Returns the number of allocated bytes in the byte allocator.
182212
#[cfg(feature = "tracking")]
183213
pub fn used_bytes(&self) -> usize {
184-
let stats = self.inner.get_stats();
214+
let stats = self.inner.lock().get_stats();
185215
stats.heap_bytes + stats.slab_bytes
186216
}
187217

188218
/// Returns the number of available bytes in the byte allocator.
189219
#[cfg(feature = "tracking")]
190220
pub fn available_bytes(&self) -> usize {
191221
// The new allocator doesn't have this exact method, so we approximate
192-
let stats = self.inner.get_stats();
222+
let stats = self.inner.lock().get_stats();
193223
stats.free_pages * PAGE_SIZE
194224
}
195225

196226
/// Returns the number of allocated pages in the page allocator.
197227
#[cfg(feature = "tracking")]
198228
pub fn used_pages(&self) -> usize {
199-
let stats = self.inner.get_stats();
229+
let stats = self.inner.lock().get_stats();
200230
stats.used_pages
201231
}
202232

203233
/// Returns the number of available pages in the page allocator.
204234
#[cfg(feature = "tracking")]
205235
pub fn available_pages(&self) -> usize {
206-
let stats = self.inner.get_stats();
236+
let stats = self.inner.lock().get_stats();
207237
stats.free_pages
208238
}
209239

@@ -312,8 +342,30 @@ pub fn global_init(start_vaddr: usize, size: usize) {
312342
info!("global allocator initialized");
313343
}
314344

345+
struct FnAddrTranslator {
346+
func: fn(memory_addr::VirtAddr) -> memory_addr::PhysAddr,
347+
}
348+
349+
impl buddy_slab_allocator::AddrTranslator for FnAddrTranslator {
350+
fn virt_to_phys(&self, va: usize) -> Option<usize> {
351+
Some((self.func)(memory_addr::VirtAddr::from(va)).as_usize())
352+
}
353+
}
354+
355+
static mut GLOBAL_ADDR_TRANSLATOR: FnAddrTranslator = FnAddrTranslator {
356+
func: |_| memory_addr::PhysAddr::from(0usize),
357+
};
358+
359+
pub fn configure_addr_translator(func: fn(memory_addr::VirtAddr) -> memory_addr::PhysAddr) {
360+
unsafe {
361+
GLOBAL_ADDR_TRANSLATOR.func = func;
362+
let translator: &'static FnAddrTranslator = &*(&raw const GLOBAL_ADDR_TRANSLATOR);
363+
GLOBAL_ALLOCATOR.set_addr_translator(translator);
364+
}
365+
}
366+
315367
/// Add the given memory region to the global allocator.
316-
///
368+
317369
/// Users should ensure that the region is valid and not being used by others,
318370
/// so that the allocated memory is also valid.
319371
///

modules/axruntime/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,12 +226,14 @@ pub fn rust_main(cpu_id: usize, arg: usize) -> ! {
226226

227227
#[cfg(feature = "alloc")]
228228
fn init_allocator() {
229-
use axhal::mem::{MemRegionFlags, memory_regions, phys_to_virt};
229+
use axhal::mem::{MemRegionFlags, VirtAddr, memory_regions, phys_to_virt, virt_to_phys};
230230
use memory_addr::MemoryAddr;
231231

232232
info!("Initialize global memory allocator...");
233233
info!(" use {} allocator.", axalloc::global_allocator().name());
234234

235+
axalloc::configure_addr_translator(virt_to_phys);
236+
235237
let mut max_region_size = 0;
236238
let mut max_region_paddr = 0.into();
237239
let mut use_next_free = false;

0 commit comments

Comments
 (0)