mirror of
https://github.com/rdmsr/zag.git
synced 2026-11-02 08:08:21 +00:00
mm: more aggressive reclamation
This commit is contained in:
+37
-14
@@ -30,18 +30,52 @@ pub fn init() void {
|
|||||||
ke.sched.enqueue(&td.kern);
|
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 {
|
fn balance_manager(_: ?*anyopaque) void {
|
||||||
while (true) {
|
const low_memory = 0;
|
||||||
|
const timeout = 1;
|
||||||
|
|
||||||
var timer: ke.Timer = undefined;
|
var timer: ke.Timer = undefined;
|
||||||
timer.init();
|
timer.init();
|
||||||
|
|
||||||
|
var which: usize = timeout;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (which == timeout) {
|
||||||
ke.timer.set(
|
ke.timer.set(
|
||||||
&timer,
|
&timer,
|
||||||
.from(r.Milliseconds.init(balance_interval.load())),
|
.from(r.Milliseconds.init(balance_interval.load())),
|
||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
_ = ke.wait.wait_one(&timer.hdr, "balmgr", .{}) catch unreachable;
|
which = ke.wait.wait_any(&.{
|
||||||
|
&mmp.phys.low_memory_event.hdr,
|
||||||
|
&timer.hdr,
|
||||||
|
}, "balmgr", .{}) catch
|
||||||
|
unreachable;
|
||||||
|
|
||||||
|
if (which == low_memory) {
|
||||||
|
reap_stacks();
|
||||||
|
mm.zone.drain();
|
||||||
|
mmp.phys.low_memory_event.reset();
|
||||||
|
} else if (which == timeout) {
|
||||||
stack_reap_time -= 1;
|
stack_reap_time -= 1;
|
||||||
zone_update_time -= 1;
|
zone_update_time -= 1;
|
||||||
|
|
||||||
@@ -53,18 +87,7 @@ fn balance_manager(_: ?*anyopaque) void {
|
|||||||
if (stack_reap_time == 0) {
|
if (stack_reap_time == 0) {
|
||||||
stack_reap_time = stack_reap_interval;
|
stack_reap_time = stack_reap_interval;
|
||||||
|
|
||||||
if (ke.thread.stack_cache_update()) |lst| {
|
reap_stacks();
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ pub var min_memory_threshold: usize = 0;
|
|||||||
pub var low_memory_threshold: usize = 0;
|
pub var low_memory_threshold: usize = 0;
|
||||||
/// Threshold at which reclamation stops.
|
/// Threshold at which reclamation stops.
|
||||||
pub var high_memory_threshold: usize = 0;
|
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 memory_map: *r.BootInfo.MemMap = undefined;
|
||||||
var early_allocs: usize = 0;
|
var early_allocs: usize = 0;
|
||||||
@@ -71,6 +73,10 @@ pub fn alloc() r.PAddr {
|
|||||||
_ = usable_memory.fetchSub(mm.page_size, .monotonic);
|
_ = usable_memory.fetchSub(mm.page_size, .monotonic);
|
||||||
free_pages -= 1;
|
free_pages -= 1;
|
||||||
|
|
||||||
|
if (free_pages < min_memory_threshold) {
|
||||||
|
low_memory_event.signal();
|
||||||
|
}
|
||||||
|
|
||||||
const elem: *mm.PageFree = @fieldParentPtr("link", head);
|
const elem: *mm.PageFree = @fieldParentPtr("link", head);
|
||||||
const page: *mm.Page = @ptrCast(elem);
|
const page: *mm.Page = @ptrCast(elem);
|
||||||
const phys_addr = mm.pfn_to_page(mm.struct_page_to_pfn(page));
|
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);
|
_ = usable_memory.fetchSub(mm.page_size, .monotonic);
|
||||||
free_pages -= 1;
|
free_pages -= 1;
|
||||||
|
|
||||||
|
if (free_pages < min_memory_threshold) {
|
||||||
|
low_memory_event.signal();
|
||||||
|
}
|
||||||
|
|
||||||
const elem: *mm.PageFree = @fieldParentPtr("link", head);
|
const elem: *mm.PageFree = @fieldParentPtr("link", head);
|
||||||
const page: *mm.Page = @ptrCast(elem);
|
const page: *mm.Page = @ptrCast(elem);
|
||||||
const phys_addr = mm.pfn_to_page(mm.struct_page_to_pfn(page));
|
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;
|
memory_map = &r.boot_info.memory_map;
|
||||||
free_list.init();
|
free_list.init();
|
||||||
free_page_event.init(.Notification);
|
free_page_event.init(.Notification);
|
||||||
|
low_memory_event.init(.Notification);
|
||||||
|
|
||||||
var total_usable_memory: usize = memory_map.loader_memory_used;
|
var total_usable_memory: usize = memory_map.loader_memory_used;
|
||||||
log.info("physical memory map:", .{});
|
log.info("physical memory map:", .{});
|
||||||
|
|||||||
Reference in New Issue
Block a user