mirror of
https://github.com/rdmsr/zag.git
synced 2026-11-01 23:58:21 +00:00
ke: add tunables
This commit is contained in:
@@ -77,6 +77,13 @@ SECTIONS
|
|||||||
__percpu_end = .;
|
__percpu_end = .;
|
||||||
} :data
|
} :data
|
||||||
|
|
||||||
|
.data.tunable : {
|
||||||
|
__tunables_start = .;
|
||||||
|
KEEP(*(.data.tunable .data.tunable.*))
|
||||||
|
__tunables_end = .;
|
||||||
|
} :data
|
||||||
|
|
||||||
|
|
||||||
.data : {
|
.data : {
|
||||||
*(.data .data.*)
|
*(.data .data.*)
|
||||||
} :data
|
} :data
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ var stack: [r.kib(16)]u8 align(16) = undefined;
|
|||||||
|
|
||||||
pub fn init(boot_info: *pl.BootInfo) linksection(r.init) void {
|
pub fn init(boot_info: *pl.BootInfo) linksection(r.init) void {
|
||||||
ki.impl.early_init();
|
ki.impl.early_init();
|
||||||
|
ki.tunable.init(boot_info);
|
||||||
std.log.info("Welcome to the machine", .{});
|
std.log.info("Welcome to the machine", .{});
|
||||||
pl.early_init(boot_info);
|
pl.early_init(boot_info);
|
||||||
ki.log.init();
|
ki.log.init();
|
||||||
|
|||||||
@@ -89,3 +89,4 @@ pub const turnstile = @import("turnstile.zig");
|
|||||||
pub const mutex = @import("mutex.zig");
|
pub const mutex = @import("mutex.zig");
|
||||||
pub const queue = @import("queue.zig");
|
pub const queue = @import("queue.zig");
|
||||||
pub const shootdown = @import("shootdown.zig");
|
pub const shootdown = @import("shootdown.zig");
|
||||||
|
pub const tunable = @import("tunable.zig");
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ pub const Event = p.event.Event;
|
|||||||
pub const Queue = p.queue.Queue;
|
pub const Queue = p.queue.Queue;
|
||||||
pub const Mutex = p.mutex.Mutex;
|
pub const Mutex = p.mutex.Mutex;
|
||||||
pub const ShootdownState = p.shootdown.ShootdownState;
|
pub const ShootdownState = p.shootdown.ShootdownState;
|
||||||
|
pub const Tunable = p.tunable.Tunable;
|
||||||
|
|
||||||
// === Exported Interfaces ===
|
// === Exported Interfaces ===
|
||||||
pub const panic = p.panic.panic;
|
pub const panic = p.panic.panic;
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
//! Tunable kernel parameters.
|
||||||
|
//! These are variables set in the cmdline at boot and never changed.
|
||||||
|
const std = @import("std");
|
||||||
|
const rtl = @import("rtl");
|
||||||
|
const r = @import("root");
|
||||||
|
const pl = r.pl;
|
||||||
|
|
||||||
|
const Entry = struct {
|
||||||
|
name: []const u8,
|
||||||
|
address: *anyopaque,
|
||||||
|
type: union(enum) {
|
||||||
|
num: std.builtin.Type.Int,
|
||||||
|
bool: void,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn Tunable(comptime T: type, comptime default: T, comptime name: []const u8) type {
|
||||||
|
return struct {
|
||||||
|
var storage: T = default;
|
||||||
|
|
||||||
|
const metadata: Entry linksection(".data.tunable") =
|
||||||
|
.{
|
||||||
|
.name = name,
|
||||||
|
.address = &storage,
|
||||||
|
.type = if (T == bool)
|
||||||
|
.bool
|
||||||
|
else switch (@typeInfo(T)) {
|
||||||
|
.int => |info| .{ .num = info },
|
||||||
|
else => @compileError("unsupported type"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn load() T {
|
||||||
|
_ = metadata;
|
||||||
|
return storage;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
extern var __tunables_start: u8;
|
||||||
|
extern var __tunables_end: u8;
|
||||||
|
|
||||||
|
pub fn init(boot_info: *pl.BootInfo) void {
|
||||||
|
const cmdline = boot_info.cmdline orelse return;
|
||||||
|
|
||||||
|
const start = @intFromPtr(&__tunables_start);
|
||||||
|
const end = @intFromPtr(&__tunables_end);
|
||||||
|
const count = (end - start) / @sizeOf(Entry);
|
||||||
|
const entries: [*]Entry = @ptrFromInt(start);
|
||||||
|
|
||||||
|
for (0..count) |i| {
|
||||||
|
switch (entries[i].type) {
|
||||||
|
.num => |info| {
|
||||||
|
const a = entries[i].address;
|
||||||
|
|
||||||
|
switch (info.signedness) {
|
||||||
|
.unsigned => {
|
||||||
|
const value = rtl.cmdline.get_number(u64, cmdline, entries[i].name) orelse {
|
||||||
|
std.log.warn("Invalid number value for '{s}', falling back.", .{entries[i].name});
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (info.bits) {
|
||||||
|
8 => (@as(*u8, @ptrCast(@alignCast(a)))).* = std.math.cast(u8, value) orelse continue,
|
||||||
|
16 => (@as(*u16, @ptrCast(@alignCast(a)))).* = std.math.cast(u16, value) orelse continue,
|
||||||
|
32 => (@as(*u32, @ptrCast(@alignCast(a)))).* = std.math.cast(u32, value) orelse continue,
|
||||||
|
64 => (@as(*u64, @ptrCast(@alignCast(a)))).* = value,
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
.signed => {
|
||||||
|
const value = rtl.cmdline.get_number(i64, cmdline, entries[i].name) orelse {
|
||||||
|
std.log.warn("Invalid number value for '{s}', falling back.", .{entries[i].name});
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (info.bits) {
|
||||||
|
8 => (@as(*i8, @ptrCast(@alignCast(a)))).* = std.math.cast(i8, value) orelse continue,
|
||||||
|
16 => (@as(*i16, @ptrCast(@alignCast(a)))).* = std.math.cast(i16, value) orelse continue,
|
||||||
|
32 => (@as(*i32, @ptrCast(@alignCast(a)))).* = std.math.cast(i32, value) orelse continue,
|
||||||
|
64 => (@as(*i64, @ptrCast(@alignCast(a)))).* = value,
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
.bool => {
|
||||||
|
const value = rtl.cmdline.get_string(cmdline, entries[i].name) orelse continue;
|
||||||
|
const ptr: *bool = @ptrCast(@alignCast(entries[i].address));
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, value, "true")) {
|
||||||
|
ptr.* = true;
|
||||||
|
} else if (std.mem.eql(u8, value, "false")) {
|
||||||
|
ptr.* = false;
|
||||||
|
} else {
|
||||||
|
std.log.warn("Invalid cmdline boolean value for tunable '{s}'", .{entries[i].name});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-3
@@ -16,11 +16,11 @@ pub fn get_string(cmdline: []const u8, key: []const u8) ?[]const u8 {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the integer value of `key` in `cmdline`.
|
/// Get the number value of `key` in `cmdline`.
|
||||||
pub fn get_number(cmdline: []const u8, key: []const u8) ?i64 {
|
pub fn get_number(comptime T: type, cmdline: []const u8, key: []const u8) ?T {
|
||||||
const str = get_string(cmdline, key);
|
const str = get_string(cmdline, key);
|
||||||
if (str) |s| {
|
if (str) |s| {
|
||||||
const res = std.fmt.parseInt(i64, s, 10) catch return null;
|
const res = std.fmt.parseInt(T, s, 10) catch return null;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user