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,
@@ -21,6 +20,10 @@ use core::{ops::Deref, ptr::NonNull};
21
20
pub mod virt;
22
21
use virt:: VmaRef ;
23
22
23
+ #[ cfg( CONFIG_MMU ) ]
24
+ pub use mmput_async:: MmWithUserAsync ;
25
+ mod mmput_async;
26
+
24
27
/// A wrapper for the kernel's `struct mm_struct`.
25
28
///
26
29
/// This represents the address space of a userspace process, so each process has one `Mm`
@@ -111,50 +114,6 @@ impl Deref for MmWithUser {
111
114
}
112
115
}
113
116
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
-
158
117
// These methods are safe to call even if `mm_users` is zero.
159
118
impl Mm {
160
119
/// Returns a raw pointer to the inner `mm_struct`.
@@ -206,13 +165,6 @@ impl MmWithUser {
206
165
unsafe { & * ptr. cast ( ) }
207
166
}
208
167
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
-
216
168
/// Attempt to access a vma using the vma read lock.
217
169
///
218
170
/// This is an optimistic trylock operation, so it may fail if there is contention. In that
0 commit comments