mm: more aggressive reclamation

This commit is contained in:
Loïc Grégoire
2026-09-07 20:58:25 -04:00
parent b5d3c5fdb9
commit 1176e97e90
2 changed files with 63 additions and 29 deletions
+52 -29
View File
@@ -30,41 +30,64 @@ pub fn init() void {
ke.sched.enqueue(&td.kern);
}
fn reap_stacks() void {
if (ke.thread.stack_cache_update()) |lst| {
// Reap all the excess stacks.
var entry: ?*ke.Stack = lst;
while (entry != null) {
const next = entry.?.next;
mm.heap.free(
(@intFromPtr(entry) + @sizeOf(ke.Stack)) -
ps.thread.kernel_thread_stack_size,
ps.thread.kernel_thread_stack_size,
);
entry = next;
}
}
}
fn balance_manager(_: ?*anyopaque) void {
const low_memory = 0;
const timeout = 1;
var timer: ke.Timer = undefined;
timer.init();
var which: usize = timeout;
while (true) {
var timer: ke.Timer = undefined;
timer.init();
ke.timer.set(
&timer,
.from(r.Milliseconds.init(balance_interval.load())),
.{},
);
_ = ke.wait.wait_one(&timer.hdr, "balmgr", .{}) catch unreachable;
stack_reap_time -= 1;
zone_update_time -= 1;
if (zone_update_time == 0) {
zone_update_time = zone_update_interval;
mm.zone.update();
if (which == timeout) {
ke.timer.set(
&timer,
.from(r.Milliseconds.init(balance_interval.load())),
.{},
);
}
if (stack_reap_time == 0) {
stack_reap_time = stack_reap_interval;
which = ke.wait.wait_any(&.{
&mmp.phys.low_memory_event.hdr,
&timer.hdr,
}, "balmgr", .{}) catch
unreachable;
if (ke.thread.stack_cache_update()) |lst| {
// Reap all the excess stacks.
var entry: ?*ke.Stack = lst;
if (which == low_memory) {
reap_stacks();
mm.zone.drain();
mmp.phys.low_memory_event.reset();
} else if (which == timeout) {
stack_reap_time -= 1;
zone_update_time -= 1;
while (entry != null) {
const next = entry.?.next;
mm.heap.free(
(@intFromPtr(entry) + @sizeOf(ke.Stack)) - ps.thread.kernel_thread_stack_size,
ps.thread.kernel_thread_stack_size,
);
entry = next;
}
if (zone_update_time == 0) {
zone_update_time = zone_update_interval;
mm.zone.update();
}
if (stack_reap_time == 0) {
stack_reap_time = stack_reap_interval;
reap_stacks();
}
}
}
+11
View File
@@ -17,6 +17,8 @@ pub var min_memory_threshold: usize = 0;
pub var low_memory_threshold: usize = 0;
/// Threshold at which reclamation stops.
pub var high_memory_threshold: usize = 0;
/// Event triggered when memory is low.
pub var low_memory_event: ke.Event = undefined;
var memory_map: *r.BootInfo.MemMap = undefined;
var early_allocs: usize = 0;
@@ -71,6 +73,10 @@ pub fn alloc() r.PAddr {
_ = usable_memory.fetchSub(mm.page_size, .monotonic);
free_pages -= 1;
if (free_pages < min_memory_threshold) {
low_memory_event.signal();
}
const elem: *mm.PageFree = @fieldParentPtr("link", head);
const page: *mm.Page = @ptrCast(elem);
const phys_addr = mm.pfn_to_page(mm.struct_page_to_pfn(page));
@@ -97,6 +103,10 @@ pub fn alloc_opts(opts: struct { policy: mm.WaitPolicy }) ?r.PAddr {
_ = usable_memory.fetchSub(mm.page_size, .monotonic);
free_pages -= 1;
if (free_pages < min_memory_threshold) {
low_memory_event.signal();
}
const elem: *mm.PageFree = @fieldParentPtr("link", head);
const page: *mm.Page = @ptrCast(elem);
const phys_addr = mm.pfn_to_page(mm.struct_page_to_pfn(page));
@@ -144,6 +154,7 @@ pub fn init() linksection(r.init) void {
memory_map = &r.boot_info.memory_map;
free_list.init();
free_page_event.init(.Notification);
low_memory_event.init(.Notification);
var total_usable_memory: usize = memory_map.loader_memory_used;
log.info("physical memory map:", .{});