mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-01 00:58:39 +02:00 
			
		
		
		
	rust: kernel: move ARef and AlwaysRefCounted to sync::aref
Move the definitions of `ARef` and `AlwaysRefCounted` from `types.rs` to a new file `sync/aref.rs`. Define the corresponding `aref` module under `rust/kernel/sync.rs`. These types are better grouped in `sync`. To avoid breaking existing imports, they are re-exported from `types.rs`. Drop unused imports `mem::ManuallyDrop`, `ptr::NonNull` from `types.rs`, they are now only used in `sync/aref.rs`, where they are already imported. Suggested-by: Benno Lossin <lossin@kernel.org> Link: https://github.com/Rust-for-Linux/linux/issues/1173 Signed-off-by: Shankari Anand <shankari.ak0208@gmail.com> Reviewed-by: Benno Lossin <lossin@kernel.org> Link: https://lore.kernel.org/r/20250715110423.334744-1-shankari.ak0208@gmail.com [ Added missing `///`. Changed module title. Reworded slightly. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
		
							parent
							
								
									4e6b5b8ab3
								
							
						
					
					
						commit
						07dad44aa9
					
				
					 3 changed files with 158 additions and 151 deletions
				
			
		|  | @ -10,6 +10,7 @@ | |||
| use pin_init; | ||||
| 
 | ||||
| mod arc; | ||||
| pub mod aref; | ||||
| pub mod completion; | ||||
| mod condvar; | ||||
| pub mod lock; | ||||
|  |  | |||
							
								
								
									
										154
									
								
								rust/kernel/sync/aref.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								rust/kernel/sync/aref.rs
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,154 @@ | |||
| // SPDX-License-Identifier: GPL-2.0
 | ||||
| 
 | ||||
| //! Internal reference counting support.
 | ||||
| 
 | ||||
| use core::{marker::PhantomData, mem::ManuallyDrop, ops::Deref, ptr::NonNull}; | ||||
| 
 | ||||
| /// Types that are _always_ reference counted.
 | ||||
| ///
 | ||||
| /// It allows such types to define their own custom ref increment and decrement functions.
 | ||||
| /// Additionally, it allows users to convert from a shared reference `&T` to an owned reference
 | ||||
| /// [`ARef<T>`].
 | ||||
| ///
 | ||||
| /// This is usually implemented by wrappers to existing structures on the C side of the code. For
 | ||||
| /// Rust code, the recommendation is to use [`Arc`](crate::sync::Arc) to create reference-counted
 | ||||
| /// instances of a type.
 | ||||
| ///
 | ||||
| /// # Safety
 | ||||
| ///
 | ||||
| /// Implementers must ensure that increments to the reference count keep the object alive in memory
 | ||||
| /// at least until matching decrements are performed.
 | ||||
| ///
 | ||||
| /// Implementers must also ensure that all instances are reference-counted. (Otherwise they
 | ||||
| /// won't be able to honour the requirement that [`AlwaysRefCounted::inc_ref`] keep the object
 | ||||
| /// alive.)
 | ||||
| pub unsafe trait AlwaysRefCounted { | ||||
|     /// Increments the reference count on the object.
 | ||||
|     fn inc_ref(&self); | ||||
| 
 | ||||
|     /// Decrements the reference count on the object.
 | ||||
|     ///
 | ||||
|     /// Frees the object when the count reaches zero.
 | ||||
|     ///
 | ||||
|     /// # Safety
 | ||||
|     ///
 | ||||
|     /// Callers must ensure that there was a previous matching increment to the reference count,
 | ||||
|     /// and that the object is no longer used after its reference count is decremented (as it may
 | ||||
|     /// result in the object being freed), unless the caller owns another increment on the refcount
 | ||||
|     /// (e.g., it calls [`AlwaysRefCounted::inc_ref`] twice, then calls
 | ||||
|     /// [`AlwaysRefCounted::dec_ref`] once).
 | ||||
|     unsafe fn dec_ref(obj: NonNull<Self>); | ||||
| } | ||||
| 
 | ||||
| /// An owned reference to an always-reference-counted object.
 | ||||
| ///
 | ||||
| /// The object's reference count is automatically decremented when an instance of [`ARef`] is
 | ||||
| /// dropped. It is also automatically incremented when a new instance is created via
 | ||||
| /// [`ARef::clone`].
 | ||||
| ///
 | ||||
| /// # Invariants
 | ||||
| ///
 | ||||
| /// The pointer stored in `ptr` is non-null and valid for the lifetime of the [`ARef`] instance. In
 | ||||
| /// particular, the [`ARef`] instance owns an increment on the underlying object's reference count.
 | ||||
