From: "Benno Lossin" <lossin@kernel.org>
To: "Gary Guo" <gary@kernel.org>, "Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Danilo Krummrich" <dakr@kernel.org>,
"Will Deacon" <will@kernel.org>,
"Peter Zijlstra" <peterz@infradead.org>,
"Mark Rutland" <mark.rutland@arm.com>,
"Tamir Duberstein" <tamird@gmail.com>,
"Xiangfei Ding" <dingxiangfei2009@gmail.com>,
"Alex Mantel" <alexmantel93@mailbox.org>
Cc: <rust-for-linux@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v4 3/5] rust: convert `Arc` to use `Refcount`
Date: Sun, 22 Jun 2025 23:08:05 +0200 [thread overview]
Message-ID: <DATDAOYC60S9.2MEZ4NHCUHNXO@kernel.org> (raw)
In-Reply-To: <20250622125802.3224264-4-gary@kernel.org>
On Sun Jun 22, 2025 at 2:57 PM CEST, Gary Guo wrote:
> @@ -428,14 +422,10 @@ fn as_ref(&self) -> &T {
>
> impl<T: ?Sized> Clone for Arc<T> {
> fn clone(&self) -> Self {
> - // SAFETY: By the type invariant, there is necessarily a reference to the object, so it is
> - // safe to dereference it.
> - let refcount = unsafe { self.ptr.as_ref() }.refcount.get();
> -
> - // INVARIANT: C `refcount_inc` saturates the refcount, so it cannot overflow to zero.
> + // INVARIANT: `Refcount` saturates the refcount, so it cannot overflow to zero.
> // SAFETY: By the type invariant, there is necessarily a reference to the object, so it is
> // safe to increment the refcount.
> - unsafe { bindings::refcount_inc(refcount) };
> + unsafe { self.ptr.as_ref().refcount.inc() };
The `.refcount.inc()` can be outside of the `unsafe` block.
>
> // SAFETY: We just incremented the refcount. This increment is now owned by the new `Arc`.
> unsafe { Self::from_inner(self.ptr) }
> @@ -444,16 +434,10 @@ fn clone(&self) -> Self {
>
> impl<T: ?Sized> Drop for Arc<T> {
> fn drop(&mut self) {
> - // SAFETY: By the type invariant, there is necessarily a reference to the object. We cannot
> - // touch `refcount` after it's decremented to a non-zero value because another thread/CPU
> - // may concurrently decrement it to zero and free it. It is ok to have a raw pointer to
> - // freed/invalid memory as long as it is never dereferenced.
> - let refcount = unsafe { self.ptr.as_ref() }.refcount.get();
> -
> // INVARIANT: If the refcount reaches zero, there are no other instances of `Arc`, and
> // this instance is being dropped, so the broken invariant is not observable.
> - // SAFETY: Also by the type invariant, we are allowed to decrement the refcount.
> - let is_zero = unsafe { bindings::refcount_dec_and_test(refcount) };
> + // SAFETY: By the type invariant, there is necessarily a reference to the object.
> + let is_zero = unsafe { self.ptr.as_ref().refcount.dec_and_test() };
Ditto.
> if is_zero {
> // The count reached zero, we must free the memory.
> //
> @@ -747,8 +731,7 @@ pub fn new_uninit(flags: Flags) -> Result<UniqueArc<MaybeUninit<T>>, AllocError>
> // INVARIANT: The refcount is initialised to a non-zero value.
> let inner = KBox::try_init::<AllocError>(
> try_init!(ArcInner {
> - // SAFETY: There are no safety requirements for this FFI call.
> - refcount: Opaque::new(unsafe { bindings::REFCOUNT_INIT(1) }),
> + refcount: Refcount::new(1),
> data <- pin_init::uninit::<T, AllocError>(),
> }? AllocError),
> flags,
> diff --git a/rust/kernel/sync/refcount.rs b/rust/kernel/sync/refcount.rs
> index a0fc22f6d645..8e7b9b0c1979 100644
> --- a/rust/kernel/sync/refcount.rs
> +++ b/rust/kernel/sync/refcount.rs
> @@ -71,6 +71,14 @@ pub fn dec(&self) {
> /// 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.
This should be in patch 1?
---
Cheers,
Benno
> #[inline]
> #[must_use = "use `dec` instead if you do not need to test if it is 0"]
> pub fn dec_and_test(&self) -> bool {
next prev parent reply other threads:[~2025-06-22 21:08 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-22 12:57 [PATCH v4 0/5] implement `kernel::sync::Refcount` and convert users Gary Guo
2025-06-22 12:57 ` [PATCH v4 1/5] rust: implement `kernel::sync::Refcount` Gary Guo
2025-06-22 21:05 ` Benno Lossin
2025-06-22 22:17 ` Gary Guo
2025-06-22 12:57 ` [PATCH v4 2/5] rust: make `Arc::into_unique_or_drop` associated function Gary Guo
2025-06-22 21:05 ` Benno Lossin
2025-06-22 12:57 ` [PATCH v4 3/5] rust: convert `Arc` to use `Refcount` Gary Guo
2025-06-22 21:08 ` Benno Lossin [this message]
2025-06-23 9:06 ` kernel test robot
2025-06-22 12:57 ` [PATCH v4 4/5] rust: block: convert `block::mq` " Gary Guo
2025-06-22 12:57 ` [PATCH v4 5/5] MAINTAINERS: update atomic infrastructure entry to include Rust Gary Guo
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=DATDAOYC60S9.2MEZ4NHCUHNXO@kernel.org \
--to=lossin@kernel.org \
--cc=a.hindborg@kernel.org \
--cc=alex.gaynor@gmail.com \
--cc=alexmantel93@mailbox.org \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@kernel.org \
--cc=dingxiangfei2009@gmail.com \
--cc=gary@garyguo.net \
--cc=gary@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=ojeda@kernel.org \
--cc=peterz@infradead.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tamird@gmail.com \
--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.