Skip to content

Commit 07dad44

Browse files
Shankari02ojeda
authored andcommitted
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 <[email protected]> Link: Rust-for-Linux/linux#1173 Signed-off-by: Shankari Anand <[email protected]> Reviewed-by: Benno Lossin <[email protected]> Link: https://lore.kernel.org/r/[email protected] [ Added missing `///`. Changed module title. Reworded slightly. - Miguel ] Signed-off-by: Miguel Ojeda <[email protected]>
1 parent 4e6b5b8 commit 07dad44

File tree

3 files changed

+158
-151
lines changed

3 files changed

+158
-151
lines changed

rust/kernel/sync.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::types::Opaque;
1010
use pin_init;
1111

1212
mod arc;
13+
pub mod aref;
1314
pub mod completion;
1415
mod condvar;
1516
pub mod lock;

rust/kernel/sync/aref.rs

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
//! Internal reference counting support.
4+
5+
use core::{marker::PhantomData, mem::ManuallyDrop, ops::Deref, ptr::NonNull};
6+
7+
/// Types that are _always_ reference counted.
8+
///
9+
/// It allows such types to define their own custom ref increment and decrement functions.
10+
/// Additionally, it allows users to convert from a shared reference `&T` to an owned reference
11+
/// [`ARef<T>`].
12+
///
13+
/// This is usually implemented by wrappers to existing structures on the C side of the code. For
14+
/// Rust code, the recommendation is to use [`Arc`](crate::sync::Arc) to create reference-counted
15+
/// instances of a type.
16+
///
17+
/// # Safety
18+
///
19+
/// Implementers must ensure that increments to the reference count keep the object alive in memory
20+
/// at least until matching decrements are performed.
21+
///
22+
/// Implementers must also ensure that all instances are reference-counted. (Otherwise they
23+
/// won't be able to honour the requirement that [`AlwaysRefCounted::inc_ref`] keep the object
24+
/// alive.)
25+
pub unsafe trait AlwaysRefCounted {
26+
/// Increments the reference count on the object.
27+
fn inc_ref(&self);
28+
29+
/// Decrements the reference count on the object.
30+
///
31+
/// Frees the object when the count reaches zero.
32+
///
33+
/// # Safety
34+
///
35+
/// Callers must ensure that there was a previous matching increment to the reference count,
36+
/// and that the object is no longer used after its reference count is decremented (as it may
37+
/// result in the object being freed), unless the caller owns another increment on the refcount
38+
/// (e.g., it calls [`AlwaysRefCounted::inc_ref`] twice, then calls
39+
/// [`AlwaysRefCounted::dec_ref`] once).
40+
unsafe fn dec_ref(obj: NonNull<Self>);
41+
}
42+
43+
/// An owned reference to an always-reference-counted object.
44+
///
45+
/// The object's reference count is automatically decremented when an instance of [`ARef`] is
46+
/// dropped. It is also automatically incremented when a new instance is created via
47+
/// [`ARef::clone`].
48+
///
49+
/// # Invariants
50+
///
51+
/// The pointer stored in `ptr` is non-null and valid for the lifetime of the [`ARef`] instance. In
52+
/// particular, the [`ARef`] instance owns an increment on the underlying object's reference count.
53+
pub struct ARef<T: AlwaysRefCounted> {
54+
ptr: NonNull<T>,
55+
_p: PhantomData<T>,
56+
}
57+
58+
// SAFETY: It is safe to send `ARef<T>` to another thread when the underlying `T` is `Sync` because
59+
// it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs
60+
// `T` to be `Send` because any thread that has an `ARef<T>` may ultimately access `T` using a
61+
// mutable reference, for example, when the reference count reaches zero and `T` is dropped.
62+
unsafe impl<T: AlwaysRefCounted + Sync + Send> Send for ARef<T> {}
63+
64+
// SAFETY: It is safe to send `&ARef<T>` to another thread when the underlying `T` is `Sync`
65+
// because it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally,
66+
// it needs `T` to be `Send` because any thread that has a `&ARef<T>` may clone it and get an
67+
// `ARef<T>` on that thread, so the thread may ultimately access `T` using a mutable reference, for
68+
// example, when the reference count reaches zero and `T` is dropped.
69+
unsafe impl<T: AlwaysRefCounted + Sync + Send> Sync for ARef<T> {}
70+
71+
impl<T: AlwaysRefCounted> ARef<T> {
72+
/// Creates a new instance of [`ARef`].
73+
///
74+
/// It takes over an increment of the reference count on the underlying object.
75+
///
76+
/// # Safety
77+
///
78+
/// Callers must ensure that the reference count was incremented at least once, and that they
79+
/// are properly relinquishing one increment. That is, if there is only one increment, callers
80+
/// must not use the underlying object anymore -- it is only safe to do so via the newly
81+
/// created [`ARef`].
82+
pub unsafe fn from_raw(ptr: NonNull<T>) -> Self {
83+
// INVARIANT: The safety requirements guarantee that the new instance now owns the
84+
// increment on the refcount.
85+
Self {
86+
ptr,
87+
_p: PhantomData,
88+
}
89+
}
90+
91+
/// Consumes the `ARef`, returning a raw pointer.
92+
///
93+
/// This function does not change the refcount. After calling this function, the caller is
94+
/// responsible for the refcount previously managed by the `ARef`.
95+
///
96+
/// # Examples
97+
///
98+
/// ```
99+
/// use core::ptr::NonNull;
100+
/// use kernel::types::{ARef, AlwaysRefCounted};
101+
///
102+
/// struct Empty {}
103+
///
104+
/// # // SAFETY: TODO.
105+
/// unsafe impl AlwaysRefCounted for Empty {
106+
/// fn inc_ref(&self) {}
107+
/// unsafe fn dec_ref(_obj: NonNull<Self>) {}
108+
/// }
109+
///
110+
/// let mut data = Empty {};
111+
/// let ptr = NonNull::<Empty>::new(&mut data).unwrap();
112+
/// # // SAFETY: TODO.
113+
/// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) };
114+
/// let raw_ptr: NonNull<Empty> = ARef::into_raw(data_ref);
115+
///
116+
/// assert_eq!(ptr, raw_ptr);
117+
/// ```
118+
pub fn into_raw(me: Self) -> NonNull<T> {
119+
ManuallyDrop::new(me).ptr
120+
}
121+
}
122+
123+
impl<T: AlwaysRefCounted> Clone for ARef<T> {
124+
fn clone(&self) -> Self {
125+
self.inc_ref();
126+
// SAFETY: We just incremented the refcount above.
127+
unsafe { Self::from_raw(self.ptr) }
128+
}
129+
}
130+
131+
impl<T: AlwaysRefCounted> Deref for ARef<T> {
132+
type Target = T;
133+
134+
fn deref(&self) -> &Self::Target {
135+
// SAFETY: The type invariants guarantee that the object is valid.
136+
unsafe { self.ptr.as_ref() }
137+
}
138+
}
139+
140+
impl<T: AlwaysRefCounted> From<&T> for ARef<T> {
141+
fn from(b: &T) -> Self {
142+
b.inc_ref();
143+
// SAFETY: We just incremented the refcount above.
144+
unsafe { Self::from_raw(NonNull::from(b)) }
145+
}
146+
}
147+
148+
impl<T: AlwaysRefCounted> Drop for ARef<T> {
149+
fn drop(&mut self) {
150+
// SAFETY: The type invariants guarantee that the `ARef` owns the reference we're about to
151+
// decrement.
152+
unsafe { T::dec_ref(self.ptr) };
153+
}
154+
}

