Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm: rust: make CONFIG_MMU ifdefs more narrow

Currently the entire kernel::mm module is ifdef'd out when CONFIG_MMU=n.
However, there are some downstream users of the module in
rust/kernel/task.rs and rust/kernel/miscdevice.rs. Thus, update the cfgs
so that only MmWithUserAsync is removed with CONFIG_MMU=n.

The code is moved into a new file, since the #[cfg()] annotation
otherwise has to be duplicated several times.

Link: https://lkml.kernel.org/r/20250516193219.2987032-1-aliceryhl@google.com
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202505071753.kldNHYVQ-lkp@intel.com/
Closes: https://lore.kernel.org/oe-kbuild-all/202505072116.eSYC8igT-lkp@intel.com/
Fixes: 5bb9ed6cdfeb ("mm: rust: add abstraction for struct mm_struct")
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Alice Ryhl and committed by
Andrew Morton
5a789772 bfe125f1

+72 -52
+4 -52
rust/kernel/mm.rs
··· 10 10 //! control what happens when userspace reads or writes to that region of memory. 11 11 //! 12 12 //! C header: [`include/linux/mm.h`](srctree/include/linux/mm.h) 13 - #![cfg(CONFIG_MMU)] 14 13 15 14 use crate::{ 16 15 bindings, ··· 19 20 20 21 pub mod virt; 21 22 use virt::VmaRef; 23 + 24 + #[cfg(CONFIG_MMU)] 25 + pub use mmput_async::MmWithUserAsync; 26 + mod mmput_async; 22 27 23 28 /// A wrapper for the kernel's `struct mm_struct`. 24 29 /// ··· 114 111 } 115 112 } 116 113 117 - /// A wrapper for the kernel's `struct mm_struct`. 118 - /// 119 - /// This type is identical to `MmWithUser` except that it uses `mmput_async` when dropping a 120 - /// refcount. This means that the destructor of `ARef<MmWithUserAsync>` is safe to call in atomic 121 - /// context. 122 - /// 123 - /// # Invariants 124 - /// 125 - /// Values of this type are always refcounted using `mmget`. The value of `mm_users` is non-zero. 126 - #[repr(transparent)] 127 - pub struct MmWithUserAsync { 128 - mm: MmWithUser, 129 - } 130 - 131 - // SAFETY: It is safe to call `mmput_async` on another thread than where `mmget` was called. 132 - unsafe impl Send for MmWithUserAsync {} 133 - // SAFETY: All methods on `MmWithUserAsync` can be called in parallel from several threads. 134 - unsafe impl Sync for MmWithUserAsync {} 135 - 136 - // SAFETY: By the type invariants, this type is always refcounted. 137 - unsafe impl AlwaysRefCounted for MmWithUserAsync { 138 - #[inline] 139 - fn inc_ref(&self) { 140 - // SAFETY: The pointer is valid since self is a reference. 141 - unsafe { bindings::mmget(self.as_raw()) }; 142 - } 143 - 144 - #[inline] 145 - unsafe fn dec_ref(obj: NonNull<Self>) { 146 - // SAFETY: The caller is giving up their refcount. 147 - unsafe { bindings::mmput_async(obj.cast().as_ptr()) }; 148 - } 149 - } 150 - 151 - // Make all `MmWithUser` methods available on `MmWithUserAsync`. 152 - impl Deref for MmWithUserAsync { 153 - type Target = MmWithUser; 154 - 155 - #[inline] 156 - fn deref(&self) -> &MmWithUser { 157 - &self.mm 158 - } 159 - } 160 - 161 114 // These methods are safe to call even if `mm_users` is zero. 162 115 impl Mm { 163 116 /// Returns a raw pointer to the inner `mm_struct`. ··· 163 204 // SAFETY: Caller promises that the pointer is valid for 'a. The layout is compatible due 164 205 // to repr(transparent). 165 206 unsafe { &*ptr.cast() } 166 - } 167 - 168 - /// Use `mmput_async` when dropping this refcount. 169 - #[inline] 170 - pub fn into_mmput_async(me: ARef<MmWithUser>) -> ARef<MmWithUserAsync> { 171 - // SAFETY: The layouts and invariants are compatible. 172 - unsafe { ARef::from_raw(ARef::into_raw(me).cast()) } 173 207 } 174 208 175 209 /// Attempt to access a vma using the vma read lock.
+68
rust/kernel/mm/mmput_async.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + // Copyright (C) 2024 Google LLC. 4 + 5 + //! Version of `MmWithUser` using `mmput_async`. 6 + //! 7 + //! This is a separate file from `mm.rs` due to the dependency on `CONFIG_MMU=y`. 8 + #![cfg(CONFIG_MMU)] 9 + 10 + use crate::{ 11 + bindings, 12 + mm::MmWithUser, 13 + types::{ARef, AlwaysRefCounted}, 14 + }; 15 + use core::{ops::Deref, ptr::NonNull}; 16 + 17 + /// A wrapper for the kernel's `struct mm_struct`. 18 + /// 19 + /// This type is identical to `MmWithUser` except that it uses `mmput_async` when dropping a 20 + /// refcount. This means that the destructor of `ARef<MmWithUserAsync>` is safe to call in atomic 21 + /// context. 22 + /// 23 + /// # Invariants 24 + /// 25 + /// Values of this type are always refcounted using `mmget`. The value of `mm_users` is non-zero. 26 + #[repr(transparent)] 27 + pub struct MmWithUserAsync { 28 + mm: MmWithUser, 29 + } 30 + 31 + // SAFETY: It is safe to call `mmput_async` on another thread than where `mmget` was called. 32 + unsafe impl Send for MmWithUserAsync {} 33 + // SAFETY: All methods on `MmWithUserAsync` can be called in parallel from several threads. 34 + unsafe impl Sync for MmWithUserAsync {} 35 + 36 + // SAFETY: By the type invariants, this type is always refcounted. 37 + unsafe impl AlwaysRefCounted for MmWithUserAsync { 38 + #[inline] 39 + fn inc_ref(&self) { 40 + // SAFETY: The pointer is valid since self is a reference. 41 + unsafe { bindings::mmget(self.as_raw()) }; 42 + } 43 + 44 + #[inline] 45 + unsafe fn dec_ref(obj: NonNull<Self>) { 46 + // SAFETY: The caller is giving up their refcount. 47 + unsafe { bindings::mmput_async(obj.cast().as_ptr()) }; 48 + } 49 + } 50 + 51 + // Make all `MmWithUser` methods available on `MmWithUserAsync`. 52 + impl Deref for MmWithUserAsync { 53 + type Target = MmWithUser; 54 + 55 + #[inline] 56 + fn deref(&self) -> &MmWithUser { 57 + &self.mm 58 + } 59 + } 60 + 61 + impl MmWithUser { 62 + /// Use `mmput_async` when dropping this refcount. 63 + #[inline] 64 + pub fn into_mmput_async(me: ARef<MmWithUser>) -> ARef<MmWithUserAsync> { 65 + // SAFETY: The layouts and invariants are compatible. 66 + unsafe { ARef::from_raw(ARef::into_raw(me).cast()) } 67 + } 68 + }