mm/zone: add tuning options

This commit is contained in:
Loïc Grégoire
2026-07-04 18:17:38 -04:00
parent baf8516f34
commit 1647da3329
+27 -20
View File
@@ -39,8 +39,9 @@
const rtl = @import("rtl"); const rtl = @import("rtl");
const r = @import("root"); const r = @import("root");
const config = @import("config");
const std = @import("std"); const std = @import("std");
const config = @import("config");
const ke = r.ke; const ke = r.ke;
const mm = r.mm; const mm = r.mm;
const ex = r.ex; const ex = r.ex;
@@ -61,16 +62,22 @@ const slab_align = 8;
const zones_num = 32; const zones_num = 32;
/// Number of rounds in a magazine. /// Number of rounds in a magazine.
const magazine_size = 8; const magazine_size = ke.Tunable(u8, 8, "mm.zone.mag_size");
/// How much extra memory CPUs are allowed to keep around. /// How much extra memory CPUs are allowed to keep around.
const max_local_memory = r.kib(128); const max_local_memory = ke.Tunable(u32, r.kib(128), "mm.zone.max_local_mem");
/// Number of contentions allowed per second before the depot grows. /// Number of contentions allowed per second before the depot grows.
const depot_grow_level = 5 * wma_unit; const depot_grow_level = ke.Tunable(u32, 5 * wma_unit, "mm.zone.depot_grow_level");
/// Number of contentions allowed per second before the depot shrinks. /// Number of contentions allowed per second before the depot shrinks.
const depot_shrink_level = wma_unit / 2; const depot_shrink_level = ke.Tunable(u32, wma_unit / 2, "mm.zone.depot_shrink_level");
/// Number of excess magazines in a zone before they are trimmed.
const excess_magazines = ke.Tunable(u32, 8, "mm.zone.excess_mags");
/// Excess memory in a zone before magazines are trimmed.
const excess_memory = ke.Tunable(u32, r.kib(16), "mm.zone.excess_mem");
/// Every power-of-two-size from 8 to 2048 (inclusively). /// Every power-of-two-size from 8 to 2048 (inclusively).
const generic_zones_num = 9; const generic_zones_num = 9;
@@ -406,7 +413,7 @@ pub const Zone = struct {
self.depot_contention_cur = 0; self.depot_contention_cur = 0;
self.depot_contention_wma = 0; self.depot_contention_wma = 0;
self.cpu_depot_size = 0; self.cpu_depot_size = 0;
self.cpu_depot_limit = max_local_memory / (self.chunk_size * magazine_size); self.cpu_depot_limit = max_local_memory.load() / (self.chunk_size * magazine_size.load());
self.trim_depot = false; self.trim_depot = false;
zone_list_lock.acquire(); zone_list_lock.acquire();
@@ -486,7 +493,7 @@ pub const Zone = struct {
} }
cpu.alloc = full_mag; cpu.alloc = full_mag;
cpu.alloc_rounds = magazine_size; cpu.alloc_rounds = magazine_size.load();
continue; continue;
} }
@@ -505,7 +512,7 @@ pub const Zone = struct {
} }
cpu.alloc = full_mag; cpu.alloc = full_mag;
cpu.alloc_rounds = magazine_size; cpu.alloc_rounds = magazine_size.load();
continue; continue;
} }
@@ -574,7 +581,7 @@ pub const Zone = struct {
cpu.lock.acquire_no_ipl(); cpu.lock.acquire_no_ipl();
const freed = while (true) { const freed = while (true) {
if (cpu.free != null and cpu.free_rounds < magazine_size) { if (cpu.free != null and cpu.free_rounds < magazine_size.load()) {
// Fast path: push directly to free magazine. // Fast path: push directly to free magazine.
if (is_poison_enabled) { if (is_poison_enabled) {
if (self.dtor) |dtor| { if (self.dtor) |dtor| {
@@ -721,11 +728,11 @@ pub const Zone = struct {
cur = (3 * old + cur) / 4; cur = (3 * old + cur) / 4;
if (self.use_magazines) { if (self.use_magazines) {
if (self.cpu_depot_size < self.cpu_depot_limit and cur > depot_grow_level) { if (self.cpu_depot_size < self.cpu_depot_limit and cur > depot_grow_level.load()) {
// We have room to grow the depot and we should. // We have room to grow the depot and we should.
// Put the new WMA at around midpoint between shrink and growth, so that // Put the new WMA at around midpoint between shrink and growth, so that
// we have time to check whether what we just did is good or not. // we have time to check whether what we just did is good or not.
cur = (depot_grow_level + depot_shrink_level) / 2; cur = (depot_grow_level.load() + depot_shrink_level.load()) / 2;
const size = if (self.cpu_depot_size == 0) const size = if (self.cpu_depot_size == 0)
2 2
@@ -735,9 +742,9 @@ pub const Zone = struct {
// Clamp it. // Clamp it.
self.cpu_depot_size = @min(size, self.cpu_depot_limit); self.cpu_depot_size = @min(size, self.cpu_depot_limit);
} else if (self.cpu_depot_size > 0 and cur <= depot_shrink_level) { } else if (self.cpu_depot_size > 0 and cur <= depot_shrink_level.load()) {
// We should shrink the depot. // We should shrink the depot.
cur = (depot_grow_level + depot_shrink_level) / 2; cur = (depot_grow_level.load() + depot_shrink_level.load()) / 2;
self.cpu_depot_size -= 1; self.cpu_depot_size -= 1;
self.trim_depot = true; self.trim_depot = true;
} }
@@ -765,16 +772,16 @@ pub const Zone = struct {
const empty = @min(self.depot.empty_mags.wma, self.depot.empty_mags.min * wma_unit); const empty = @min(self.depot.empty_mags.wma, self.depot.empty_mags.min * wma_unit);
if (empty > config.excess_magazines * wma_unit) { if (empty > excess_magazines.load() * wma_unit) {
// Too many excess magazines. // Too many excess magazines.
return true; return true;
} }
const full = @min(self.depot.full_mags.wma, self.depot.full_mags.min * wma_unit); const full = @min(self.depot.full_mags.wma, self.depot.full_mags.min * wma_unit);
const full_bytes = full * magazine_size * self.chunk_size; const full_bytes = full * magazine_size.load() * self.chunk_size;
if (full >= 2 * wma_unit and full_bytes >= r.kib(16) * wma_unit) { if (full >= 2 * wma_unit and full_bytes >= excess_memory.load() * wma_unit) {
// We have at least 2 excess full magazines and they take up at least 16 KiB. // We have at least 2 excess full magazines and they take up at least 16 KiB.
return true; return true;
} }
@@ -790,7 +797,7 @@ pub const Zone = struct {
self.lock.acquire(); self.lock.acquire();
self.trim_maglist(&self.depot.empty_mags, 0); self.trim_maglist(&self.depot.empty_mags, 0);
self.trim_maglist(&self.depot.full_mags, magazine_size); self.trim_maglist(&self.depot.full_mags, magazine_size.load());
if (trim_depot) { if (trim_depot) {
// The depot has size changed, trim the CPU depots. // The depot has size changed, trim the CPU depots.
@@ -801,7 +808,7 @@ pub const Zone = struct {
} }
self.maglist_destroy(depot.empty_mags.list, 0); self.maglist_destroy(depot.empty_mags.list, 0);
self.maglist_destroy(depot.full_mags.list, magazine_size); self.maglist_destroy(depot.full_mags.list, magazine_size.load());
} }
self.lock.release(); self.lock.release();
@@ -830,7 +837,7 @@ pub const Zone = struct {
} }
self.maglist_destroy(depot.empty_mags.list, 0); self.maglist_destroy(depot.empty_mags.list, 0);
self.maglist_destroy(depot.full_mags.list, magazine_size); self.maglist_destroy(depot.full_mags.list, magazine_size.load());
self.lock.release(); self.lock.release();
} }
@@ -1158,7 +1165,7 @@ pub fn early_init() linksection(r.init) void {
zone.init(generic_zone_names[i], @as(usize, 1) << @intCast(i + 3), .{}); zone.init(generic_zone_names[i], @as(usize, 1) << @intCast(i + 3), .{});
} }
magazine_zone.init("magazine", @sizeOf(Magazine) + magazine_size * @sizeOf(*anyopaque), .{ magazine_zone.init("magazine", @sizeOf(Magazine) + magazine_size.load() * @sizeOf(*anyopaque), .{
.magazines = false, .magazines = false,
}); });
} }