From: Elle Rhumsaa <elle@weathered-steel.dev>
To: Boqun Feng <boqun.feng@gmail.com>
Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org,
lkmm@lists.linux.dev, "Will Deacon" <will@kernel.org>,
"Peter Zijlstra" <peterz@infradead.org>,
"Mark Rutland" <mark.rutland@arm.com>,
"Ingo Molnar" <mingo@kernel.org>,
"Thomas Gleixner" <tglx@linutronix.de>,
"Paul E. McKenney" <paulmck@kernel.org>,
stern@rowland.harvard.edu, "Miguel Ojeda" <ojeda@kernel.org>,
alex.gaynor@gmail.com, "Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Danilo Krummrich" <dakr@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Fiona Behrens" <me@kloenk.dev>
Subject: Re: [PATCH 10/14] rust: implement `kernel::sync::Refcount`
Date: Sat, 6 Sep 2025 04:25:21 +0000 [thread overview]
Message-ID: <aLu3saVN2506n7NZ@archiso> (raw)
In-Reply-To: <20250905044141.77868-11-boqun.feng@gmail.com>
On Thu, Sep 04, 2025 at 09:41:37PM -0700, Boqun Feng wrote:
> From: Gary Guo <gary@garyguo.net>
>
> This is a wrapping layer of `include/linux/refcount.h`. Currently the
> kernel refcount has already been used in `Arc`, however it calls into
> FFI directly.
>
> Reviewed-by: Alice Ryhl <aliceryhl@google.com>
> Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
> Reviewed-by: Fiona Behrens <me@kloenk.dev>
> Signed-off-by: Gary Guo <gary@garyguo.net>
> Reviewed-by: Benno Lossin <lossin@kernel.org>
> [boqun: Add the missing <> for the link in comment]
> Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
> Link: https://lore.kernel.org/r/20250723233312.3304339-2-gary@kernel.org
> ---
> rust/helpers/refcount.c | 10 ++++
> rust/kernel/sync.rs | 2 +
> rust/kernel/sync/refcount.rs | 98 ++++++++++++++++++++++++++++++++++++
> 3 files changed, 110 insertions(+)
> create mode 100644 rust/kernel/sync/refcount.rs
>
> diff --git a/rust/helpers/refcount.c b/rust/helpers/refcount.c
> index d6adbd2e45a1..d175898ad7b8 100644
> --- a/rust/helpers/refcount.c
> +++ b/rust/helpers/refcount.c
> @@ -7,11 +7,21 @@ refcount_t rust_helper_REFCOUNT_INIT(int n)
> return (refcount_t)REFCOUNT_INIT(n);
> }
>
> +void rust_helper_refcount_set(refcount_t *r, int n)
> +{
> + refcount_set(r, n);
> +}
> +
> void rust_helper_refcount_inc(refcount_t *r)
> {
> refcount_inc(r);
> }
>
> +void rust_helper_refcount_dec(refcount_t *r)
> +{
> + refcount_dec(r);
> +}
> +
> bool rust_helper_refcount_dec_and_test(refcount_t *r)
> {
> return refcount_dec_and_test(r);
> diff --git a/rust/kernel/sync.rs b/rust/kernel/sync.rs
> index bf8943c88a89..cf5b638a097d 100644
> --- a/rust/kernel/sync.rs
> +++ b/rust/kernel/sync.rs
> @@ -19,6 +19,7 @@
> mod locked_by;
> pub mod poll;
> pub mod rcu;
> +mod refcount;
>
> pub use arc::{Arc, ArcBorrow, UniqueArc};
> pub use completion::Completion;
> @@ -27,6 +28,7 @@
> pub use lock::mutex::{new_mutex, Mutex, MutexGuard};
> pub use lock::spinlock::{new_spinlock, SpinLock, SpinLockGuard};
> pub use locked_by::LockedBy;
> +pub use refcount::Refcount;
>
> /// Represents a lockdep class. It's a wrapper around C's `lock_class_key`.
> #[repr(transparent)]
> diff --git a/rust/kernel/sync/refcount.rs b/rust/kernel/sync/refcount.rs
> new file mode 100644
> index 000000000000..cc1a80ae7ae9
> --- /dev/null
> +++ b/rust/kernel/sync/refcount.rs
> @@ -0,0 +1,98 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +//! Atomic reference counting.
> +//!
> +//! C header: [`include/linux/refcount.h`](srctree/include/linux/refcount.h)
> +
> +use crate::build_assert;
> +use crate::types::Opaque;
> +
> +/// Atomic reference counter.
> +///
> +/// This type is conceptually an atomic integer, but provides saturation semantics compared to
> +/// normal atomic integers. Values in the negative range when viewed as a signed integer are
> +/// saturation (bad) values. For details about the saturation semantics, please refer to top of
> +/// [`include/linux/refcount.h`](srctree/include/linux/refcount.h).
> +///
> +/// Wraps the kernel's C `refcount_t`.
> +#[repr(transparent)]
> +pub struct Refcount(Opaque<bindings::refcount_t>);
> +
> +impl Refcount {
> + /// Construct a new [`Refcount`] from an initial value.
> + ///
> + /// The initial value should be non-saturated.
> + #[inline]
> + pub fn new(value: i32) -> Self {
> + build_assert!(value >= 0, "initial value saturated");
> + // SAFETY: There are no safety requirements for this FFI call.
> + Self(Opaque::new(unsafe { bindings::REFCOUNT_INIT(value) }))
> + }
> +
> + #[inline]
> + fn as_ptr(&self) -> *mut bindings::refcount_t {
> + self.0.get()
> + }
> +
> + /// Set a refcount's value.
> + #[inline]
> + pub fn set(&self, value: i32) {
> + // SAFETY: `self.as_ptr()` is valid.
> + unsafe { bindings::refcount_set(self.as_ptr(), value) }
> + }
> +
> + /// Increment a refcount.
> + ///
> + /// It will saturate if overflows and `WARN`. It will also `WARN` if the refcount is 0, as this
> + /// represents a possible use-after-free condition.
> + ///
> + /// Provides no memory ordering, it is assumed that caller already has a reference on the
> + /// object.
> + #[inline]
> + pub fn inc(&self) {
> + // SAFETY: self is valid.
> + unsafe { bindings::refcount_inc(self.as_ptr()) }
> + }
> +
> + /// Decrement a refcount.
> + ///
> + /// It will `WARN` on underflow and fail to decrement when saturated.
> + ///
> + /// Provides release memory ordering, such that prior loads and stores are done
> + /// before.
> + #[inline]
> + pub fn dec(&self) {
> + // SAFETY: `self.as_ptr()` is valid.
> + unsafe { bindings::refcount_dec(self.as_ptr()) }
> + }
> +
> + /// Decrement a refcount and test if it is 0.
> + ///
> + /// It will `WARN` on underflow and fail to decrement when saturated.
> + ///
> + /// Provides release memory ordering, such that prior loads and stores are done
> + /// before, and provides an acquire ordering on success such that memory deallocation
> + /// must come after.
> + ///
> + /// Returns true if the resulting refcount is 0, false otherwise.
> + ///
> + /// # Notes
> + ///
> + /// A common pattern of using `Refcount` is to free memory when the reference count reaches
> + /// zero. This means that the reference to `Refcount` could become invalid after calling this
> + /// function. This is fine as long as the reference to `Refcount` is no longer used when this
> + /// function returns `false`. It is not necessary to use raw pointers in this scenario, see
> + /// <https://github.com/rust-lang/rust/issues/55005>.
> + #[inline]
> + #[must_use = "use `dec` instead if you do not need to test if it is 0"]
> + pub fn dec_and_test(&self) -> bool {
> + // SAFETY: `self.as_ptr()` is valid.
> + unsafe { bindings::refcount_dec_and_test(self.as_ptr()) }
> + }
> +}
> +
> +// SAFETY: `refcount_t` is thread-safe.
> +unsafe impl Send for Refcount {}
> +
> +// SAFETY: `refcount_t` is thread-safe.
> +unsafe impl Sync for Refcount {}
> --
> 2.51.0
>
>
Reviewed-by: Elle Rhumsaa <elle@weathered-steel.dev>
next prev parent reply other threads:[~2025-09-06 4:25 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-05 4:41 [GIT PULL] [PATCH 00/14] Rust atomic changes for v6.18 Boqun Feng
2025-09-05 4:41 ` [PATCH 01/14] rust: Introduce atomic API helpers Boqun Feng
2025-09-06 4:22 ` Elle Rhumsaa
2025-09-15 7:48 ` [tip: locking/core] " tip-bot2 for Boqun Feng
2025-09-05 4:41 ` [PATCH 02/14] rust: sync: Add basic atomic operation mapping framework Boqun Feng
2025-09-06 4:22 ` Elle Rhumsaa
2025-09-13 10:15 ` [tip: locking/core] " tip-bot2 for Boqun Feng
2025-09-15 7:48 ` tip-bot2 for Boqun Feng
2025-09-05 4:41 ` [PATCH 03/14] rust: sync: atomic: Add ordering annotation types Boqun Feng
2025-09-06 4:22 ` Elle Rhumsaa
2025-09-13 10:15 ` [tip: locking/core] " tip-bot2 for Boqun Feng
2025-09-15 7:48 ` tip-bot2 for Boqun Feng
2025-09-05 4:41 ` [PATCH 04/14] rust: sync: atomic: Add generic atomics Boqun Feng
2025-09-06 4:23 ` Elle Rhumsaa
2025-09-13 10:15 ` [tip: locking/core] " tip-bot2 for Boqun Feng
2025-09-15 7:48 ` tip-bot2 for Boqun Feng
2025-09-05 4:41 ` [PATCH 05/14] rust: sync: atomic: Add atomic {cmp,}xchg operations Boqun Feng
2025-09-06 4:23 ` Elle Rhumsaa
2025-09-13 10:15 ` [tip: locking/core] " tip-bot2 for Boqun Feng
2025-09-15 7:48 ` tip-bot2 for Boqun Feng
2025-09-05 4:41 ` [PATCH 06/14] rust: sync: atomic: Add the framework of arithmetic operations Boqun Feng
2025-09-06 4:23 ` Elle Rhumsaa
2025-09-13 10:15 ` [tip: locking/core] " tip-bot2 for Boqun Feng
2025-09-15 7:48 ` tip-bot2 for Boqun Feng
2025-09-05 4:41 ` [PATCH 07/14] rust: sync: atomic: Add Atomic<u{32,64}> Boqun Feng
2025-09-06 4:24 ` Elle Rhumsaa
2025-09-13 10:15 ` [tip: locking/core] " tip-bot2 for Boqun Feng
2025-09-15 7:48 ` tip-bot2 for Boqun Feng
2025-09-05 4:41 ` [PATCH 08/14] rust: sync: atomic: Add Atomic<{usize,isize}> Boqun Feng
2025-09-06 4:24 ` Elle Rhumsaa
2025-09-13 10:15 ` [tip: locking/core] " tip-bot2 for Boqun Feng
2025-09-15 7:48 ` tip-bot2 for Boqun Feng
2025-09-05 4:41 ` [PATCH 09/14] rust: sync: Add memory barriers Boqun Feng
2025-09-06 4:25 ` Elle Rhumsaa
2025-09-13 10:15 ` [tip: locking/core] " tip-bot2 for Boqun Feng
2025-09-15 7:48 ` tip-bot2 for Boqun Feng
2025-09-05 4:41 ` [PATCH 10/14] rust: implement `kernel::sync::Refcount` Boqun Feng
2025-09-06 4:25 ` Elle Rhumsaa [this message]
2025-09-13 10:15 ` [tip: locking/core] " tip-bot2 for Gary Guo
2025-09-15 7:48 ` tip-bot2 for Gary Guo
2025-09-05 4:41 ` [PATCH 11/14] rust: make `Arc::into_unique_or_drop` associated function Boqun Feng
2025-09-06 4:25 ` Elle Rhumsaa
2025-09-13 10:15 ` [tip: locking/core] " tip-bot2 for Gary Guo
2025-09-15 7:48 ` tip-bot2 for Gary Guo
2025-09-05 4:41 ` [PATCH 12/14] rust: convert `Arc` to use `Refcount` Boqun Feng
2025-09-06 4:26 ` Elle Rhumsaa
2025-09-13 10:15 ` [tip: locking/core] " tip-bot2 for Gary Guo
2025-09-15 7:48 ` tip-bot2 for Gary Guo
2025-09-05 4:41 ` [PATCH 13/14] rust: block: convert `block::mq` " Boqun Feng
2025-09-06 4:26 ` Elle Rhumsaa
2025-09-13 10:15 ` [tip: locking/core] " tip-bot2 for Gary Guo
2025-09-15 7:48 ` tip-bot2 for Gary Guo
2025-09-05 4:41 ` [PATCH 14/14] MAINTAINERS: update atomic infrastructure entry to include Rust Boqun Feng
2025-09-06 4:26 ` Elle Rhumsaa
2025-09-13 10:15 ` [tip: locking/core] " tip-bot2 for Gary Guo
2025-09-15 7:48 ` tip-bot2 for Gary Guo
2025-09-10 5:27 ` [GIT PULL] [PATCH 00/14] Rust atomic changes for v6.18 Boqun Feng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aLu3saVN2506n7NZ@archiso \
--to=elle@weathered-steel.dev \
--cc=a.hindborg@kernel.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@kernel.org \
--cc=gary@garyguo.net \
--cc=linux-kernel@vger.kernel.org \
--cc=lkmm@lists.linux.dev \
--cc=lossin@kernel.org \
--cc=mark.rutland@arm.com \
--cc=me@kloenk.dev \
--cc=mingo@kernel.org \
--cc=ojeda@kernel.org \
--cc=paulmck@kernel.org \
--cc=peterz@infradead.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=stern@rowland.harvard.edu \
--cc=tglx@linutronix.de \
--cc=tmgross@umich.edu \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.