diff options
| author | Gary Guo <gary@garyguo.net> | 2025-09-04 21:41:40 -0700 |
|---|---|---|
| committer | Peter Zijlstra <peterz@infradead.org> | 2025-09-15 09:38:36 +0200 |
| commit | a307bf1db5448eccd72a1d7857f7661c6330d5ad (patch) | |
| tree | 13ad271e34c14d904a78cc0f425c54dff934fec9 /rust/kernel/sync/refcount.rs | |
| parent | rust: convert `Arc` to use `Refcount` (diff) | |
| download | linux-a307bf1db5448eccd72a1d7857f7661c6330d5ad.tar.gz linux-a307bf1db5448eccd72a1d7857f7661c6330d5ad.zip | |
rust: block: convert `block::mq` to use `Refcount`
Currently there's a custom reference counting in `block::mq`, which uses
`AtomicU64` Rust atomics, and this type doesn't exist on some 32-bit
architectures. We cannot just change it to use 32-bit atomics, because
doing so will make it vulnerable to refcount overflow. So switch it to
use the kernel refcount `kernel::sync::Refcount` instead.
There is an operation needed by `block::mq`, atomically decreasing
refcount from 2 to 0, which is not available through refcount.h, so
I exposed `Refcount::as_atomic` which allows accessing the refcount
directly.
[boqun: Adopt the LKMM atomic API]
Signed-off-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Benno Lossin <lossin@kernel.org>
Reviewed-by: Elle Rhumsaa <elle@weathered-steel.dev>
Acked-by: Andreas Hindborg <a.hindborg@kernel.org>
Tested-by: David Gow <davidgow@google.com>
Link: https://lore.kernel.org/r/20250723233312.3304339-5-gary@kernel.org
Diffstat (limited to 'rust/kernel/sync/refcount.rs')
| -rw-r--r-- | rust/kernel/sync/refcount.rs | 15 |
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) { |
