FILE
mmput_async.rs
File preview with syntax highlighting.
linux-6.19.14/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 10use crate::{ 11 bindings, 12 mm::MmWithUser, 13 sync::aref::{ARef, AlwaysRefCounted}, 14}; 15use 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)] 27pub struct MmWithUserAsync { 28 mm: MmWithUser, 29} 30 31// SAFETY: It is safe to call `mmput_async` on another thread than where `mmget` was called. 32unsafe impl Send for MmWithUserAsync {} 33// SAFETY: All methods on `MmWithUserAsync` can be called in parallel from several threads. 34unsafe impl Sync for MmWithUserAsync {} 35 36// SAFETY: By the type invariants, this type is always refcounted. 37unsafe 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`. 52impl Deref for MmWithUserAsync { 53 type Target = MmWithUser; 54 55 #[inline] 56 fn deref(&self) -> &MmWithUser { 57 &self.mm 58 } 59} 60 61impl 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}
~/
Read-only file preview.