ke: fix racey DPC inserted field

This commit is contained in:
Loïc Grégoire
2026-05-19 22:09:54 -04:00
parent 5dac8266f7
commit bf1fa31aed
+4 -5
View File
@@ -15,7 +15,7 @@ pub const Dpc = struct {
/// Argument passed to the routine /// Argument passed to the routine
arg: ?*anyopaque, arg: ?*anyopaque,
/// Whether or not the DPC is currently inserted /// Whether or not the DPC is currently inserted
inserted: bool, inserted: std.atomic.Value(bool),
/// Initialize a DPC for `func`. /// Initialize a DPC for `func`.
pub fn init(func: *const fn (?*anyopaque) void) Dpc { pub fn init(func: *const fn (?*anyopaque) void) Dpc {
@@ -23,7 +23,7 @@ pub const Dpc = struct {
.link = undefined, .link = undefined,
.func = func, .func = func,
.arg = undefined, .arg = undefined,
.inserted = false, .inserted = .init(false),
}; };
} }
}; };
@@ -53,7 +53,7 @@ pub fn enqueue(dpc: *Dpc, arg: ?*anyopaque) void {
const mycpu = ke.cpu.current(); const mycpu = ke.cpu.current();
const dpc_cpu = pcpu.local(); const dpc_cpu = pcpu.local();
if (!dpc.inserted) { if (dpc.inserted.cmpxchgStrong(false, true, .acquire, .monotonic) == null) {
dpc.arg = arg; dpc.arg = arg;
// Insert the DPC on this CPU's DPC queue // Insert the DPC on this CPU's DPC queue
@@ -63,7 +63,6 @@ pub fn enqueue(dpc: *Dpc, arg: ?*anyopaque) void {
// Mark the DPC as pending on this CPU // Mark the DPC as pending on this CPU
ki.ipl.set_softint_pending(mycpu, .Dispatch); ki.ipl.set_softint_pending(mycpu, .Dispatch);
dpc.inserted = true;
dpc_cpu.lock.release_no_ipl(); dpc_cpu.lock.release_no_ipl();
} }
@@ -97,7 +96,7 @@ fn dispatch_queue(cpu: u32) void {
first_elem.remove(); first_elem.remove();
dpc = @fieldParentPtr("link", first_elem); dpc = @fieldParentPtr("link", first_elem);
dpc.inserted = false; dpc.inserted.store(false, .release);
// An interrupt which would enqueue this DPC could occur between loading the argument and calling the routine, // An interrupt which would enqueue this DPC could occur between loading the argument and calling the routine,
// which is why we capture it here to ensure that we get the intended context. // which is why we capture it here to ensure that we get the intended context.