| pub struct ARef<T: AlwaysRefCounted> { | ||||
|     ptr: NonNull<T>, | ||||
|     _p: PhantomData<T>, | ||||
| } | ||||
| 
 | ||||
| // SAFETY: It is safe to send `ARef<T>` to another thread when the underlying `T` is `Sync` because
 | ||||
| // it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs
 | ||||
| // `T` to be `Send` because any thread that has an `ARef<T>` may ultimately access `T` using a
 | ||||
| // mutable reference, for example, when the reference count reaches zero and `T` is dropped.
 | ||||
| unsafe impl<T: AlwaysRefCounted + Sync + Send> Send for ARef<T> {} | ||||
| 
 | ||||
| // SAFETY: It is safe to send `&ARef<T>` to another thread when the underlying `T` is `Sync`
 | ||||
| // because it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally,
 | ||||
| // it needs `T` to be `Send` because any thread that has a `&ARef<T>` may clone it and get an
 | ||||
| // `ARef<T>` on that thread, so the thread may ultimately access `T` using a mutable reference, for
 | ||||
| // example, when the reference count reaches zero and `T` is dropped.
 | ||||
| unsafe impl<T: AlwaysRefCounted + Sync + Send> Sync for ARef<T> {} | ||||
| 
 | ||||
| impl<T: AlwaysRefCounted> ARef<T> { | ||||
|     /// Creates a new instance of [`ARef`].
 | ||||
|     ///
 | ||||
|     /// It takes over an increment of the reference count on the underlying object.
 | ||||
|     ///
 | ||||
|     /// # Safety
 | ||||
|     ///
 | ||||
|     /// Callers must ensure that the reference count was incremented at least once, and that they
 | ||||
|     /// are properly relinquishing one increment. That is, if there is only one increment, callers
 | ||||
|     /// must not use the underlying object anymore -- it is only safe to do so via the newly
 | ||||
|     /// created [`ARef`].
 | ||||
|     pub unsafe fn from_raw(ptr: NonNull<T>) -> Self { | ||||
|         // INVARIANT: The safety requirements guarantee that the new instance now owns the
 | ||||
|         // increment on the refcount.
 | ||||
|         Self { | ||||
|             ptr, | ||||
|             _p: PhantomData, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Consumes the `ARef`, returning a raw pointer.
 | ||||
|     ///
 | ||||
|     /// This function does not change the refcount. After calling this function, the caller is
 | ||||
|     /// responsible for the refcount previously managed by the `ARef`.
 | ||||
|     ///
 | ||||
|     /// # Examples
 | ||||
|     ///
 | ||||
|     /// ```
 | ||||
|     /// use core::ptr::NonNull;
 | ||||
|     /// use kernel::types::{ARef, AlwaysRefCounted};
 | ||||
|     ///
 | ||||
|     /// struct Empty {}
 | ||||
|     ///
 | ||||
|     /// # // SAFETY: TODO.
 | ||||
|     /// unsafe impl AlwaysRefCounted for Empty {
 | ||||
|     ///     fn inc_ref(&self) {}
 | ||||
|     ///     unsafe fn dec_ref(_obj: NonNull<Self>) {}
 | ||||
|     /// }
 | ||||
|     ///
 | ||||
|     /// let mut data = Empty {};
 | ||||
|     /// let ptr = NonNull::<Empty>::new(&mut data).unwrap();
 | ||||
|     /// # // SAFETY: TODO.
 | ||||
|     /// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) };
 | ||||
|     /// let raw_ptr: NonNull<Empty> = ARef::into_raw(data_ref);
 | ||||
|     ///
 | ||||
|     /// assert_eq!(ptr, raw_ptr);
 | ||||
|     /// ```
 | ||||
|     pub fn into_raw(me: Self) -> NonNull<T> { | ||||
|         ManuallyDrop::new(me).ptr | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<T: AlwaysRefCounted> Clone for ARef<T> { | ||||
|     fn clone(&self) -> Self { | ||||
|         self.inc_ref(); | ||||
|         // SAFETY: We just incremented the refcount above.
 | ||||
|         unsafe { Self::from_raw(self.ptr) } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<T: AlwaysRefCounted> Deref for ARef<T> { | ||||
|     type Target = T; | ||||
| 
 | ||||
|     fn deref(&self) -> &Self::Target { | ||||
|         // SAFETY: The type invariants guarantee that the object is valid.
 | ||||
|         unsafe { self.ptr.as_ref() } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<T: AlwaysRefCounted> From<&T> for ARef<T> { | ||||
|     fn from(b: &T) -> Self { | ||||
|         b.inc_ref(); | ||||
|         // SAFETY: We just incremented the refcount above.
 | ||||
|         unsafe { Self::from_raw(NonNull::from(b)) } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<T: AlwaysRefCounted> Drop for ARef<T> { | ||||
|     fn drop(&mut self) { | ||||
|         // SAFETY: The type invariants guarantee that the `ARef` owns the reference we're about to
 | ||||
|         // decrement.
 | ||||
|         unsafe { T::dec_ref(self.ptr) }; | ||||
|     } | ||||
| } | ||||
|  | @ -6,12 +6,13 @@ | |||
| use core::{ | ||||
|     cell::UnsafeCell, | ||||
|     marker::{PhantomData, PhantomPinned}, | ||||
|     mem::{ManuallyDrop, MaybeUninit}, | ||||
|     mem::MaybeUninit, | ||||
|     ops::{Deref, DerefMut}, | ||||
|     ptr::NonNull, | ||||
| }; | ||||
| use pin_init::{PinInit, Zeroable}; | ||||
| 
 | ||||
| pub use crate::sync::aref::{ARef, AlwaysRefCounted}; | ||||
| 
 | ||||
| /// Used to transfer ownership to and from foreign (non-Rust) languages.
 | ||||
| ///
 | ||||
| /// Ownership is transferred from Rust to a foreign language by calling [`Self::into_foreign`] and
 | ||||
|  | @ -420,155 +421,6 @@ pub const fn cast_from(this: *const T) -> *const Self { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Types that are _always_ reference counted.
 | ||||
| ///
 | ||||
| /// It allows such types to define their own custom ref increment and decrement functions.
 | ||||
| /// Additionally, it allows users to convert from a shared reference `&T` to an owned reference
 | ||||
| /// [`ARef<T>`].
 | ||||
| ///
 | ||||
| /// This is usually implemented by wrappers to existing structures on the C side of the code. For
 | ||||
| /// Rust code, the recommendation is to use [`Arc`](crate::sync::Arc) to create reference-counted
 | ||||
| /// instances of a type.
 | ||||
| ///
 | ||||
| /// # Safety
 | ||||
| ///
 | ||||
| /// Implementers must ensure that increments to the reference count keep the object alive in memory
 | ||||
| /// at least until matching decrements are performed.
 | ||||
| ///
 | ||||
| /// Implementers must also ensure that all instances are reference-counted. (Otherwise they
 | ||||
| /// won't be able to honour the requirement that [`AlwaysRefCounted::inc_ref`] keep the object
 | ||||
| /// alive.)
 | ||||
| pub unsafe trait AlwaysRefCounted { | ||||
|     /// Increments the reference count on the object.
 | ||||
|     fn inc_ref(&self); | ||||
| 
 | ||||
|     /// Decrements the reference count on the object.
 | ||||
|     ///
 | ||||
|     /// Frees the object when the count reaches zero.
 | ||||
|     ///
 | ||||
|     /// # Safety
 | ||||
|     ///
 | ||||
|     /// Callers must ensure that there was a previous matching increment to the reference count,
 | ||||
|     /// and that the object is no longer used after its reference count is decremented (as it may
 | ||||
|     /// result in the object being freed), unless the caller owns another increment on the refcount
 | ||||
|     /// (e.g., it calls [`AlwaysRefCounted::inc_ref`] twice, then calls
 | ||||
|     /// [`AlwaysRefCounted::dec_ref`] once).
 | ||||
|     unsafe fn dec_ref(obj: NonNull<Self>); | ||||
| } | ||||
| 
 | ||||
| /// An owned reference to an always-reference-counted object.
 | ||||
| ///
 | ||||
| /// The object's reference count is automatically decremented when an instance of [`ARef`] is
 | ||||
| /// dropped. It is also automatically incremented when a new instance is created via
 | ||||
| /// [`ARef::clone`].
 | ||||
| ///
 | ||||
| /// # Invariants
 | ||||
| ///
 | ||||
| /// The pointer stored in `ptr` is non-null and valid for the lifetime of the [`ARef`] instance. In
 | ||||
| /// particular, the [`ARef`] instance owns an increment on the underlying object's reference count.
 | ||||
| pub struct ARef<T: AlwaysRefCounted> { | ||||
|     ptr: NonNull<T>, | ||||
|     _p: PhantomData<T>, | ||||
| } | ||||
| 
 | ||||
| // SAFETY: It is safe to send `ARef<T>` to another thread when the underlying `T` is `Sync` because
 | ||||
| // it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs
 | ||||
| // `T` to be `Send` because any thread that has an `ARef<T>` may ultimately access `T` using a
 | ||||
| // mutable reference, for example, when the reference count reaches zero and `T` is dropped.
 | ||||
| unsafe impl<T: AlwaysRefCounted + Sync + Send> Send for ARef<T> {} | ||||
| 
 | ||||
| // SAFETY: It is safe to send `&ARef<T>` to another thread when the underlying `T` is `Sync`
 | ||||
| // because it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally,
 | ||||
| // it needs `T` to be `Send` because any thread that has a `&ARef<T>` may clone it and get an
 | ||||
| // `ARef<T>` on that thread, so the thread may ultimately access `T` using a mutable reference, for
 | ||||
| // example, when the reference count reaches zero and `T` is dropped.
 | ||||
| unsafe impl<T: AlwaysRefCounted + Sync + Send> Sync for ARef<T> {} | ||||
| 
 | ||||
| impl<T: AlwaysRefCounted> ARef<T> { | ||||
|     /// Creates a new instance of [`ARef`].
 | ||||
|     ///
 | ||||
|     /// It takes over an increment of the reference count on the underlying object.
 | ||||
|     ///
 | ||||
|     /// # Safety
 | ||||
|     ///
 | ||||
|     /// Callers must ensure that the reference count was incremented at least once, and that they
 | ||||
|     /// are properly relinquishing one increment. That is, if there is only one increment, callers
 | ||||
|     /// must not use the underlying object anymore -- it is only safe to do so via the newly
 | ||||
|     /// created [`ARef`].
 | ||||
|     pub unsafe fn from_raw(ptr: NonNull<T>) -> Self { | ||||
|         // INVARIANT: The safety requirements guarantee that the new instance now owns the
 | ||||
|         // increment on the refcount.
 | ||||
|         Self { | ||||
|             ptr, | ||||
|             _p: PhantomData, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Consumes the `ARef`, returning a raw pointer.
 | ||||
|     ///
 | ||||
|     /// This function does not change the refcount. After calling this function, the caller is
 | ||||
|     /// responsible for the refcount previously managed by the `ARef`.
 | ||||
|     ///
 | ||||
|     /// # Examples
 | ||||
|     ///
 | ||||
|     /// ```
 | ||||
|     /// use core::ptr::NonNull;
 | ||||
|     /// use kernel::types::{ARef, AlwaysRefCounted};
 | ||||
|     ///
 | ||||
|     /// struct Empty {}
 | ||||
|     ///
 | ||||
|     /// # // SAFETY: TODO.
 | ||||
|     /// unsafe impl AlwaysRefCounted for Empty {
 | ||||
|     ///     fn inc_ref(&self) {}
 | ||||
|     ///     unsafe fn dec_ref(_obj: NonNull<Self>) {}
 | ||||
|     /// }
 | ||||
|     ///
 | ||||
|     /// let mut data = Empty {};
 | ||||
|     /// let ptr = NonNull::<Empty>::new(&mut data).unwrap();
 | ||||
|     /// # // SAFETY: TODO.
 | ||||
|     /// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) };
 | ||||
|     /// let raw_ptr: NonNull<Empty> = ARef::into_raw(data_ref);
 | ||||
|     ///
 | ||||
|     /// assert_eq!(ptr, raw_ptr);
 | ||||
|     /// ```
 | ||||
|     pub fn into_raw(me: Self) -> NonNull<T> { | ||||
|         ManuallyDrop::new(me).ptr | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<T: AlwaysRefCounted> Clone for ARef<T> { | ||||
|     fn clone(&self) -> Self { | ||||
|         self.inc_ref(); | ||||
|         // SAFETY: We just incremented the refcount above.
 | ||||
|         unsafe { Self::from_raw(self.ptr) } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<T: AlwaysRefCounted> Deref for ARef<T> { | ||||
|     type Target = T; | ||||
| 
 | ||||
|     fn deref(&self) -> &Self::Target { | ||||
|         // SAFETY: The type invariants guarantee that the object is valid.
 | ||||
|         unsafe { self.ptr.as_ref() } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<T: AlwaysRefCounted> From<&T> for ARef<T> { | ||||
|     fn from(b: &T) -> Self { | ||||
|         b.inc_ref(); | ||||
|         // SAFETY: We just incremented the refcount above.
 | ||||
|         unsafe { Self::from_raw(NonNull::from(b)) } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<T: AlwaysRefCounted> Drop for ARef<T> { | ||||
|     fn drop(&mut self) { | ||||
|         // SAFETY: The type invariants guarantee that the `ARef` owns the reference we're about to
 | ||||
|         // decrement.
 | ||||
|         unsafe { T::dec_ref(self.ptr) }; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Zero-sized type to mark types not [`Send`].
 | ||||
| ///
 | ||||
| /// Add this type as a field to your struct if your type should not be sent to a different task.
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Shankari Anand
						Shankari Anand