diff options
Diffstat (limited to 'rust/kernel')
| -rw-r--r-- | rust/kernel/device.rs | 15 | ||||
| -rw-r--r-- | rust/kernel/firmware.rs | 2 | ||||
| -rw-r--r-- | rust/kernel/kunit.rs | 4 | ||||
| -rw-r--r-- | rust/kernel/lib.rs | 2 | ||||
| -rw-r--r-- | rust/kernel/sync/locked_by.rs | 18 | 
5 files changed, 21 insertions, 20 deletions
| diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs index 851018eef885..c8199ee079ef 100644 --- a/rust/kernel/device.rs +++ b/rust/kernel/device.rs @@ -51,18 +51,9 @@ impl Device {      ///      /// It must also be ensured that `bindings::device::release` can be called from any thread.      /// While not officially documented, this should be the case for any `struct device`. -    pub unsafe fn from_raw(ptr: *mut bindings::device) -> ARef<Self> { -        // SAFETY: By the safety requirements, ptr is valid. -        // Initially increase the reference count by one to compensate for the final decrement once -        // this newly created `ARef<Device>` instance is dropped. -        unsafe { bindings::get_device(ptr) }; - -        // CAST: `Self` is a `repr(transparent)` wrapper around `bindings::device`. -        let ptr = ptr.cast::<Self>(); - -        // SAFETY: `ptr` is valid by the safety requirements of this function. By the above call to -        // `bindings::get_device` we also own a reference to the underlying `struct device`. -        unsafe { ARef::from_raw(ptr::NonNull::new_unchecked(ptr)) } +    pub unsafe fn get_device(ptr: *mut bindings::device) -> ARef<Self> { +        // SAFETY: By the safety requirements ptr is valid +        unsafe { Self::as_ref(ptr) }.into()      }      /// Obtain the raw `struct device *`. diff --git a/rust/kernel/firmware.rs b/rust/kernel/firmware.rs index dee5b4b18aec..13a374a5cdb7 100644 --- a/rust/kernel/firmware.rs +++ b/rust/kernel/firmware.rs @@ -44,7 +44,7 @@ impl FwFunc {  ///  /// # fn no_run() -> Result<(), Error> {  /// # // SAFETY: *NOT* safe, just for the example to get an `ARef<Device>` instance -/// # let dev = unsafe { Device::from_raw(core::ptr::null_mut()) }; +/// # let dev = unsafe { Device::get_device(core::ptr::null_mut()) };  ///  /// let fw = Firmware::request(c_str!("path/to/firmware.bin"), &dev)?;  /// let blob = fw.data(); diff --git a/rust/kernel/kunit.rs b/rust/kernel/kunit.rs index 0ba77276ae7e..824da0e9738a 100644 --- a/rust/kernel/kunit.rs +++ b/rust/kernel/kunit.rs @@ -18,7 +18,7 @@ pub fn err(args: fmt::Arguments<'_>) {      #[cfg(CONFIG_PRINTK)]      unsafe {          bindings::_printk( -            b"\x013%pA\0".as_ptr() as _, +            c"\x013%pA".as_ptr() as _,              &args as *const _ as *const c_void,          );      } @@ -34,7 +34,7 @@ pub fn info(args: fmt::Arguments<'_>) {      #[cfg(CONFIG_PRINTK)]      unsafe {          bindings::_printk( -            b"\x016%pA\0".as_ptr() as _, +            c"\x016%pA".as_ptr() as _,              &args as *const _ as *const c_void,          );      } diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 22a3bfa5a9e9..b5f4b3ce6b48 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -44,8 +44,8 @@ pub mod net;  pub mod page;  pub mod prelude;  pub mod print; -pub mod sizes;  pub mod rbtree; +pub mod sizes;  mod static_assert;  #[doc(hidden)]  pub mod std_vendor; diff --git a/rust/kernel/sync/locked_by.rs b/rust/kernel/sync/locked_by.rs index babc731bd5f6..ce2ee8d87865 100644 --- a/rust/kernel/sync/locked_by.rs +++ b/rust/kernel/sync/locked_by.rs @@ -83,8 +83,12 @@ pub struct LockedBy<T: ?Sized, U: ?Sized> {  // SAFETY: `LockedBy` can be transferred across thread boundaries iff the data it protects can.  unsafe impl<T: ?Sized + Send, U: ?Sized> Send for LockedBy<T, U> {} -// SAFETY: `LockedBy` serialises the interior mutability it provides, so it is `Sync` as long as the -// data it protects is `Send`. +// SAFETY: If `T` is not `Sync`, then parallel shared access to this `LockedBy` allows you to use +// `access_mut` to hand out `&mut T` on one thread at the time. The requirement that `T: Send` is +// sufficient to allow that. +// +// If `T` is `Sync`, then the `access` method also becomes available, which allows you to obtain +// several `&T` from several threads at once. However, this is okay as `T` is `Sync`.  unsafe impl<T: ?Sized + Send, U: ?Sized> Sync for LockedBy<T, U> {}  impl<T, U> LockedBy<T, U> { @@ -118,7 +122,10 @@ impl<T: ?Sized, U> LockedBy<T, U> {      ///      /// Panics if `owner` is different from the data protected by the lock used in      /// [`new`](LockedBy::new). -    pub fn access<'a>(&'a self, owner: &'a U) -> &'a T { +    pub fn access<'a>(&'a self, owner: &'a U) -> &'a T +    where +        T: Sync, +    {          build_assert!(              size_of::<U>() > 0,              "`U` cannot be a ZST because `owner` wouldn't be unique" @@ -127,7 +134,10 @@ impl<T: ?Sized, U> LockedBy<T, U> {              panic!("mismatched owners");          } -        // SAFETY: `owner` is evidence that the owner is locked. +        // SAFETY: `owner` is evidence that there are only shared references to the owner for the +        // duration of 'a, so it's not possible to use `Self::access_mut` to obtain a mutable +        // reference to the inner value that aliases with this shared reference. The type is `Sync` +        // so there are no other requirements.          unsafe { &*self.data.get() }      } | 
