mirror of
https://github.com/rdmsr/zag.git
synced 2026-11-01 15:48:21 +00:00
mm: initial balance manager code
This commit is contained in:
@@ -0,0 +1,71 @@
|
|||||||
|
//! Balance manager.
|
||||||
|
//! The balance manager is called periodically (or when memory is low) to do
|
||||||
|
//! the following actions:
|
||||||
|
//! 1. Reap unused kernel stacks
|
||||||
|
//! 2. Zone trimming
|
||||||
|
//! 3. Working-set trimming (eventually...)
|
||||||
|
|
||||||
|
const r = @import("root");
|
||||||
|
const std = @import("std");
|
||||||
|
const ps = r.ps;
|
||||||
|
const ke = r.ke;
|
||||||
|
const mm = r.mm;
|
||||||
|
const mi = mm.private;
|
||||||
|
|
||||||
|
const balance_interval = ke.Tunable(u32, 1000, "mm.balance.interval_ms");
|
||||||
|
|
||||||
|
const stack_reap_interval = 5;
|
||||||
|
const zone_update_interval = mm.zone.update_interval_s;
|
||||||
|
|
||||||
|
var stack_reap_time: u8 = stack_reap_interval;
|
||||||
|
var zone_update_time: u8 = zone_update_interval;
|
||||||
|
|
||||||
|
pub fn init() void {
|
||||||
|
const td = ps.thread.create_kernel(.LowRealtime, .{
|
||||||
|
.func = balance_manager,
|
||||||
|
.arg = null,
|
||||||
|
}, true) catch
|
||||||
|
@panic("Could not create balance manager thread");
|
||||||
|
|
||||||
|
ke.sched.enqueue(&td.kern);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn balance_manager(_: ?*anyopaque) void {
|
||||||
|
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 (stack_reap_time == 0) {
|
||||||
|
stack_reap_time = stack_reap_interval;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,4 +14,5 @@ pub fn init() linksection(r.init) void {
|
|||||||
pub fn late_init() linksection(r.init) void {
|
pub fn late_init() linksection(r.init) void {
|
||||||
mi.zone.late_init();
|
mi.zone.late_init();
|
||||||
mi.tlb.init();
|
mi.tlb.init();
|
||||||
|
mi.balance.init();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ pub const heap = @import("heap.zig");
|
|||||||
pub const zone = @import("zone.zig");
|
pub const zone = @import("zone.zig");
|
||||||
pub const PMap = pmap.PMap;
|
pub const PMap = pmap.PMap;
|
||||||
pub const tlb = @import("tlb.zig");
|
pub const tlb = @import("tlb.zig");
|
||||||
|
pub const balance = @import("balance.zig");
|
||||||
|
|
||||||
const ke = @import("root").ke;
|
const ke = @import("root").ke;
|
||||||
|
|
||||||
|
|||||||
+4
-11
@@ -118,9 +118,7 @@ const ex = r.ex;
|
|||||||
const mi = mm.private;
|
const mi = mm.private;
|
||||||
|
|
||||||
/// Interval at which we do housekeeping (working set update, reaping, etc.)
|
/// Interval at which we do housekeeping (working set update, reaping, etc.)
|
||||||
const update_interval_s = 15;
|
pub const update_interval_s = 15;
|
||||||
const update_interval: r.Nanoseconds = .from(r.Seconds.init(update_interval_s));
|
|
||||||
var update_work_item: ex.DelayedWorkItem = undefined;
|
|
||||||
|
|
||||||
/// Fixed point conversion for WMA computation.
|
/// Fixed point conversion for WMA computation.
|
||||||
const wma_unit = 256;
|
const wma_unit = 256;
|
||||||
@@ -1076,11 +1074,10 @@ pub const Zone = struct {
|
|||||||
|
|
||||||
self.lock.release();
|
self.lock.release();
|
||||||
|
|
||||||
while (true) {
|
while (entry != head) {
|
||||||
const slab: *Slab = @fieldParentPtr("link", entry);
|
const slab: *Slab = @fieldParentPtr("link", entry);
|
||||||
const next = entry.next;
|
const next = entry.next;
|
||||||
self.slab_destroy(slab);
|
self.slab_destroy(slab);
|
||||||
if (next == head) break;
|
|
||||||
entry = next;
|
entry = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1332,6 +1329,7 @@ pub const Zone = struct {
|
|||||||
|
|
||||||
mm.heap.free(slab.base, self.slab_size);
|
mm.heap.free(slab.base, self.slab_size);
|
||||||
} else {
|
} else {
|
||||||
|
std.log.info("slab is {*}", .{slab});
|
||||||
free_page(@ptrFromInt(
|
free_page(@ptrFromInt(
|
||||||
std.mem.alignBackward(usize, @intFromPtr(slab), mm.page_size),
|
std.mem.alignBackward(usize, @intFromPtr(slab), mm.page_size),
|
||||||
));
|
));
|
||||||
@@ -1503,7 +1501,7 @@ pub const Zone = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Called periodically to do housekeeping tasks on zones.
|
/// Called periodically to do housekeeping tasks on zones.
|
||||||
fn update(_: ?*anyopaque) void {
|
pub fn update() void {
|
||||||
zone_list_lock.acquire();
|
zone_list_lock.acquire();
|
||||||
|
|
||||||
var zone = all_zones;
|
var zone = all_zones;
|
||||||
@@ -1513,9 +1511,6 @@ fn update(_: ?*anyopaque) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
zone_list_lock.release();
|
zone_list_lock.release();
|
||||||
|
|
||||||
// Do it again.
|
|
||||||
ex.work.enqueue_in(&update_work_item, update_interval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parameterized version of Zone, useful for object caches.
|
/// Parameterized version of Zone, useful for object caches.
|
||||||
@@ -1605,8 +1600,6 @@ pub fn late_init() linksection(r.init) void {
|
|||||||
zone_list_lock.release();
|
zone_list_lock.release();
|
||||||
|
|
||||||
magazines_initialized = true;
|
magazines_initialized = true;
|
||||||
update_work_item.init(.Normal, update, null);
|
|
||||||
ex.work.enqueue_in(&update_work_item, update_interval);
|
|
||||||
|
|
||||||
smr_zone.init("SMR", .{});
|
smr_zone.init("SMR", .{});
|
||||||
smr_cpu_zone.init("SMR CPU", @sizeOf(ke.smr.Cpu) * ke.ncpus, .{});
|
smr_cpu_zone.init("SMR CPU", @sizeOf(ke.smr.Cpu) * ke.ncpus, .{});
|
||||||
|
|||||||
Reference in New Issue
Block a user