mirror of
https://github.com/rdmsr/zag.git
synced 2026-11-01 23:58:21 +00:00
mm+ke: make shootdowns use HandoffList
This commit is contained in:
@@ -19,7 +19,6 @@ pub fn init(boot_info: *r.BootInfo) linksection(r.init) void {
|
|||||||
ki.log.init();
|
ki.log.init();
|
||||||
ki.cpu.init_cpu(0);
|
ki.cpu.init_cpu(0);
|
||||||
ki.turnstile.init_turnstiles();
|
ki.turnstile.init_turnstiles();
|
||||||
ki.shootdown.init();
|
|
||||||
|
|
||||||
thread0.init(@intFromPtr(&stack), r.kib(16), ke.Thread.Priority.idle_low, ki.sched.idle, null);
|
thread0.init(@intFromPtr(&stack), r.kib(16), ke.Thread.Priority.idle_low, ki.sched.idle, null);
|
||||||
thread0.priority = 0;
|
thread0.priority = 0;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ pub const ShootdownState = struct {
|
|||||||
/// This is used as a counter when the request is outstanding,
|
/// This is used as a counter when the request is outstanding,
|
||||||
/// otherwise it is set to the `slot_*` values below.
|
/// otherwise it is set to the `slot_*` values below.
|
||||||
state: std.atomic.Value(u16),
|
state: std.atomic.Value(u16),
|
||||||
link: rtl.List.Entry,
|
link: ?*anyopaque,
|
||||||
/// Base virtual address of the shootdown.
|
/// Base virtual address of the shootdown.
|
||||||
base: r.VAddr,
|
base: r.VAddr,
|
||||||
/// Number of pages to flush.
|
/// Number of pages to flush.
|
||||||
@@ -42,7 +42,7 @@ const slot_free: u16 = std.math.maxInt(u16);
|
|||||||
const slot_reserved: u16 = std.math.maxInt(u16) - 1;
|
const slot_reserved: u16 = std.math.maxInt(u16) - 1;
|
||||||
const percpu = ke.CpuLocal(PerCpu, undefined);
|
const percpu = ke.CpuLocal(PerCpu, undefined);
|
||||||
|
|
||||||
pub var shootdowns: ke.Queue = undefined;
|
pub var shootdowns: rtl.HandoffList = undefined;
|
||||||
|
|
||||||
var sync_counter: std.atomic.Value(usize) = .init(0);
|
var sync_counter: std.atomic.Value(usize) = .init(0);
|
||||||
var sync_addr: r.VAddr = 0;
|
var sync_addr: r.VAddr = 0;
|
||||||
@@ -149,7 +149,7 @@ pub fn process_shootdowns() void {
|
|||||||
flush_range(state.base, state.npages);
|
flush_range(state.base, state.npages);
|
||||||
|
|
||||||
if (state.state.fetchSub(1, .release) == 1) {
|
if (state.state.fetchSub(1, .release) == 1) {
|
||||||
shootdowns.insert(&state.link, .Tail);
|
shootdowns.insert(&state.link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,7 +189,3 @@ pub fn submit(state: ShootdownState, target_mask: ke.CpuMask) !void {
|
|||||||
percpu.remote(@truncate(bit)).senders.set(curcpu, .release);
|
percpu.remote(@truncate(bit)).senders.set(curcpu, .release);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() void {
|
|
||||||
shootdowns.init(ke.ncpus);
|
|
||||||
}
|
|
||||||
|
|||||||
+17
-11
@@ -2,19 +2,26 @@
|
|||||||
|
|
||||||
const r = @import("root");
|
const r = @import("root");
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const rtl = @import("rtl");
|
||||||
|
|
||||||
const ke = r.ke;
|
const ke = r.ke;
|
||||||
const mm = r.mm;
|
const mm = r.mm;
|
||||||
const mi = mm.private;
|
const mi = mm.private;
|
||||||
const ps = r.ps;
|
const ps = r.ps;
|
||||||
|
const ex = r.ex;
|
||||||
|
|
||||||
pub var sync_shootdowns: std.atomic.Value(usize) = .init(0);
|
pub var sync_shootdowns: std.atomic.Value(usize) = .init(0);
|
||||||
pub var async_shootdowns: std.atomic.Value(usize) = .init(0);
|
pub var async_shootdowns: std.atomic.Value(usize) = .init(0);
|
||||||
pub var sent_shootdowns: std.atomic.Value(usize) = .init(0);
|
pub var sent_shootdowns: std.atomic.Value(usize) = .init(0);
|
||||||
|
|
||||||
|
var work_item: ex.WorkItem = undefined;
|
||||||
|
|
||||||
/// Reclaim the memory associated with a state.
|
/// Reclaim the memory associated with a state.
|
||||||
/// This can only be done when all CPUs have flushed their TLB.
|
/// This can only be done when all CPUs have flushed their TLB.
|
||||||
fn reclaim_state(state: *ke.ShootdownState) void {
|
fn reclaim_state(obj: *anyopaque, _: ?*anyopaque) void {
|
||||||
|
const link: *?*anyopaque = @ptrCast(@alignCast(obj));
|
||||||
|
const state: *ke.ShootdownState = @fieldParentPtr("link", link);
|
||||||
|
|
||||||
const space: *mm.Space = @ptrFromInt(state.payload[0]);
|
const space: *mm.Space = @ptrFromInt(state.payload[0]);
|
||||||
const pfn_list: mi.PfnList = @bitCast(state.payload[1]);
|
const pfn_list: mi.PfnList = @bitCast(state.payload[1]);
|
||||||
const base = state.base;
|
const base = state.base;
|
||||||
@@ -36,13 +43,8 @@ fn reclaim_state(state: *ke.ShootdownState) void {
|
|||||||
state.release();
|
state.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn worker_thread(_: ?*anyopaque) void {
|
fn reap_pages(_: ?*anyopaque) void {
|
||||||
while (true) {
|
ke.shootdown.shootdowns.process(reclaim_state, null);
|
||||||
const entry = ke.shootdown.shootdowns.remove();
|
|
||||||
const state: *ke.ShootdownState = @fieldParentPtr("link", entry);
|
|
||||||
|
|
||||||
reclaim_state(state);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unmap and flush a virtual range on the given space.
|
/// Unmap and flush a virtual range on the given space.
|
||||||
@@ -86,7 +88,11 @@ pub fn reclaim_range(space: *mm.Space, va: r.VAddr, size: usize) void {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() void {
|
fn activation(_: *rtl.HandoffList) void {
|
||||||
const td = ps.thread.create_kernel(ke.Thread.Priority.default, worker_thread, null) catch unreachable;
|
ex.workqueue.enqueue(&work_item);
|
||||||
ke.sched.enqueue(&td.kern);
|
}
|
||||||
|
|
||||||
|
pub fn init() void {
|
||||||
|
ke.shootdown.shootdowns.* = .init(activation);
|
||||||
|
work_item.init(.High, reap_pages, null);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user