Skip to content

Commit 5a78977

Browse files
Darksonnakpm00
authored andcommitted
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/[email protected] Reported-by: kernel test robot <[email protected]> Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/ Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/ Fixes: 5bb9ed6 ("mm: rust: add abstraction for struct mm_struct") Signed-off-by: Alice Ryhl <[email protected]> Reviewed-by: Boqun Feng <[email protected]> Cc: Boqun Feng <[email protected]> Cc: Liam Howlett <[email protected]> Cc: Lorenzo Stoakes <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent bfe125f commit 5a78977

File tree

2 files changed

+72
-52
lines changed

2 files changed

+72
-52
lines changed

rust/kernel/mm.rs

Lines changed: 4 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//! control what happens when userspace reads or writes to that region of memory.
1111
//!
1212
//! C header: [`include/linux/mm.h`](srctree/include/linux/mm.h)
13-
#![cfg(CONFIG_MMU)]
1413
1514
use crate::{
1615
bindings,
@@ -21,6 +20,10 @@ use core::{ops::Deref, ptr::NonNull};
2120
pub mod virt;
2221
use virt::VmaRef;
2322

23+
#[cfg(CONFIG_MMU)]
24+
pub use mmput_async::MmWithUserAsync;
25+
mod mmput_async;
26+
2427
/// A wrapper for the kernel's `struct mm_struct`.
2528
///
2629
/// This represents the address space of a userspace process, so each process has one `Mm`
@@ -111,50 +114,6 @@ impl Deref for MmWithUser {
111114
}
112115
}
113116

114-
/// A wrapper for the kernel's `struct mm_struct`.
115-
///
116-
/// This type is identical to `MmWithUser` except that it uses `mmput_async` when dropping a
117-
/// refcount. This means that the destructor of `ARef<MmWithUserAsync>` is safe to call in atomic
118-
/// context.
119-
///
120-
/// # Invariants
121-
///
122-
/// Values of this type are always refcounted using `mmget`. The value of `mm_users` is non-zero.
123-
#[repr(transparent)]
124-
pub struct MmWithUserAsync {
125-
mm: MmWithUser,
126-
}
127-
128-
// SAFETY: It is safe to call `mmput_async` on another thread than where `mmget` was called.
129-
unsafe impl Send for MmWithUserAsync {}
130-
// SAFETY: All methods on `MmWithUserAsync` can be called in parallel from several threads.
131-
unsafe impl Sync for MmWithUserAsync {}
132-
133-
// SAFETY: By the type invariants, this type is always refcounted.
134-
unsafe impl AlwaysRefCounted for MmWithUserAsync {
135-
#[inline]
136-
fn inc_ref(&self) {
137-
// SAFETY: The pointer is valid since self is a reference.
138-
unsafe { bindings::mmget(self.as_raw()) };
139-
}
140-
141-
#[inline]
142-
unsafe fn dec_ref(obj: NonNull<Self>) {
143-
// SAFETY: The caller is giving up their refcount.
144-
unsafe { bindings::mmput_async(obj.cast().as_ptr()) };
145-
}
146-
}
147-
148-
// Make all `MmWithUser` methods available on `MmWithUserAsync`.
149-
impl Deref for MmWithUserAsync {
150-
type Target = MmWithUser;
151-
152-
#[inline]
153-
fn deref(&self) -> &MmWithUser {
154-
&self.mm
155-
}
156-
}
157-
158117
// These methods are safe to call even if `mm_users` is zero.
159118
impl Mm {
160119
/// Returns a raw pointer to the inner `mm_struct`.
@@ -206,13 +165,6 @@ impl MmWithUser {
206165
unsafe { &*ptr.cast() }
207166
}
208167

209-
/// Use `mmput_async` when dropping this refcount.
210-
#[inline]
211-
pub fn into_mmput_async(me: ARef<MmWithUser>) -> ARef<MmWithUserAsync> {
212-
// SAFETY: The layouts and invariants are compatible.
213-
unsafe { ARef::from_raw(ARef::into_raw(me).cast()) }
214-
}
215-
216168
/// Attempt to access a vma using the vma read lock.
217169
///
218170
/// This is an optimistic trylock operation, so it may fail if there is contention. In that

rust/kernel/mm/mmput_async.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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+
}

0 commit comments

Comments
 (0)