Skip to content

Commit

Permalink
rust: add safety comment in workqueue traits
Browse files Browse the repository at this point in the history
Add missing safety comments for the implementation of the unsafe traits
WorkItemPointer and RawWorkItem for Arc<T> in workqueue.rs

Link: Rust-for-Linux#351.
Co-developed-by: Vangelis Mamalakis <mamalakis@google.com>
Signed-off-by: Vangelis Mamalakis <mamalakis@google.com>
Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Konstantin Andrikopoulos <kernel@mandragore.io>
Signed-off-by: Tejun Heo <tj@kernel.org>
  • Loading branch information
Konstantin Andrikopoulos authored and jhanger-dev committed Jan 20, 2025
1 parent e6d4870 commit a71cbe5
Showing 1 changed file with 16 additions and 2 deletions.
18 changes: 16 additions & 2 deletions rust/kernel/workqueue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,15 @@ impl_has_work! {
impl{T} HasWork<Self> for ClosureWork<T> { self.work }
}

// SAFETY: TODO.
// SAFETY: The `__enqueue` implementation in RawWorkItem uses a `work_struct` initialized with the
// `run` method of this trait as the function pointer because:
// - `__enqueue` gets the `work_struct` from the `Work` field, using `T::raw_get_work`.
// - The only safe way to create a `Work` object is through `Work::new`.
// - `Work::new` makes sure that `T::Pointer::run` is passed to `init_work_with_key`.
// - Finally `Work` and `RawWorkItem` guarantee that the correct `Work` field
// will be used because of the ID const generic bound. This makes sure that `T::raw_get_work`
// uses the correct offset for the `Work` field, and `Work::new` picks the correct
// implementation of `WorkItemPointer` for `Arc<T>`.
unsafe impl<T, const ID: u64> WorkItemPointer<ID> for Arc<T>
where
T: WorkItem<ID, Pointer = Self>,
Expand All @@ -537,7 +545,13 @@ where
}
}

// SAFETY: TODO.
// SAFETY: The `work_struct` raw pointer is guaranteed to be valid for the duration of the call to
// the closure because we get it from an `Arc`, which means that the ref count will be at least 1,
// and we don't drop the `Arc` ourselves. If `queue_work_on` returns true, it is further guaranteed
// to be valid until a call to the function pointer in `work_struct` because we leak the memory it
// points to, and only reclaim it if the closure returns false, or in `WorkItemPointer::run`, which
// is what the function pointer in the `work_struct` must be pointing to, according to the safety
// requirements of `WorkItemPointer`.
unsafe impl<T, const ID: u64> RawWorkItem<ID> for Arc<T>
where
T: WorkItem<ID, Pointer = Self>,
Expand Down

0 comments on commit a71cbe5

Please sign in to comment.