mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 00:28:52 +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; | use pin_init; | ||||||
| 
 | 
 | ||||||
| mod arc; | mod arc; | ||||||
|  | pub mod aref; | ||||||
| pub mod completion; | pub mod completion; | ||||||
| mod condvar; | mod condvar; | ||||||
| pub mod lock; | 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::{ | use core::{ | ||||||
|     cell::UnsafeCell, |     cell::UnsafeCell, | ||||||
|     marker::{PhantomData, PhantomPinned}, |     marker::{PhantomData, PhantomPinned}, | ||||||
|     mem::{ManuallyDrop, MaybeUninit}, |     mem::MaybeUninit, | ||||||
|     ops::{Deref, DerefMut}, |     ops::{Deref, DerefMut}, | ||||||
|     ptr::NonNull, |  | ||||||
| }; | }; | ||||||
| use pin_init::{PinInit, Zeroable}; | use pin_init::{PinInit, Zeroable}; | ||||||
| 
 | 
 | ||||||
|  | pub use crate::sync::aref::{ARef, AlwaysRefCounted}; | ||||||
|  | 
 | ||||||
| /// Used to transfer ownership to and from foreign (non-Rust) languages.
 | /// 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
 | /// 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`].
 | /// 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.
 | /// 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