From d66384514f12bf7607fbb45185bc66699e6cbf48 Mon Sep 17 00:00:00 2001 From: slopisgood Date: Thu, 7 Aug 2025 07:54:00 -0700 Subject: [PATCH 2/2] rust: clarify safety comments in workqueue.rs Replace placeholder `SAFETY: TODO` comments in rust/kernel/workqueue.rs with detailed explanations of safety invariants for RawWorkItem and WorkItemPointer, following rust kernel guidelines. Signed-off-by: slopisgood --- rust/kernel/workqueue.rs | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs index b9343d5..4a34651 100644 --- a/rust/kernel/workqueue.rs +++ b/rust/kernel/workqueue.rs @@ -881,7 +881,19 @@ where { } -// SAFETY: TODO. + // SAFETY: + // + // The [`run`](WorkItemPointer::run) function pointer stored in the `work_struct` always + // originates from a prior call to [`__enqueue`](RawWorkItem::__enqueue) on a + // `Pin>`. A `Pin>` owns its heap allocation and, by virtue of being + // pinned, guarantees that its contents will not be moved. When the C side of the + // workqueue invokes the function pointer, it passes back the same `work_struct` + // pointer that was produced by `__enqueue`. This implementation computes the + // original `KBox` from that pointer via `work_container_of` and converts it back + // into a pinned box, which is safe because ownership is transferred back from the + // kernel. Therefore, the pointer passed to `run` is always valid for the + // duration of the call, and dereferencing it is sound. + unsafe impl WorkItemPointer for Pin> where T: WorkItem, @@ -901,7 +913,20 @@ where } } -// SAFETY: TODO. + // SAFETY: + // + // The implementation of [`RawWorkItem::__enqueue`] for `Pin>` allocates a + // new `Work` and obtains a raw pointer to its embedded `work_struct` via + // [`raw_get_work`](Work::raw_get). It then passes that pointer to the provided + // closure. The `Pin>` is freshly allocated and by type invariants cannot + // already be enqueued, so the closure must return `true`. If it were to return + // `false`, the implementation invokes `unreachable_unchecked()`, which is never + // reached in valid usage. When the closure returns `true` the C workqueue + // subsystem takes ownership of the `work_struct` and will eventually call back + // into [`WorkItemPointer::run`], at which point the box is recovered and + // dropped. Throughout this process the raw pointer passed to the closure + // remains valid for the duration specified in [`RawWorkItem`]'s safety contract. + unsafe impl RawWorkItem for Pin> where T: WorkItem, -- 2.39.5