Skip to content

Commit 1351bab

Browse files
committed
rust: use UnsafePinned in the implementation of Opaque
Make the semantics of the `Opaque` implementation clearer and prepare for the switch to the upstream rust `UnsafePinned` type in the future. `Opaque` still uses `UnsafeCell` even though the kernel implementation of `UnsafePinned` already includes it, since the current upstream version does not. Reviewed-by: Gerald Wisböck <[email protected]> Reviewed-by: Alice Ryhl <[email protected]> Reviewed-by: Benno Lossin <[email protected]> Signed-off-by: Christian Schrefl <[email protected]>
1 parent 6033132 commit 1351bab

File tree

1 file changed

+15
-17
lines changed

1 file changed

+15
-17
lines changed

rust/kernel/types.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
55
use core::{
66
cell::UnsafeCell,
7-
marker::{PhantomData, PhantomPinned},
7+
marker::PhantomData,
88
mem::{ManuallyDrop, MaybeUninit},
99
ops::{Deref, DerefMut},
1010
ptr::NonNull,
1111
};
12-
use pin_init::{PinInit, Wrapper, Zeroable};
12+
use pin_init::{cast_pin_init, PinInit, Wrapper, Zeroable};
1313

1414
/// Used to transfer ownership to and from foreign (non-Rust) languages.
1515
///
@@ -308,8 +308,10 @@ impl<T, F: FnOnce(T)> Drop for ScopeGuard<T, F> {
308308
/// ```
309309
#[repr(transparent)]
310310
pub struct Opaque<T> {
311-
value: UnsafeCell<MaybeUninit<T>>,
312-
_pin: PhantomPinned,
311+
// The kernel implementation of `UnsafePinned` uses `UnsafeCell` internally, but the
312+
// upstream rust `UnsafePinned` will not. So to make sure this is compatible with
313+
// the upstream version use `UnsafeCell` here.
314+
value: UnsafePinned<UnsafeCell<MaybeUninit<T>>>,
313315
}
314316

315317
// SAFETY: `Opaque<T>` allows the inner value to be any bit pattern, including all zeros.
@@ -319,16 +321,14 @@ impl<T> Opaque<T> {
319321
/// Creates a new opaque value.
320322
pub const fn new(value: T) -> Self {
321323
Self {
322-
value: UnsafeCell::new(MaybeUninit::new(value)),
323-
_pin: PhantomPinned,
324+
value: UnsafePinned::new(UnsafeCell::new(MaybeUninit::new(value))),
324325
}
325326
}
326327

327328
/// Creates an uninitialised value.
328329
pub const fn uninit() -> Self {
329330
Self {
330-
value: UnsafeCell::new(MaybeUninit::uninit()),
331-
_pin: PhantomPinned,
331+
value: UnsafePinned::new(UnsafeCell::new(MaybeUninit::uninit())),
332332
}
333333
}
334334

@@ -371,7 +371,7 @@ impl<T> Opaque<T> {
371371

372372
/// Returns a raw pointer to the opaque data.
373373
pub const fn get(&self) -> *mut T {
374-
UnsafeCell::get(&self.value).cast::<T>()
374+
UnsafeCell::raw_get(self.value.get()).cast::<T>()
375375
}
376376

377377
/// Gets the value behind `this`.
@@ -384,14 +384,12 @@ impl<T> Opaque<T> {
384384
}
385385
impl<T> Wrapper<T> for Opaque<T> {
386386
/// Create an opaque pin-initializer from the given pin-initializer.
387-
fn pin_init<E>(slot: impl PinInit<T, E>) -> impl PinInit<Self, E> {
388-
Self::try_ffi_init(|ptr: *mut T| {
389-
// SAFETY:
390-
// - `ptr` is a valid pointer to uninitialized memory,
391-
// - `slot` is not accessed on error; the call is infallible,
392-
// - `slot` is pinned in memory.
393-
unsafe { PinInit::<T, E>::__pinned_init(slot, ptr) }
394-
})
387+
fn pin_init<E>(value_init: impl PinInit<T, E>) -> impl PinInit<Self, E> {
388+
let value_init =
389+
UnsafePinned::pin_init(UnsafeCell::pin_init(MaybeUninit::pin_init(value_init)));
390+
// SAFETY: `Opaque<T>` is a `repr(transparent)` wrapper around
391+
// `UnsafePinned<UnsafeCell<MabeUninit<T>>>` so the memory representation is compatible.
392+
unsafe { cast_pin_init(value_init) }
395393
}
396394
}
397395

0 commit comments

Comments
 (0)