Skip to content

Commit 1ce98bb

Browse files
tamirdojeda
authored andcommitted
rust: workqueue: remove HasWork::OFFSET
Implement `HasWork::work_container_of` in `impl_has_work!`, narrowing the interface of `HasWork` and replacing pointer arithmetic with `container_of!`. Remove the provided implementation of `HasWork::get_work_offset` without replacement; an implementation is already generated in `impl_has_work!`. Remove the `Self: Sized` bound on `HasWork::work_container_of` which was apparently necessary to access `OFFSET` as `OFFSET` no longer exists. A similar API change was discussed on the hrtimer series[1]. Link: https://lore.kernel.org/all/[email protected]/ [1] Reviewed-by: Benno Lossin <[email protected]> Reviewed-by: Alice Ryhl <[email protected]> Tested-by: Alice Ryhl <[email protected]> Reviewed-by: Andreas Hindborg <[email protected]> Signed-off-by: Tamir Duberstein <[email protected]> Acked-by: Tejun Heo <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Miguel Ojeda <[email protected]>
1 parent 74d6a60 commit 1ce98bb

File tree

1 file changed

+17
-33
lines changed

1 file changed

+17
-33
lines changed

rust/kernel/workqueue.rs

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -429,51 +429,28 @@ impl<T: ?Sized, const ID: u64> Work<T, ID> {
429429
///
430430
/// # Safety
431431
///
432-
/// The [`OFFSET`] constant must be the offset of a field in `Self` of type [`Work<T, ID>`]. The
433-
/// methods on this trait must have exactly the behavior that the definitions given below have.
432+
/// The methods [`raw_get_work`] and [`work_container_of`] must return valid pointers and must be
433+
/// true inverses of each other; that is, they must satisfy the following invariants:
434+
/// - `work_container_of(raw_get_work(ptr)) == ptr` for any `ptr: *mut Self`.
435+
/// - `raw_get_work(work_container_of(ptr)) == ptr` for any `ptr: *mut Work<T, ID>`.
434436
///
435437
/// [`impl_has_work!`]: crate::impl_has_work
436-
/// [`OFFSET`]: HasWork::OFFSET
438+
/// [`raw_get_work`]: HasWork::raw_get_work
439+
/// [`work_container_of`]: HasWork::work_container_of
437440
pub unsafe trait HasWork<T, const ID: u64 = 0> {
438-
/// The offset of the [`Work<T, ID>`] field.
439-
const OFFSET: usize;
440-
441-
/// Returns the offset of the [`Work<T, ID>`] field.
442-
///
443-
/// This method exists because the [`OFFSET`] constant cannot be accessed if the type is not
444-
/// [`Sized`].
445-
///
446-
/// [`OFFSET`]: HasWork::OFFSET
447-
#[inline]
448-
fn get_work_offset(&self) -> usize {
449-
Self::OFFSET
450-
}
451-
452441
/// Returns a pointer to the [`Work<T, ID>`] field.
453442
///
454443
/// # Safety
455444
///
456445
/// The provided pointer must point at a valid struct of type `Self`.
457-
#[inline]
458-
unsafe fn raw_get_work(ptr: *mut Self) -> *mut Work<T, ID> {
459-
// SAFETY: The caller promises that the pointer is valid.
460-
unsafe { (ptr as *mut u8).add(Self::OFFSET) as *mut Work<T, ID> }
461-
}
446+
unsafe fn raw_get_work(ptr: *mut Self) -> *mut Work<T, ID>;
462447

463448
/// Returns a pointer to the struct containing the [`Work<T, ID>`] field.
464449
///
465450
/// # Safety
466451
///
467452
/// The pointer must point at a [`Work<T, ID>`] field in a struct of type `Self`.
468-
#[inline]
469-
unsafe fn work_container_of(ptr: *mut Work<T, ID>) -> *mut Self
470-
where
471-
Self: Sized,
472-
{
473-
// SAFETY: The caller promises that the pointer points at a field of the right type in the
474-
// right kind of struct.
475-
unsafe { (ptr as *mut u8).sub(Self::OFFSET) as *mut Self }
476-
}
453+
unsafe fn work_container_of(ptr: *mut Work<T, ID>) -> *mut Self;
477454
}
478455

479456
/// Used to safely implement the [`HasWork<T, ID>`] trait.
@@ -504,15 +481,22 @@ macro_rules! impl_has_work {
504481
// SAFETY: The implementation of `raw_get_work` only compiles if the field has the right
505482
// type.
506483
unsafe impl$(<$($generics)+>)? $crate::workqueue::HasWork<$work_type $(, $id)?> for $self {
507-
const OFFSET: usize = ::core::mem::offset_of!(Self, $field) as usize;
508-
509484
#[inline]
510485
unsafe fn raw_get_work(ptr: *mut Self) -> *mut $crate::workqueue::Work<$work_type $(, $id)?> {
511486
// SAFETY: The caller promises that the pointer is not dangling.
512487
unsafe {
513488
::core::ptr::addr_of_mut!((*ptr).$field)
514489
}
515490
}
491+
492+
#[inline]
493+
unsafe fn work_container_of(
494+
ptr: *mut $crate::workqueue::Work<$work_type $(, $id)?>,
495+
) -> *mut Self {
496+
// SAFETY: The caller promises that the pointer points at a field of the right type
497+
// in the right kind of struct.
498+
unsafe { $crate::container_of!(ptr, Self, $field) }
499+
}
516500
}
517501
)*};
518502
}

0 commit comments

Comments
 (0)