rust/kernel/types.rs

Lines changed: 3 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ use crate::ffi::c_void;
66
use core::{
77
cell::UnsafeCell,
88
marker::{PhantomData, PhantomPinned},
9-
mem::{ManuallyDrop, MaybeUninit},
9+
mem::MaybeUninit,
1010
ops::{Deref, DerefMut},
11-
ptr::NonNull,
1211
};
1312
use pin_init::{PinInit, Zeroable};
1413

14+
pub use crate::sync::aref::{ARef, AlwaysRefCounted};
15+
1516
/// Used to transfer ownership to and from foreign (non-Rust) languages.
1617
///
1718
/// Ownership is transferred from Rust to a foreign language by calling [`Self::into_foreign`] and
@@ -420,155 +421,6 @@ impl<T> Opaque<T> {
420421
}
421422
}
422423

423-
/// Types that are _always_ reference counted.
424-
///
425-
/// It allows such types to define their own custom ref increment and decrement functions.
426-
/// Additionally, it allows users to convert from a shared reference `&T` to an owned reference
427-
/// [`ARef<T>`].
428-
///
429-
/// This is usually implemented by wrappers to existing structures on the C side of the code. For
430-
/// Rust code, the recommendation is to use [`Arc`](crate::sync::Arc) to create reference-counted
431-
/// instances of a type.
432-
///
433-
/// # Safety
434-
///
435-
/// Implementers must ensure that increments to the reference count keep the object alive in memory
436-
/// at least until matching decrements are performed.
437-
///
438-
/// Implementers must also ensure that all instances are reference-counted. (Otherwise they
439-
/// won't be able to honour the requirement that [`AlwaysRefCounted::inc_ref`] keep the object
440-
/// alive.)
441-
pub unsafe trait AlwaysRefCounted {
442-
/// Increments the reference count on the object.
443-
fn inc_ref(&self);
444-
445-
/// Decrements the reference count on the object.
446-
///
447-
/// Frees the object when the count reaches zero.
448-
///
449-
/// # Safety
450-
///
451-
/// Callers must ensure that there was a previous matching increment to the reference count,
452-
/// and that the object is no longer used after its reference count is decremented (as it may
453-
/// result in the object being freed), unless the caller owns another increment on the refcount
454-
/// (e.g., it calls [`AlwaysRefCounted::inc_ref`] twice, then calls
455-
/// [`AlwaysRefCounted::dec_ref`] once).
456-
unsafe fn dec_ref(obj: NonNull<Self>);
457-
}
458-
459-
/// An owned reference to an always-reference-counted object.
460-
///
461-
/// The object's reference count is automatically decremented when an instance of [`ARef`] is
462-
/// dropped. It is also automatically incremented when a new instance is created via
463-
/// [`ARef::clone`].
464-
///
465-
/// # Invariants
466-
///
467-
/// The pointer stored in `ptr` is non-null and valid for the lifetime of the [`ARef`] instance. In
468-
/// particular, the [`ARef`] instance owns an increment on the underlying object's reference count.
469-
pub struct ARef<T: AlwaysRefCounted> {
470-
ptr: NonNull<T>,
471-
_p: PhantomData<T>,
472-
}
473-
474-
// SAFETY: It is safe to send `ARef<T>` to another thread when the underlying `T` is `Sync` because
475-
// it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs
476-
// `T` to be `Send` because any thread that has an `ARef<T>` may ultimately access `T` using a
477-
// mutable reference, for example, when the reference count reaches zero and `T` is dropped.
478-
unsafe impl<T: AlwaysRefCounted + Sync + Send> Send for ARef<T> {}
479-
480-
// SAFETY: It is safe to send `&ARef<T>` to another thread when the underlying `T` is `Sync`
481-
// because it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally,
482-
// it needs `T` to be `Send` because any thread that has a `&ARef<T>` may clone it and get an
483-
// `ARef<T>` on that thread, so the thread may ultimately access `T` using a mutable reference, for
484-
// example, when the reference count reaches zero and `T` is dropped.
485-
unsafe impl<T: AlwaysRefCounted + Sync + Send> Sync for ARef<T> {}
486-
487-
impl<T: AlwaysRefCounted> ARef<T> {
488-
/// Creates a new instance of [`ARef`].
489-
///
490-
/// It takes over an increment of the reference count on the underlying object.
491-
///
492-
/// # Safety
493-
///
494-
/// Callers must ensure that the reference count was incremented at least once, and that they
495-
/// are properly relinquishing one increment. That is, if there is only one increment, callers
496-
/// must not use the underlying object anymore -- it is only safe to do so via the newly
497-
/// created [`ARef`].
498-
pub unsafe fn from_raw(ptr: NonNull<T>) -> Self {
499-
// INVARIANT: The safety requirements guarantee that the new instance now owns the
500-
// increment on the refcount.
501-
Self {
502-
ptr,
503-
_p: PhantomData,
504-
}
505-
}
506-
507-
/// Consumes the `ARef`, returning a raw pointer.
508-
///
509-
/// This function does not change the refcount. After calling this function, the caller is
510-
/// responsible for the refcount previously managed by the `ARef`.
511-
///
512-
/// # Examples
513-
///
514-
/// ```
515-
/// use core::ptr::NonNull;
516-
/// use kernel::types::{ARef, AlwaysRefCounted};
517-
///
518-
/// struct Empty {}
519-
///
520-
/// # // SAFETY: TODO.
521-
/// unsafe impl AlwaysRefCounted for Empty {
522-
/// fn inc_ref(&self) {}
523-
/// unsafe fn dec_ref(_obj: NonNull<Self>) {}
524-
/// }
525-
///
526-
/// let mut data = Empty {};
527-
/// let ptr = NonNull::<Empty>::new(&mut data).unwrap();
528-
/// # // SAFETY: TODO.
529-
/// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) };
530-
/// let raw_ptr: NonNull<Empty> = ARef::into_raw(data_ref);
531-
///
532-
/// assert_eq!(ptr, raw_ptr);
533-
/// ```
534-
pub fn into_raw(me: Self) -> NonNull<T> {
535-
ManuallyDrop::new(me).ptr
536-
}
537-
}
538-
539-
impl<T: AlwaysRefCounted> Clone for ARef<T> {
540-
fn clone(&self) -> Self {
541-
self.inc_ref();
542-
// SAFETY: We just incremented the refcount above.
543-
unsafe { Self::from_raw(self.ptr) }
544-
}
545-
}
546-
547-
impl<T: AlwaysRefCounted> Deref for ARef<T> {
548-
type Target = T;
549-
550-
fn deref(&self) -> &Self::Target {
551-
// SAFETY: The type invariants guarantee that the object is valid.
552-
unsafe { self.ptr.as_ref() }
553-
}
554-
}
555-
556-
impl<T: AlwaysRefCounted> From<&T> for ARef<T> {
557-
fn from(b: &T) -> Self {
558-
b.inc_ref();
559-
// SAFETY: We just incremented the refcount above.
560-
unsafe { Self::from_raw(NonNull::from(b)) }
561-
}
562-
}
563-
564-
impl<T: AlwaysRefCounted> Drop for ARef<T> {
565-
fn drop(&mut self) {
566-
// SAFETY: The type invariants guarantee that the `ARef` owns the reference we're about to
567-
// decrement.
568-
unsafe { T::dec_ref(self.ptr) };
569-
}
570-
}
571-
572424
/// Zero-sized type to mark types not [`Send`].
573425
///
574426
/// Add this type as a field to your struct if your type should not be sent to a different task.

0 commit comments

Comments
 (0)