[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <aBuQgY4wMv1CsVdo@Mac.home>
Date: Wed, 7 May 2025 09:55:29 -0700
From: Boqun Feng <boqun.feng@...il.com>
To: Alice Ryhl <aliceryhl@...gle.com>
Cc: Miguel Ojeda <ojeda@...nel.org>, Matthew Wilcox <willy@...radead.org>,
Lorenzo Stoakes <lorenzo.stoakes@...cle.com>,
Vlastimil Babka <vbabka@...e.cz>,
John Hubbard <jhubbard@...dia.com>,
"Liam R. Howlett" <Liam.Howlett@...cle.com>,
Andrew Morton <akpm@...ux-foundation.org>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Arnd Bergmann <arnd@...db.de>, Jann Horn <jannh@...gle.com>,
Suren Baghdasaryan <surenb@...gle.com>,
Alex Gaynor <alex.gaynor@...il.com>, Gary Guo <gary@...yguo.net>,
Björn Roy Baron <bjorn3_gh@...tonmail.com>,
Benno Lossin <benno.lossin@...ton.me>,
Andreas Hindborg <a.hindborg@...nel.org>,
Trevor Gross <tmgross@...ch.edu>, linux-kernel@...r.kernel.org,
linux-mm@...ck.org, rust-for-linux@...r.kernel.org
Subject: Re: [PATCH v16 8/9] task: rust: rework how current is accessed
On Wed, May 07, 2025 at 09:46:23AM -0700, Boqun Feng wrote:
> On Wed, May 07, 2025 at 09:06:01AM -0700, Boqun Feng wrote:
> [...]
> > > +impl CurrentTask {
> > > + /// Access the address space of the current task.
> > > + ///
> > > + /// This function does not touch the refcount of the mm.
> > > + #[inline]
> > > + pub fn mm(&self) -> Option<&MmWithUser> {
> > > + // SAFETY: The `mm` field of `current` is not modified from other threads, so reading it is
> > > + // not a data race.
> > > + let mm = unsafe { (*self.as_ptr()).mm };
> > > +
> > > + if mm.is_null() {
> > > + return None;
> > > + }
> > > +
> > > + // SAFETY: If `current->mm` is non-null, then it references a valid mm with a non-zero
> > > + // value of `mm_users`. Furthermore, the returned `&MmWithUser` borrows from this
> > > + // `CurrentTask`, so it cannot escape the scope in which the current pointer was obtained.
> > > + //
> > > + // This is safe even if `kthread_use_mm()`/`kthread_unuse_mm()` are used. There are two
> > > + // relevant cases:
> > > + // * If the `&CurrentTask` was created before `kthread_use_mm()`, then it cannot be
> > > + // accessed during the `kthread_use_mm()`/`kthread_unuse_mm()` scope due to the
> > > + // `NotThreadSafe` field of `CurrentTask`.
> > > + // * If the `&CurrentTask` was created within a `kthread_use_mm()`/`kthread_unuse_mm()`
> > > + // scope, then the `&CurrentTask` cannot escape that scope, so the returned `&MmWithUser`
> > > + // also cannot escape that scope.
> > > + // In either case, it's not possible to read `current->mm` and keep using it after the
> > > + // scope is ended with `kthread_unuse_mm()`.
> > > + Some(unsafe { MmWithUser::from_raw(mm) })
> > > + }
> > > +
> >
> > Due to this:
> >
> > https://lore.kernel.org/oe-kbuild-all/202505072116.eSYC8igT-lkp@intel.com/
> >
> > , I think we should move this impl block into rust/kernel/mm.rs for now,
> > i.e. (in rust/kernel/mm.rs)
> >
> > impl crate::task::CurrentTask {
> > pub fn mm(&self) -> Option<&MmWithUser> { ... }
> > }
> >
> > Thoughts?
> >
>
> Hmm.. this alone won't be enough, because miscdevice also uses mm. Maybe
> you could most of mm defined even when CONFIG_MMU=n but keep
> MmWithUserAsync only available when CONFIG_MMU=y?
>
Something like this, probably? But your choice ;-) Make CONFIG_RUST
select CONFIG_MMU is fine but the question is who is going to unselect
that at when?
Regards,
Boqun
------------------>8
diff --git a/rust/kernel/mm.rs b/rust/kernel/mm.rs
index 615907a0f3b4..8a1c8158f2b3 100644
--- a/rust/kernel/mm.rs
+++ b/rust/kernel/mm.rs
@@ -10,7 +10,6 @@
//! control what happens when userspace reads or writes to that region of memory.
//!
//! C header: [`include/linux/mm.h`](srctree/include/linux/mm.h)
-#![cfg(CONFIG_MMU)]
use crate::{
bindings,
@@ -130,6 +129,7 @@ unsafe impl Send for MmWithUserAsync {}
// SAFETY: All methods on `MmWithUserAsync` can be called in parallel from several threads.
unsafe impl Sync for MmWithUserAsync {}
+#[cfg(CONFIG_MMU)]
// SAFETY: By the type invariants, this type is always refcounted.
unsafe impl AlwaysRefCounted for MmWithUserAsync {
#[inline]
@@ -207,6 +207,7 @@ pub unsafe fn from_raw<'a>(ptr: *const bindings::mm_struct) -> &'a MmWithUser {
}
/// Use `mmput_async` when dropping this refcount.
+ #[cfg(CONFIG_MMU)]
#[inline]
pub fn into_mmput_async(me: ARef<MmWithUser>) -> ARef<MmWithUserAsync> {
// SAFETY: The layouts and invariants are compatible.
Powered by blists - more mailing lists