aboutsummaryrefslogtreecommitdiffstats
path: root/rust/kernel/sync/refcount.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/kernel/sync/refcount.rs')
-rw-r--r--rust/kernel/sync/refcount.rs15
1 files changed, 15 insertions, 0 deletions
diff --git a/rust/kernel/sync/refcount.rs b/rust/kernel/sync/refcount.rs
index cc1a80ae7ae9..19236a5bccde 100644
--- a/rust/kernel/sync/refcount.rs
+++ b/rust/kernel/sync/refcount.rs
@@ -5,6 +5,7 @@
//! C header: [`include/linux/refcount.h`](srctree/include/linux/refcount.h)
use crate::build_assert;
+use crate::sync::atomic::Atomic;
use crate::types::Opaque;
/// Atomic reference counter.
@@ -34,6 +35,20 @@ impl Refcount {
self.0.get()
}
+ /// Get the underlying atomic counter that backs the refcount.
+ ///
+ /// NOTE: Usage of this function is discouraged as it can circumvent the protections offered by
+ /// `refcount.h`. If there is no way to achieve the result using APIs in `refcount.h`, then
+ /// this function can be used. Otherwise consider adding a binding for the required API.
+ #[inline]
+ pub fn as_atomic(&self) -> &Atomic<i32> {
+ let ptr = self.0.get().cast();
+ // SAFETY: `refcount_t` is a transparent wrapper of `atomic_t`, which is an atomic 32-bit
+ // integer that is layout-wise compatible with `Atomic<i32>`. All values are valid for
+ // `refcount_t`, despite some of the values being considered saturated and "bad".
+ unsafe { &*ptr }
+ }
+
/// Set a refcount's value.
#[inline]
pub fn set(&self, value: i32) {