From: Dirk Behme Date: Wed, 2 Oct 2024 05:03:01 +0000 (+0200) Subject: rust: types: extend `Opaque` documentation X-Git-Tag: v6.13-rc1~71^2~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=718c4069896cabba5c39b637cbb7205927f16ae0;p=thirdparty%2Fkernel%2Flinux.git rust: types: extend `Opaque` documentation Update the `Opaque` documentation and add an example as proposed by Miguel Ojeda in [1]. The documentation update is mainly taken from Benno Lossin's description [2]. Cc: Nell Shamrell-Harrington Suggested-by: Miguel Ojeda Link: https://rust-for-linux.zulipchat.com/#narrow/stream/291565/topic/x/near/467478085 [1] Link: https://rust-for-linux.zulipchat.com/#narrow/stream/291565/topic/x/near/470498289 [2] Co-developed-by: Benno Lossin Signed-off-by: Benno Lossin Signed-off-by: Dirk Behme Link: https://lore.kernel.org/r/20241002050301.1927545-1-dirk.behme@de.bosch.com [ Used `expect`. Rewrapped docs. Added intra-doc link. Formatted example. Reworded to fix tag typo/order. Fixed `&mut` formatting as discussed. Added Benno's SOB and CDB as discussed. Shortened links. - Miguel ] Signed-off-by: Miguel Ojeda --- diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index ced143600eb1b..fae80814fa1c5 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -206,7 +206,58 @@ impl Drop for ScopeGuard { /// Stores an opaque value. /// -/// This is meant to be used with FFI objects that are never interpreted by Rust code. +/// `Opaque` is meant to be used with FFI objects that are never interpreted by Rust code. +/// +/// It is used to wrap structs from the C side, like for example `Opaque`. +/// It gets rid of all the usual assumptions that Rust has for a value: +/// +/// * The value is allowed to be uninitialized (for example have invalid bit patterns: `3` for a +/// [`bool`]). +/// * The value is allowed to be mutated, when a `&Opaque` exists on the Rust side. +/// * No uniqueness for mutable references: it is fine to have multiple `&mut Opaque` point to +/// the same value. +/// * The value is not allowed to be shared with other threads (i.e. it is `!Sync`). +/// +/// This has to be used for all values that the C side has access to, because it can't be ensured +/// that the C side is adhering to the usual constraints that Rust needs. +/// +/// Using `Opaque` allows to continue to use references on the Rust side even for values shared +/// with C. +/// +/// # Examples +/// +/// ``` +/// # #![expect(unreachable_pub, clippy::disallowed_names)] +/// use kernel::types::Opaque; +/// # // Emulate a C struct binding which is from C, maybe uninitialized or not, only the C side +/// # // knows. +/// # mod bindings { +/// # pub struct Foo { +/// # pub val: u8, +/// # } +/// # } +/// +/// // `foo.val` is assumed to be handled on the C side, so we use `Opaque` to wrap it. +/// pub struct Foo { +/// foo: Opaque, +/// } +/// +/// impl Foo { +/// pub fn get_val(&self) -> u8 { +/// let ptr = Opaque::get(&self.foo); +/// +/// // SAFETY: `Self` is valid from C side. +/// unsafe { (*ptr).val } +/// } +/// } +/// +/// // Create an instance of `Foo` with the `Opaque` wrapper. +/// let foo = Foo { +/// foo: Opaque::new(bindings::Foo { val: 0xdb }), +/// }; +/// +/// assert_eq!(foo.get_val(), 0xdb); +/// ``` #[repr(transparent)] pub struct Opaque { value: UnsafeCell>,