From patchwork Fri Nov 22 15:40:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 13883302 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id A0CB2E6916D for ; Fri, 22 Nov 2024 15:41:08 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 30DFC8D000B; Fri, 22 Nov 2024 10:41:08 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 2BF1F8D0007; Fri, 22 Nov 2024 10:41:08 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 1117F8D000B; Fri, 22 Nov 2024 10:41:08 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id DB4128D0007 for ; Fri, 22 Nov 2024 10:41:07 -0500 (EST) Received: from smtpin13.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id 929D51A16DD for ; Fri, 22 Nov 2024 15:41:07 +0000 (UTC) X-FDA: 82814141802.13.49809DB Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.202]) by imf07.hostedemail.com (Postfix) with ESMTP id 3AA2740010 for ; Fri, 22 Nov 2024 15:39:51 +0000 (UTC) Authentication-Results: imf07.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=FUAmD4qB; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf07.hostedemail.com: domain of 3EKZAZwkKCJ89KHBDQXGKFNNFKD.BNLKHMTW-LLJU9BJ.NQF@flex--aliceryhl.bounces.google.com designates 209.85.128.202 as permitted sender) smtp.mailfrom=3EKZAZwkKCJ89KHBDQXGKFNNFKD.BNLKHMTW-LLJU9BJ.NQF@flex--aliceryhl.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1732289972; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=ZJFWlPcRbAWY+HnVngOyCc1o+97QXNSOMi5+R+xDQr4=; b=h42Ik8TeFGIxxCWjbhiUDhuLHGDfPJ2RrWOfs15Rl9gg+5o5KY2hb+KLfaBdJtyItqrCS/ 3VsiAitig1+JjZTnM5jTZHZGK5XBj8S3FyszuvplyylAY4Lgfo9JwuNbzQaWv0T1HvYazQ PvCqKm4TExkLdmhA+xDLsw3FSBiFvXo= ARC-Authentication-Results: i=1; imf07.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=FUAmD4qB; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf07.hostedemail.com: domain of 3EKZAZwkKCJ89KHBDQXGKFNNFKD.BNLKHMTW-LLJU9BJ.NQF@flex--aliceryhl.bounces.google.com designates 209.85.128.202 as permitted sender) smtp.mailfrom=3EKZAZwkKCJ89KHBDQXGKFNNFKD.BNLKHMTW-LLJU9BJ.NQF@flex--aliceryhl.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1732289972; a=rsa-sha256; cv=none; b=JlBFQt+ZjCaQePJ5DKpzNsLM26BBcWPgpf3kVMniKFBn8yGpooBFf5KmdH2pwo7JDwrSTn k58pXgCnasBjrQrWmaCGmtr5KXUOPOObeKyNRsZml7zh8gMy/QHo26BOsJXMUBbSPiWdZ2 OEZdZZQSfaosgHGX6nP8+khgtQTWDJA= Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-6ee65ae21b9so37253747b3.3 for ; Fri, 22 Nov 2024 07:41:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1732290064; x=1732894864; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=ZJFWlPcRbAWY+HnVngOyCc1o+97QXNSOMi5+R+xDQr4=; b=FUAmD4qBQkPnP8socnAYdEepYzm47g8kC2MWA7CLdZDndHPBwdVJhfCfF9JN7yjOEW QPoavnKi5EwNvBpR2QJIomrmS9MnkAGPzt7O4AjEuHLIIfuEtG79qjlKdqShFcdgxpAl auMg/N7YDzc49A9u1BZK3cnY3fd/ZZ8WJiP6bf38EdNUSB71DzN99DgJSfEEGQtn5Fu1 GfdPq1wiqhhylLm64XSGFfWJczb12L8BgWENH6g0FGd7wS33ky8QC47QpfFzc6kCb+q7 ohg11jCOfp5zNltX1eFzDyY4f/PUQc1AE32xvSl2g2NKGILuMwEz2JEvuckivRMhtzDv wmNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732290064; x=1732894864; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ZJFWlPcRbAWY+HnVngOyCc1o+97QXNSOMi5+R+xDQr4=; b=wfe3pPz0wI6y5U1cvNHOnQcuVvs97s1+aPvpLDgLluPBCcz69Aa8XY5FZ2+4PfWzLK mLSnoqmrCTGswizGrRclluy3Xewtn48V27REHdKvjtUk+2fr8mSgPhIy9KDaPZelS8T5 4p+T0Upi17yRX0YlR5kmGnqOz8JosmXWQcT7BhrAe6LbpHFi52BVoDmWTdY3s5qQ9ggK ml89YS3KY+lEEJZI7nD/VJFwnj5z+BrdvX0/x6OJHf6IEJrcU7d3g/rz4MrcSvEx/KlU mRkWj3izULQIfMYCwrwRc/6lER+RgUwZ74NHDpAMMyx3L6u3Mh9J93M+/UvRPxTvbFXG UGAg== X-Forwarded-Encrypted: i=1; AJvYcCXMh39GKMXDsN6RKtpjo6zajj3zbJiPIhEBwfcrBjT/qoLqV3/RVyfCqTXhm3b2OUYjSxaAMIDkcw==@kvack.org X-Gm-Message-State: AOJu0YyJQOSox+ZbIzN5El7gFjKPPc4SnYhooS1A9WP8OuJtN6kQ6Dkx e8G3AsUQCeTZE13ninzzK4DL3rJfKrw0+l6HSYe9he3SXk2NJnr/Buv5f4gCLlDsZaWlpqrXFUP ORwn32hoQo7rpeg== X-Google-Smtp-Source: AGHT+IFkONJC35kmfVY70U61nS/i2+8qUNS80u+/hoQsPbcnJf4FyJ3hfmZEVlFS1n5cWkqU0f6+UfL+LNXTVJs= X-Received: from aliceryhl.c.googlers.com ([fda3:e722:ac3:cc00:68:fe9:ac10:f29e]) (user=aliceryhl job=sendgmr) by 2002:a05:690c:680d:b0:6ee:b693:f752 with SMTP id 00721157ae682-6eee0777adfmr474527b3.0.1732290064561; Fri, 22 Nov 2024 07:41:04 -0800 (PST) Date: Fri, 22 Nov 2024 15:40:26 +0000 In-Reply-To: <20241122-vma-v9-0-7127bfcdd54e@google.com> Mime-Version: 1.0 References: <20241122-vma-v9-0-7127bfcdd54e@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=9971; i=aliceryhl@google.com; h=from:subject:message-id; bh=ZPc1KRKfoIOZWtqnzIede0sGQwVP3YDeDd6Hc6TOsWM=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBnQKYHu02lowltad/mpq8VFaO/SbmENjK7ouQqb BP+7GBjeceJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ0CmBwAKCRAEWL7uWMY5 RtBIEACzoJXZvz8inFVeNuo4OnCxriwsgPHZvem8VJonDGvKOqY3hV8gdgEW0K8ZCRVi3FxkX6Q rhi2LU17e0tNyuNS/fPXzgTVtlQ+uePX+T16VcOwD6Tok3wwoFlgJFYP9rkgdXCwPbTP1RDxVZI O0KP5gnzotaIObWIAXjiInjRdZzTbu3YtmSadyCpxmsvplUP30jlZPPQEtB8IdO9lXBfN+aoekT 8ol3fX/5me6J/ORV/A9ejQWpWz3GgcyhCfe7Z+y/+7cvWVFPxs3arcjCc0HMHPLabcK0RClafYY JiNexDK8yqS0gGZ+aYr+2c7FhCwv+6Klck+F9LsSSLgiXKK3VxKaFYAqAt/H5ketvAtoyPYcwIf Jjv6yuP4SQ9Js1cuTPVfq+ecqT60ApH2hc8GZnQ4Kd9UjBnMePsRewrTf5Osa1l9sfU4RCT8Wtx V6epoDSENmIwUkovL8UmHv18xLKpQCWU7aWYAxZuyjsBx8wxUpBAh+sDxz1MHYXLAiYqfNPDeyZ GoQ0KMDpW3H2jq+9YhKTCXVo+6Q85RXhvMNZcA5+oj1eki94TSGdEl13UC6kuaNaME/ROr2jR0N ljH+qZ+PVCKuKW6ETcGvkIkZ3tCYAlCN4p1AtzRwK5nz1lGdMpgjtgc77S7WlWJXRLmw0AIzo2M B1pjqpbr9pI51IQ== X-Mailer: b4 0.13.0 Message-ID: <20241122-vma-v9-1-7127bfcdd54e@google.com> Subject: [PATCH v9 1/8] mm: rust: add abstraction for struct mm_struct From: Alice Ryhl To: Miguel Ojeda , Matthew Wilcox , Lorenzo Stoakes , Vlastimil Babka , John Hubbard , "Liam R. Howlett" , Andrew Morton , Greg Kroah-Hartman , Arnd Bergmann , Christian Brauner , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl , Andreas Hindborg X-Rspam-User: X-Rspamd-Server: rspam03 X-Rspamd-Queue-Id: 3AA2740010 X-Stat-Signature: xqfyt6ow5mqd445fhjt86dn9sgscog7o X-HE-Tag: 1732289991-490230 X-HE-Meta: U2FsdGVkX18dsPHajGWjcKbrKpdxhzNkSSti9ojd3YPFvIdpZ6Rkv8UK88/4MfH/Ceep0utzuI6apoUor01up7vGyW5RWrcWWapsk5cajxw07VxN7JsD3TJCKIXRz1DKYQMVLJRHQbM92kO1NfvB5PPEHNlK/PvILZy9sHFeTq5vWEgzhM02Ol85yt4MpGDP1grjZsXF/CjmBb/IcuL0Dt4cJ9++yZYq9EYCdxVkwZ9HTiAJi2Jb37AkUgEhUfr7ebeTN+uZtqb27fR+B7GsU94b6OHhlf+QO5jC/zbqDv/Gv7RkHKoiDZUtBVkAGUclGTsKCvOKu4sR3r777QsmshjaFV9YnkwlJH8lzjWuAOGtr1wVTicvxn5F3VomHAq4AtrxwKns6aVfIBlfLwq4r2ixJM3U+zRlCjSg8uc9I2t+WBbMu5Tbn0eOcHptmpcfXmcAAHdDSNQKsXzl+LRAjTl4u7dKiJd0/+4VAHd+Qg+lB330ShkGPYlCogOqYyJUXYJO5NBl9p1Rn7jJ7kls0s74kCxgvkGRwgXh+17/IJE+9E1Cw5GExjvpSp6M4WP+Kwul/qWhv278OrxiSpw/WFCR+rDuh2XoWHUtvw16oDXPv3mxjPitXmBm3QTCMIf+RC81y5Q4AAML8d1gCGMZ9pb6rdX3dg+RYwLy3AGqadPFYrxKEgRR6plNf/jifoOi6+he5vzRYoRJ92fqyvjn7eKW7RFHgQGX/NBtL3Z6MdBhhG9Tj5gRLICZLwL6TBFxHcD7ZHdlVteJEJpSx1sRPBj9+2tybNV9VMuXyT1mGwH0WCu07fVeanzVk400Q8ZcVWML8JZcnV58zTuDKHyxULYi+6vS1XCLllZzQ/xH9wOgBGCrO4xNh57jsO4v1e4BaNbuEVR5MCr9Tm8RIixBDcqVJeynV6qTd2s+2aCLqGpe31i94e1D67N7t3IHXTG/7wGd29qrz/GQJPzB7Yq ycjj66U9 S/4APtZrWX2TkJKGalqo3252B8jZqdGyF6p8CyX8271NmDl32QVXbYhChwZ5W86Z2zf6sK9AVxSzTCAiETJhvwGbW4K04Lh5Ii4xgerkjz2KQmeScTBJTuHlQZKNjv5yHV5KbW+d1bU+CSMbu8ap5+d04KynLi6gri4B3+wqBnk26xX5g5pQ3K7TTwF+FBOQtShy2M6+ZshufxreNtRpT0JuBh4E+WXOZzU6ovyr2gszcNjovdFSG6zhJUjs+oiNKUsGXyudszOvJEJZE7oCr4v28uFq5sAGkYPtgRNKCdgByeEyyqWK0/zBQgasWMPhwokM+6X09wlGZk1CPc+UKbQhcw/pBSozbo7F+xNN93UqLrmM3bz0ppk6s7NW8PV2hl2weSk2g2Y1ltmv9ix2HLn5lSbXdBysn26Vhem9/dYP52242VRuN0AvPNfkGc2z8Kz93WIMY7JuQQ9ByedboKWOYbQlb7zfwb1mUuVk2Xtq7reJIfMNSrUeQeebi8gQhrRkywbL3i87ON8ijHAE5ptG8U3YfD3JeOIBtTx63h+c7Uyz1lbjNTxzKHcFzOEdZwy6V8HrIhZ2fFVz8YsVuCG4mEBVmAvsPDPIvzPJuqqCwcIksp4G6G9C/zUZMvrfTKIcD0SSK20TqorF+ELbwthVijirf15/WpJWKkIlNE4XFAM9KX8ApMmP1LQ== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: These abstractions allow you to reference a `struct mm_struct` using both mmgrab and mmget refcounts. This is done using two Rust types: * Mm - represents an mm_struct where you don't know anything about the value of mm_users. * MmWithUser - represents an mm_struct where you know at compile time that mm_users is non-zero. This allows us to encode in the type system whether a method requires that mm_users is non-zero or not. For instance, you can always call `mmget_not_zero` but you can only call `mmap_read_lock` when mm_users is non-zero. It's possible to access current->mm without a refcount increment, but that is added in a later patch of this series. Signed-off-by: Alice Ryhl Acked-by: Lorenzo Stoakes (for mm bits) --- rust/helpers/helpers.c | 1 + rust/helpers/mm.c | 39 +++++++++ rust/kernel/lib.rs | 1 + rust/kernel/mm.rs | 219 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 260 insertions(+) diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c index 6d90afd38c40..2ee3af594633 100644 --- a/rust/helpers/helpers.c +++ b/rust/helpers/helpers.c @@ -15,6 +15,7 @@ #include "err.c" #include "fs.c" #include "kunit.c" +#include "mm.c" #include "mutex.c" #include "page.c" #include "rbtree.c" diff --git a/rust/helpers/mm.c b/rust/helpers/mm.c new file mode 100644 index 000000000000..7201747a5d31 --- /dev/null +++ b/rust/helpers/mm.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include + +void rust_helper_mmgrab(struct mm_struct *mm) +{ + mmgrab(mm); +} + +void rust_helper_mmdrop(struct mm_struct *mm) +{ + mmdrop(mm); +} + +void rust_helper_mmget(struct mm_struct *mm) +{ + mmget(mm); +} + +bool rust_helper_mmget_not_zero(struct mm_struct *mm) +{ + return mmget_not_zero(mm); +} + +void rust_helper_mmap_read_lock(struct mm_struct *mm) +{ + mmap_read_lock(mm); +} + +bool rust_helper_mmap_read_trylock(struct mm_struct *mm) +{ + return mmap_read_trylock(mm); +} + +void rust_helper_mmap_read_unlock(struct mm_struct *mm) +{ + mmap_read_unlock(mm); +} diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index bf98caa6d6a5..104e619f5dbd 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -45,6 +45,7 @@ pub mod kunit; pub mod list; pub mod miscdevice; +pub mod mm; #[cfg(CONFIG_NET)] pub mod net; pub mod page; diff --git a/rust/kernel/mm.rs b/rust/kernel/mm.rs new file mode 100644 index 000000000000..84cba581edaa --- /dev/null +++ b/rust/kernel/mm.rs @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: GPL-2.0 + +// Copyright (C) 2024 Google LLC. + +//! Memory management. +//! +//! C header: [`include/linux/mm.h`](srctree/include/linux/mm.h) + +use crate::{ + bindings, + types::{ARef, AlwaysRefCounted, NotThreadSafe, Opaque}, +}; +use core::{ops::Deref, ptr::NonNull}; + +/// A wrapper for the kernel's `struct mm_struct`. +/// +/// Since `mm_users` may be zero, the associated address space may not exist anymore. You can use +/// [`mmget_not_zero`] to be able to access the address space. +/// +/// The `ARef` smart pointer holds an `mmgrab` refcount. Its destructor may sleep. +/// +/// # Invariants +/// +/// Values of this type are always refcounted using `mmgrab`. +/// +/// [`mmget_not_zero`]: Mm::mmget_not_zero +#[repr(transparent)] +pub struct Mm { + mm: Opaque, +} + +// SAFETY: It is safe to call `mmdrop` on another thread than where `mmgrab` was called. +unsafe impl Send for Mm {} +// SAFETY: All methods on `Mm` can be called in parallel from several threads. +unsafe impl Sync for Mm {} + +// SAFETY: By the type invariants, this type is always refcounted. +unsafe impl AlwaysRefCounted for Mm { + #[inline] + fn inc_ref(&self) { + // SAFETY: The pointer is valid since self is a reference. + unsafe { bindings::mmgrab(self.as_raw()) }; + } + + #[inline] + unsafe fn dec_ref(obj: NonNull) { + // SAFETY: The caller is giving up their refcount. + unsafe { bindings::mmdrop(obj.cast().as_ptr()) }; + } +} + +/// A wrapper for the kernel's `struct mm_struct`. +/// +/// This type is like [`Mm`], but with non-zero `mm_users`. It can only be used when `mm_users` can +/// be proven to be non-zero at compile-time, usually because the relevant code holds an `mmget` +/// refcount. It can be used to access the associated address space. +/// +/// The `ARef` smart pointer holds an `mmget` refcount. Its destructor may sleep. +/// +/// # Invariants +/// +/// Values of this type are always refcounted using `mmget`. The value of `mm_users` is non-zero. +#[repr(transparent)] +pub struct MmWithUser { + mm: Mm, +} + +// SAFETY: It is safe to call `mmput` on another thread than where `mmget` was called. +unsafe impl Send for MmWithUser {} +// SAFETY: All methods on `MmWithUser` can be called in parallel from several threads. +unsafe impl Sync for MmWithUser {} + +// SAFETY: By the type invariants, this type is always refcounted. +unsafe impl AlwaysRefCounted for MmWithUser { + #[inline] + fn inc_ref(&self) { + // SAFETY: The pointer is valid since self is a reference. + unsafe { bindings::mmget(self.as_raw()) }; + } + + #[inline] + unsafe fn dec_ref(obj: NonNull) { + // SAFETY: The caller is giving up their refcount. + unsafe { bindings::mmput(obj.cast().as_ptr()) }; + } +} + +// Make all `Mm` methods available on `MmWithUser`. +impl Deref for MmWithUser { + type Target = Mm; + + #[inline] + fn deref(&self) -> &Mm { + &self.mm + } +} + +// These methods are safe to call even if `mm_users` is zero. +impl Mm { + /// Call `mmgrab` on `current.mm`. + #[inline] + pub fn mmgrab_current() -> Option> { + // SAFETY: It's safe to get the `mm` field from current. + let mm = unsafe { + let current = bindings::get_current(); + (*current).mm + }; + + if mm.is_null() { + return None; + } + + // SAFETY: The value of `current->mm` is guaranteed to be null or a valid `mm_struct`. We + // just checked that it's not null. Furthermore, the returned `&Mm` is valid only for the + // duration of this function, and `current->mm` will stay valid for that long. + let mm = unsafe { Mm::from_raw(mm) }; + + // This increments the refcount using `mmgrab`. + Some(ARef::from(mm)) + } + + /// Returns a raw pointer to the inner `mm_struct`. + #[inline] + pub fn as_raw(&self) -> *mut bindings::mm_struct { + self.mm.get() + } + + /// Obtain a reference from a raw pointer. + /// + /// # Safety + /// + /// The caller must ensure that `ptr` points at an `mm_struct`, and that it is not deallocated + /// during the lifetime 'a. + #[inline] + pub unsafe fn from_raw<'a>(ptr: *const bindings::mm_struct) -> &'a Mm { + // SAFETY: Caller promises that the pointer is valid for 'a. Layouts are compatible due to + // repr(transparent). + unsafe { &*ptr.cast() } + } + + /// Calls `mmget_not_zero` and returns a handle if it succeeds. + #[inline] + pub fn mmget_not_zero(&self) -> Option> { + // SAFETY: The pointer is valid since self is a reference. + let success = unsafe { bindings::mmget_not_zero(self.as_raw()) }; + + if success { + // SAFETY: We just created an `mmget` refcount. + Some(unsafe { ARef::from_raw(NonNull::new_unchecked(self.as_raw().cast())) }) + } else { + None + } + } +} + +// These methods require `mm_users` to be non-zero. +impl MmWithUser { + /// Obtain a reference from a raw pointer. + /// + /// # Safety + /// + /// The caller must ensure that `ptr` points at an `mm_struct`, and that `mm_users` remains + /// non-zero for the duration of the lifetime 'a. + #[inline] + pub unsafe fn from_raw<'a>(ptr: *const bindings::mm_struct) -> &'a MmWithUser { + // SAFETY: Caller promises that the pointer is valid for 'a. The layout is compatible due + // to repr(transparent). + unsafe { &*ptr.cast() } + } + + /// Lock the mmap read lock. + #[inline] + pub fn mmap_read_lock(&self) -> MmapReadGuard<'_> { + // SAFETY: The pointer is valid since self is a reference. + unsafe { bindings::mmap_read_lock(self.as_raw()) }; + + // INVARIANT: We just acquired the read lock. + MmapReadGuard { + mm: self, + _nts: NotThreadSafe, + } + } + + /// Try to lock the mmap read lock. + #[inline] + pub fn mmap_read_trylock(&self) -> Option> { + // SAFETY: The pointer is valid since self is a reference. + let success = unsafe { bindings::mmap_read_trylock(self.as_raw()) }; + + if success { + // INVARIANT: We just acquired the read lock. + Some(MmapReadGuard { + mm: self, + _nts: NotThreadSafe, + }) + } else { + None + } + } +} + +/// A guard for the mmap read lock. +/// +/// # Invariants +/// +/// This `MmapReadGuard` guard owns the mmap read lock. +pub struct MmapReadGuard<'a> { + mm: &'a MmWithUser, + // `mmap_read_lock` and `mmap_read_unlock` must be called on the same thread + _nts: NotThreadSafe, +} + +impl Drop for MmapReadGuard<'_> { + #[inline] + fn drop(&mut self) { + // SAFETY: We hold the read lock by the type invariants. + unsafe { bindings::mmap_read_unlock(self.mm.as_raw()) }; + } +} From patchwork Fri Nov 22 15:40:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 13883303 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2A892E6916F for ; Fri, 22 Nov 2024 15:41:12 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id B24226B009C; Fri, 22 Nov 2024 10:41:11 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id AD3EF6B009F; Fri, 22 Nov 2024 10:41:11 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 900166B00A2; Fri, 22 Nov 2024 10:41:11 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id 6E3E56B009C for ; Fri, 22 Nov 2024 10:41:11 -0500 (EST) Received: from smtpin12.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id 32C951A17CD for ; Fri, 22 Nov 2024 15:41:11 +0000 (UTC) X-FDA: 82814143188.12.724DB71 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) by imf11.hostedemail.com (Postfix) with ESMTP id EEC0140004 for ; Fri, 22 Nov 2024 15:40:00 +0000 (UTC) Authentication-Results: imf11.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=hRIkoEio; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf11.hostedemail.com: domain of 3EqZAZwkKCKEBMJDFSZIMHPPHMF.DPNMJOVY-NNLWBDL.PSH@flex--aliceryhl.bounces.google.com designates 209.85.128.74 as permitted sender) smtp.mailfrom=3EqZAZwkKCKEBMJDFSZIMHPPHMF.DPNMJOVY-NNLWBDL.PSH@flex--aliceryhl.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1732289975; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=rpRgqzz82sEijd8ek2p3HLExnZlmTISx521fYTMYg7A=; b=hDafaRr9tDDWn8qyaqiASgpLlWBIn2Bk/7NgT5EVECp67QU3OXlDMM1QNikaZIApPnkQqJ Kxnvvc2AGMYiYdgaM5vjwt5kyWNONRITFMvHA5CuC1h8+xrusl21qN2l51KI7mbtuNDoZI covPEFm4lGMaH0AfyIh2pjGV2yGukR0= ARC-Authentication-Results: i=1; imf11.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=hRIkoEio; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf11.hostedemail.com: domain of 3EqZAZwkKCKEBMJDFSZIMHPPHMF.DPNMJOVY-NNLWBDL.PSH@flex--aliceryhl.bounces.google.com designates 209.85.128.74 as permitted sender) smtp.mailfrom=3EqZAZwkKCKEBMJDFSZIMHPPHMF.DPNMJOVY-NNLWBDL.PSH@flex--aliceryhl.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1732289975; a=rsa-sha256; cv=none; b=ipxikfMBKtJroS4hP1bPHDhk6bZgUhaP4Re/AvywBbmlDBXBLRKYStkhd6g5VZ0rEiqg3I 5xChXDSLdzDBzsg+fBZq17oCqJgpqiQHR/Mig0dYmguAJqxxXEZBWGEUcPGyMTUVUH3DQw 7oDIWH1TM3Zy9pkVfjVjpBjelERtX7c= Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43159c07193so19857765e9.0 for ; Fri, 22 Nov 2024 07:41:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1732290067; x=1732894867; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=rpRgqzz82sEijd8ek2p3HLExnZlmTISx521fYTMYg7A=; b=hRIkoEio3+HX4Jqrl3WCN5vMa2kP8+rXJ9T+aULDSTIS44GFdQ5bvsqIZGhQTqcgPl cCnTls2UEH7URqG4tDQC7czt07f5CTfz8cHxYvmTxz407SRJj+2tlqzZ0vvDdeaCDcD6 48IqaHsknx5iTvCr/reKL4PMIywt+KsYrnTqu6AexprXvjK3oNYenpQ0bNZeFf1nvnCT tK/q0G3F/1KyP5BFOirfEsb9GAegNd+j1D1lbCiD3Fatcp5ce3Kiak9hTw8+ewUol+8g 1vju5SwPm0EYncPf4Vgw2gwO8rLpIWK3tVgBo3XPZIVww4ix2wwFvUXxw38dC23NiROT ffag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732290067; x=1732894867; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=rpRgqzz82sEijd8ek2p3HLExnZlmTISx521fYTMYg7A=; b=OwDVNxyIqQHytBaw0758aK3Ywf0XI7jOb4s5Xgt58FRnsJHuuyghztuL824UJ/lmDe o4+u9MBWqDQ+4tc7Ybv935AhLnSdWRqQLVJ+FkFR0g6qgceGdH8pRPcgGvuX6KjBsiac rmgwmnaNZwLzd+pu3z9YlcUxfZkZZzqh+wj4Je3op1hLHvF1yq1aouWeWuxdZFJX2LLU ErIrEGE2xjGtgkzTGpAznX0G/b0HDRaHftSA3LXAmBxd98/BsnCqdZuI1vA4tbv3ZcNP ECeB+IH4oLyftoU8lrfbvML54nHryRLdYXWBLIwo/6pPQxEoZn65UdMzo9+bYYqfqSH8 ovjg== X-Forwarded-Encrypted: i=1; AJvYcCWzC4+bgGZ1BoflGsX8L5BeAfuQNqH7YJpck+Recg734sZ5Af4cXMP13o8Rx1+pjxmYMBVeQJe4eA==@kvack.org X-Gm-Message-State: AOJu0Yws58wzgwAdWIw8oW6ITpdxdRoWXe/yj1kOtD7WCAZJKnOTPa1O uxliqEH40hG8D2pkjsYZnYQMrNvvPS83ySStQM80MJcxSAPd89fNc4miiIJfBSTLZHhlty/B80b jiFcPKnPX2HQqPw== X-Google-Smtp-Source: AGHT+IESpHOo7osW11QO7Begd6/hgV+HnuolBUZ1nG+UDTyG0tnysPZ8TSCOWeW0XPKFP+U93HN/frQCkrDDEt4= X-Received: from aliceryhl.c.googlers.com ([fda3:e722:ac3:cc00:68:fe9:ac10:f29e]) (user=aliceryhl job=sendgmr) by 2002:a05:600c:1d0f:b0:42e:e66c:2a8e with SMTP id 5b1f17b1804b1-433ce4fa122mr290465e9.7.1732290066790; Fri, 22 Nov 2024 07:41:06 -0800 (PST) Date: Fri, 22 Nov 2024 15:40:27 +0000 In-Reply-To: <20241122-vma-v9-0-7127bfcdd54e@google.com> Mime-Version: 1.0 References: <20241122-vma-v9-0-7127bfcdd54e@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=9346; i=aliceryhl@google.com; h=from:subject:message-id; bh=r818IxuzXbN9g3c4yrMD7Y71e/4bceEXKMyljx6a6J0=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBnQKYH5R8PxJfDPHVIRhFqASmlS4/vOqLyQrhYP 00O1+uub3yJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ0CmBwAKCRAEWL7uWMY5 RthAD/4+eTK7BgZe7rEzEuKSggCjNmJFDiXSil0wpt6Mtne5FMxrKaoPhFbPYUG7/eQKsmKd229 R+9N4RwgUgUz9BDTGtPkfqyzHqDWGgcDvh2HBj182rXM5D8w74KVjyOaD6qLk6K4zdAZxXKjbfQ 2vVRpOmJfMVsNxsv86dNQ+D98nJ0LmV2m6gqctO1QAIsXh38mtiOMuvFDh4NlHe0qyLeQp/aoD/ t8PsiCifW8wxZl5nfaOS1E4RuxMvOM2dxx0zrqWIfLMAE2RlhCrZpMYwnwVifnlvhRljlRmkbPX XFFk49kIp7UkagsYcfTJLpdeEIJlv/scIG8ko6s2WuT8XvSQOL14tgt8d2W1Z88SQD6++dY432o POxTp6FvrQbGURx2KiscUqumI4RiGASEFAjaBLWjk8j1qDcBDUp0nz1E1sOuukO9ibjVE61txXK PnGgib++npZ5+cYCldHT/A22ixyl9VwI3s0+iUGGJlJo1Tu7sqjaLd42Az9hG6a0PTW4Q5kXVcE Hsh7yvtZqWvj2o5XbjW9n2WGPZnQFv07376GF34phwW9EqaYwjLbjjHEGwiBQ2PpaL/Z4CgHc52 I48IUA9YXGDW+Vbed1yYkq9UwLdrLtszSN3Nvb9VOK6rEHAtc/liw2mXu9jYxYry7ThWaXmPpnx c1Ug0Ul61WNzz6A== X-Mailer: b4 0.13.0 Message-ID: <20241122-vma-v9-2-7127bfcdd54e@google.com> Subject: [PATCH v9 2/8] mm: rust: add vm_area_struct methods that require read access From: Alice Ryhl To: Miguel Ojeda , Matthew Wilcox , Lorenzo Stoakes , Vlastimil Babka , John Hubbard , "Liam R. Howlett" , Andrew Morton , Greg Kroah-Hartman , Arnd Bergmann , Christian Brauner , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl , Andreas Hindborg X-Rspam-User: X-Rspamd-Server: rspam03 X-Rspamd-Queue-Id: EEC0140004 X-Stat-Signature: noscbihgccuszj76ssnyo6sjtfw6z74o X-HE-Tag: 1732290000-928771 X-HE-Meta: U2FsdGVkX18JhuIK3AGGQt7/0NOtXibDVTVCekDem3SOy6fcAIUmxmfBBD/hHWIx0EZ2CmYWlNR7WK8XUR6SKIwgf+x2L5TOyOWx+fLZetlGUKvG98dkWC1OrjYrRUutESEDoqx+mOZL/p45fOfaDmI74bn0XwG56ZbDQvxgBeCRRgCXm/irQYcsN3qJqFslu2hoZYjyWq5xDP+DM78eRrIGDn53O96FieJdjpguf/CqkWVkybpRoK+lcYxjDBi1HqIVF2A7CYEuuQ8x/3tLJRNqXL73/fkciCu5yvTedlZ82WiNOl2YtrrCfTvut2/2u5PoFp3rDZ4KRUm/G2zJ5ikvHTmUdDTpVpd/mthHgREdIwzRCYFvMeDB9ii9FXIklRaF8dXHDNZ2O3wCiBKvxmEPBPYkI+BbeRnIiFmZ7T1DNf7v7xt5yfPjtlxu3xJXVWqnPDt8USNubvTvhsXhTHlsHXo7+PGP6jtnyThA/ZeMZwgasdPE2RVdS1FaqNcwYu7+HUL0f9tfbeHNP6SNVpAYcIlgVf1OYbrVr8C5YyKnYEopt4lNMPxCV4XL9f6rIamn3DwEHQx1rwc701E3DBN7hWIB4HRRpgMFSeJFGzNbrs0jBB6Nvs79tu5O06rqQZ+e4eiFSjoo4m0ySJzJ7eywfqoHWzUjx53OE3IO241VmKnVPkcq/b1I2VSK4DFUd+vjZfFWYb4YKsanZP1A8vs2pM37XQXNzLwPdR/wbkAStn4OLvpKdu9PKZXA85GPAwky27YAv16F80pCCdGB4dP59BdSRf+COQub+Bjs2hVP0bDvpUUAcu5iE8u6fak0VbVzo/5YRwL3y1CYxfYja+a/hahR4UePZpg4e4+DWRQHTB3Fw5hb3sj0zXJQDndmlzDdPCOgWswOpBPgg/g2gBt6NcsFR4kpV+n/D+c8s+lICQ95b3a1W09wdWiMlqQVXYme6lE+8isC4sARI13 q6kOQpNH hj8LdAEL72viP6PkvzDD73sWuFniTpSrZsgbuamJM7BWHpf5VDgkbpypE2052usX0OHxxHuJ4Se+pUB6r+5kNsPrXRo7vCxPr/V6qJJoWW9beqcjS8h6FmFrvgH5tMUEHIJupnrfFkfdLBLKObE2xU+mSarl6UUORF1sA9MFFf+hObU6eESqa7Te0kDGtjEBiTkpCpp6Ux+iQN6M1ehpr6WlXACHSCXMqKckzqc/WYR54hRldQPZIu2y0DPsqEr/Kjbm0WAVyDPNXjeJZbEHaWZ2KCqzv2hrRiaKhXtwL7w6EWztEDDAdqQYKboLnPLBQ6OFDSZXlx6TsUJVLQ8AUB1OODMAfahaAdTrpa3keI4PvbNzgE2b4/azc/47T77XFi1VB+3t3LXOs5TNlENpJYHoij82uw/NAxEFb3sL+KDJ0B9QYcnEMXRaCBUsM6seD7ztj5lao4/GKxAHxjbfTs+HYvn80qA56Q+euVI/YGmAbM3iFlysE1+6itzszyf5t5EP+5sgOBf+xsuvs0cw5EnYj+61vscYzBF72Zx10lPXTuSzidWcC0B7XeXUUVIE8XfmgqEfkjePn8lkx+XeukzzbRvtU/WArSt01rCDE/HQvS10vI6KYGNiNLAXGlNqNLYXxueLB1Q3JgSIO5BhcZbymsxlvC01sC7Or4qCJsd3BRjhTEwzzz7f3n+4E9QKKWXOpvwFp6x0mf6cJ5ggOXTtKjg== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: This adds a type called VmAreaRef which is used when referencing a vma that you have read access to. Here, read access means that you hold either the mmap read lock or the vma read lock (or stronger). Additionally, a vma_lookup method is added to the mmap read guard, which enables you to obtain a &VmAreaRef in safe Rust code. This patch only provides a way to lock the mmap read lock, but a follow-up patch also provides a way to just lock the vma read lock. Acked-by: Lorenzo Stoakes (for mm bits) Signed-off-by: Alice Ryhl --- rust/helpers/mm.c | 6 ++ rust/kernel/mm.rs | 21 ++++++ rust/kernel/mm/virt.rs | 176 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 203 insertions(+) diff --git a/rust/helpers/mm.c b/rust/helpers/mm.c index 7201747a5d31..7b72eb065a3e 100644 --- a/rust/helpers/mm.c +++ b/rust/helpers/mm.c @@ -37,3 +37,9 @@ void rust_helper_mmap_read_unlock(struct mm_struct *mm) { mmap_read_unlock(mm); } + +struct vm_area_struct *rust_helper_vma_lookup(struct mm_struct *mm, + unsigned long addr) +{ + return vma_lookup(mm, addr); +} diff --git a/rust/kernel/mm.rs b/rust/kernel/mm.rs index 84cba581edaa..ace8e7d57afe 100644 --- a/rust/kernel/mm.rs +++ b/rust/kernel/mm.rs @@ -12,6 +12,8 @@ }; use core::{ops::Deref, ptr::NonNull}; +pub mod virt; + /// A wrapper for the kernel's `struct mm_struct`. /// /// Since `mm_users` may be zero, the associated address space may not exist anymore. You can use @@ -210,6 +212,25 @@ pub struct MmapReadGuard<'a> { _nts: NotThreadSafe, } +impl<'a> MmapReadGuard<'a> { + /// Look up a vma at the given address. + #[inline] + pub fn vma_lookup(&self, vma_addr: usize) -> Option<&virt::VmAreaRef> { + // SAFETY: We hold a reference to the mm, so the pointer must be valid. Any value is okay + // for `vma_addr`. + let vma = unsafe { bindings::vma_lookup(self.mm.as_raw(), vma_addr as _) }; + + if vma.is_null() { + None + } else { + // SAFETY: We just checked that a vma was found, so the pointer is valid. Furthermore, + // the returned area will borrow from this read lock guard, so it can only be used + // while the mmap read lock is still held. + unsafe { Some(virt::VmAreaRef::from_raw(vma)) } + } + } +} + impl Drop for MmapReadGuard<'_> { #[inline] fn drop(&mut self) { diff --git a/rust/kernel/mm/virt.rs b/rust/kernel/mm/virt.rs new file mode 100644 index 000000000000..6df145fea128 --- /dev/null +++ b/rust/kernel/mm/virt.rs @@ -0,0 +1,176 @@ +// SPDX-License-Identifier: GPL-2.0 + +// Copyright (C) 2024 Google LLC. + +//! Virtual memory. + +use crate::{bindings, types::Opaque}; + +/// A wrapper for the kernel's `struct vm_area_struct` with read access. +/// +/// It represents an area of virtual memory. +/// +/// # Invariants +/// +/// The caller must hold the mmap read lock or the vma read lock. +#[repr(transparent)] +pub struct VmAreaRef { + vma: Opaque, +} + +// Methods you can call when holding the mmap or vma read lock (or strong). They must be usable no +// matter what the vma flags are. +impl VmAreaRef { + /// Access a virtual memory area given a raw pointer. + /// + /// # Safety + /// + /// Callers must ensure that `vma` is valid for the duration of 'a, and that the mmap or vma + /// read lock (or stronger) is held for at least the duration of 'a. + #[inline] + pub unsafe fn from_raw<'a>(vma: *const bindings::vm_area_struct) -> &'a Self { + // SAFETY: The caller ensures that the invariants are satisfied for the duration of 'a. + unsafe { &*vma.cast() } + } + + /// Returns a raw pointer to this area. + #[inline] + pub fn as_ptr(&self) -> *mut bindings::vm_area_struct { + self.vma.get() + } + + /// Returns the flags associated with the virtual memory area. + /// + /// The possible flags are a combination of the constants in [`flags`]. + #[inline] + pub fn flags(&self) -> vm_flags_t { + // SAFETY: By the type invariants, the caller holds at least the mmap read lock, so this + // access is not a data race. + unsafe { (*self.as_ptr()).__bindgen_anon_2.vm_flags as _ } + } + + /// Returns the (inclusive) start address of the virtual memory area. + #[inline] + pub fn start(&self) -> usize { + // SAFETY: By the type invariants, the caller holds at least the mmap read lock, so this + // access is not a data race. + unsafe { (*self.as_ptr()).__bindgen_anon_1.__bindgen_anon_1.vm_start as _ } + } + + /// Returns the (exclusive) end address of the virtual memory area. + #[inline] + pub fn end(&self) -> usize { + // SAFETY: By the type invariants, the caller holds at least the mmap read lock, so this + // access is not a data race. + unsafe { (*self.as_ptr()).__bindgen_anon_1.__bindgen_anon_1.vm_end as _ } + } + + /// Zap pages in the given page range. + /// + /// This clears page table mappings for the range at the leaf level, leaving all other page + /// tables intact, and freeing any memory referenced by the VMA in this range. That is, + /// anonymous memory is completely freed, file-backed memory has its reference count on page + /// cache folio's dropped, any dirty data will still be written back to disk as usual. + #[inline] + pub fn zap_page_range_single(&self, address: usize, size: usize) { + // SAFETY: By the type invariants, the caller has read access to this VMA, which is + // sufficient for this method call. This method has no requirements on the vma flags. Any + // value of `address` and `size` is allowed. + unsafe { + bindings::zap_page_range_single( + self.as_ptr(), + address as _, + size as _, + core::ptr::null_mut(), + ) + }; + } +} + +/// The integer type used for vma flags. +#[doc(inline)] +pub use bindings::vm_flags_t; + +/// All possible flags for [`VmAreaRef`]. +pub mod flags { + use super::vm_flags_t; + use crate::bindings; + + /// No flags are set. + pub const NONE: vm_flags_t = bindings::VM_NONE as _; + + /// Mapping allows reads. + pub const READ: vm_flags_t = bindings::VM_READ as _; + + /// Mapping allows writes. + pub const WRITE: vm_flags_t = bindings::VM_WRITE as _; + + /// Mapping allows execution. + pub const EXEC: vm_flags_t = bindings::VM_EXEC as _; + + /// Mapping is shared. + pub const SHARED: vm_flags_t = bindings::VM_SHARED as _; + + /// Mapping may be updated to allow reads. + pub const MAYREAD: vm_flags_t = bindings::VM_MAYREAD as _; + + /// Mapping may be updated to allow writes. + pub const MAYWRITE: vm_flags_t = bindings::VM_MAYWRITE as _; + + /// Mapping may be updated to allow execution. + pub const MAYEXEC: vm_flags_t = bindings::VM_MAYEXEC as _; + + /// Mapping may be updated to be shared. + pub const MAYSHARE: vm_flags_t = bindings::VM_MAYSHARE as _; + + /// Page-ranges managed without `struct page`, just pure PFN. + pub const PFNMAP: vm_flags_t = bindings::VM_PFNMAP as _; + + /// Memory mapped I/O or similar. + pub const IO: vm_flags_t = bindings::VM_IO as _; + + /// Do not copy this vma on fork. + pub const DONTCOPY: vm_flags_t = bindings::VM_DONTCOPY as _; + + /// Cannot expand with mremap(). + pub const DONTEXPAND: vm_flags_t = bindings::VM_DONTEXPAND as _; + + /// Lock the pages covered when they are faulted in. + pub const LOCKONFAULT: vm_flags_t = bindings::VM_LOCKONFAULT as _; + + /// Is a VM accounted object. + pub const ACCOUNT: vm_flags_t = bindings::VM_ACCOUNT as _; + + /// Should the VM suppress accounting. + pub const NORESERVE: vm_flags_t = bindings::VM_NORESERVE as _; + + /// Huge TLB Page VM. + pub const HUGETLB: vm_flags_t = bindings::VM_HUGETLB as _; + + /// Synchronous page faults. (DAX-specific) + pub const SYNC: vm_flags_t = bindings::VM_SYNC as _; + + /// Architecture-specific flag. + pub const ARCH_1: vm_flags_t = bindings::VM_ARCH_1 as _; + + /// Wipe VMA contents in child on fork. + pub const WIPEONFORK: vm_flags_t = bindings::VM_WIPEONFORK as _; + + /// Do not include in the core dump. + pub const DONTDUMP: vm_flags_t = bindings::VM_DONTDUMP as _; + + /// Not soft dirty clean area. + pub const SOFTDIRTY: vm_flags_t = bindings::VM_SOFTDIRTY as _; + + /// Can contain `struct page` and pure PFN pages. + pub const MIXEDMAP: vm_flags_t = bindings::VM_MIXEDMAP as _; + + /// MADV_HUGEPAGE marked this vma. + pub const HUGEPAGE: vm_flags_t = bindings::VM_HUGEPAGE as _; + + /// MADV_NOHUGEPAGE marked this vma. + pub const NOHUGEPAGE: vm_flags_t = bindings::VM_NOHUGEPAGE as _; + + /// KSM may merge identical pages. + pub const MERGEABLE: vm_flags_t = bindings::VM_MERGEABLE as _; +} From patchwork Fri Nov 22 15:40:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 13883304 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3F5E7E6916D for ; Fri, 22 Nov 2024 15:41:14 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id BC1676B00A2; Fri, 22 Nov 2024 10:41:12 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id B6F506B00A4; Fri, 22 Nov 2024 10:41:12 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id A115E6B00B3; Fri, 22 Nov 2024 10:41:12 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 83BD46B00A2 for ; Fri, 22 Nov 2024 10:41:12 -0500 (EST) Received: from smtpin11.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 3C161AF00B for ; Fri, 22 Nov 2024 15:41:12 +0000 (UTC) X-FDA: 82814143776.11.1CCE3D2 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) by imf13.hostedemail.com (Postfix) with ESMTP id CEC6120008 for ; Fri, 22 Nov 2024 15:40:10 +0000 (UTC) Authentication-Results: imf13.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=UoJZofie; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf13.hostedemail.com: domain of 3FaZAZwkKCKQEPMGIVcLPKSSKPI.GSQPMRYb-QQOZEGO.SVK@flex--aliceryhl.bounces.google.com designates 209.85.128.73 as permitted sender) smtp.mailfrom=3FaZAZwkKCKQEPMGIVcLPKSSKPI.GSQPMRYb-QQOZEGO.SVK@flex--aliceryhl.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1732290002; a=rsa-sha256; cv=none; b=WgyviDE5HyKH32AknXl0EIpCtqM5TnXgDyT0TPFuXsPFVFSpmwk46cC1eguUxicxfWAYht Xe7BGFoUvvFyISKe56h7cXqAlx+1gVRtO3zMclZ1cjFjI3HDC7tNslNtN8kA4t9Dm0akEW OzwUcYFyb6nwWGpLqCRmXx0g4Xq8/AI= ARC-Authentication-Results: i=1; imf13.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=UoJZofie; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf13.hostedemail.com: domain of 3FaZAZwkKCKQEPMGIVcLPKSSKPI.GSQPMRYb-QQOZEGO.SVK@flex--aliceryhl.bounces.google.com designates 209.85.128.73 as permitted sender) smtp.mailfrom=3FaZAZwkKCKQEPMGIVcLPKSSKPI.GSQPMRYb-QQOZEGO.SVK@flex--aliceryhl.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1732290002; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=hYxLUop5CFzWW+VlEDd2o5nmfczomOBA2awiJyr0ME8=; b=xfqbmeXtQyEWmOr7PnZm1mT2wzHX4rmOFkMbzjRZXSQThA+f0pZrLtrKF5q1hDW7vKc+4t TQL2snuiM7LpJYNBuh+fKW5irbmCCe7KGBO8kgrH0KevlK/eqwiqA/lSKubMWR+PsSCEF8 MA9K31lLM8CJ75VQgAwj8X/VpX8BmiY= Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-4315eaa3189so19779285e9.1 for ; Fri, 22 Nov 2024 07:41:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1732290069; x=1732894869; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=hYxLUop5CFzWW+VlEDd2o5nmfczomOBA2awiJyr0ME8=; b=UoJZofieHf4Vh+2IRqLqiXdfCAcT6ln3zSBYjKTtGQNVG5yyKsLHX7p+YFKNM5h8ab XYsbx0betti0cPC/vu6+e8BWonSxVj80dxhVD871sB8MF0TO/Ncie0BzQ296qVQjr6mA 6LniRML9Odj1S4GSxyVrD21xcu1tPMstFih9VQ7UtBwYoXU8KSjccLIEqol8qSQZ+HJ6 D3IrCYnU/TKrEz32+BQt+33GqSVwlmiUrnEcLxjddd2uh1l+tT212H73++K4MoL7nymo hjfQ8DXOK1z2Wpe8bMgf2BGPd9LU3KQt+ENRkqme7Mi1Tj1y7BHIQSdrYeWEXbZU4kPU sc6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732290069; x=1732894869; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=hYxLUop5CFzWW+VlEDd2o5nmfczomOBA2awiJyr0ME8=; b=HwEWiFPamtTIgIeiv9h35eucr63S8BUzpe/52b+EDx+BAoEUJH0QKL5XS1msgxNIxx xpoPu8meRyLOep37a2Y2Fw4JRDdimUU1u5VTEdO8ByvL5iJEPvUxIFlh6/cCFa4sQ3F0 1kv1aSMRzzk04Niy89GwW6Hbwv8FUTgnX2t3drEndS4yAD9La+CwfiLFyH9H+BNH4LBq QG7GS513XMdDoVEQ7Tseb9/wTo8pTBN7fEztGu8/shSGhKOCGme6DdXOezX5GHwMVgT6 XrqMMJ8QSYNzbVmjgSRdzdyqYbFZU/sdodbKthfHI376YD7U4QDKomZ93eYPQvijK2RQ kY3g== X-Forwarded-Encrypted: i=1; AJvYcCWb9jEH1hsriLCHI51z71drxcmZH4J4TnePJUxsoMe6Ed+dt4w62dUfrgPkvPSD19ZxnhXV8vN6oQ==@kvack.org X-Gm-Message-State: AOJu0YyLo7BfVwVBcFUBNRPb1cmztyvGwDnclUjvSLYsqVtIiEGjwDze Z1QySKCulDXywWCidFID/BzPQT6/57YQDNAI5xj+AM6jua6GuT+6DBxu0v0+SE1mr9HJYVKZcdW awPUqrBGD3XItFw== X-Google-Smtp-Source: AGHT+IEIKcYcdx6MVWct3b+zC6qUnAKNrcyvu2pxBZsUhCYdS8JAEE1PK1hh3wfuatjl0mJTsbCFOi6Ydty6B7I= X-Received: from aliceryhl.c.googlers.com ([fda3:e722:ac3:cc00:68:fe9:ac10:f29e]) (user=aliceryhl job=sendgmr) by 2002:a05:600c:35c4:b0:42e:d463:3ea7 with SMTP id 5b1f17b1804b1-433ce4b2e61mr290325e9.3.1732290069096; Fri, 22 Nov 2024 07:41:09 -0800 (PST) Date: Fri, 22 Nov 2024 15:40:28 +0000 In-Reply-To: <20241122-vma-v9-0-7127bfcdd54e@google.com> Mime-Version: 1.0 References: <20241122-vma-v9-0-7127bfcdd54e@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=3694; i=aliceryhl@google.com; h=from:subject:message-id; bh=0kJbDQ2R2LaDZDdpCyVYpygYX3kC3nlpmnRFMMkub60=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBnQKYIvyS3vYvaLl2hnXmTUoNnpgWbUaM0XAaBO 5Hd920hx1WJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ0CmCAAKCRAEWL7uWMY5 RpyREACin3dfUAa6PzIT6e2p6DXDZa92oR0hkUItIreeOaz+aDB7QYUz1TQHXS+0/ggVZfuQ5qM PW6oK14yS9QIiu6J0zqJlQ+h9CcPk6ycDjrkQKKQQNlnLaoA1KUSopOA0/dXkvOqDZx7eh0rczd yRoj+CT4F/YkIYDETENVy6KMVZIMklx4enehQes6M1v/AftWAvbN7ZluoxYjzTtcsgsw2dpLQyx 7qtm2TIoTqNlAKvdXoxetMePlgiR9OmK4DFj9zSoknu222UrRAZLZrEQ8Us3nMTCd6rFI9dsVrh SCqn+C7ZJgAOZP0UDU7gBbCXtL0TdYszA+ja48fRu7t9eb8GZZZmuDMM6i2jHKgKcw5HKVmPW2U H4YawniEx4YivnbG2E58oYT2t6bhlDrlBu4OZ2PFnSo0O0TvsiX8919xV8I3dfRkiGz7bpC4icL Eeyu4sxt/8cUq/Bdr52weSKg05oKqakBtcrCfbQ0SFx0QyO/X+ZPpuoUjw5l6SIRSglewAePJui rlIdtOTOVSpaMVVvRJiCG1X7KKQLnOa9o/znQ2gVJjMOYupgju8s87HWBq/AKVyzZPO+9LI9JxH b7afReIFODoqSqosl36aTz7325JcyO+7kKY7zNDD5KnoFhgQa/Hj/u1nSsxHHiPTc/MT1lNXiLA Zar/2JKK9H6pk4Q== X-Mailer: b4 0.13.0 Message-ID: <20241122-vma-v9-3-7127bfcdd54e@google.com> Subject: [PATCH v9 3/8] mm: rust: add vm_insert_page From: Alice Ryhl To: Miguel Ojeda , Matthew Wilcox , Lorenzo Stoakes , Vlastimil Babka , John Hubbard , "Liam R. Howlett" , Andrew Morton , Greg Kroah-Hartman , Arnd Bergmann , Christian Brauner , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl , Andreas Hindborg X-Rspam-User: X-Rspamd-Queue-Id: CEC6120008 X-Rspamd-Server: rspam01 X-Stat-Signature: 4y733xnmc6nu35owpj5c64sreee84a1i X-HE-Tag: 1732290010-577171 X-HE-Meta: U2FsdGVkX1++F7kvOsXGEfN1IPu8XGblZvzrj8INydLuq8JYWSObI4r3fjo8qOQq3DGDQwT6Fk7FW+CbmmJVIiqIL2UtDGUHo3qguMNoFGOQPaHV9mf/TeSlbmUGisGOtq6wJHhFvKX+LRj14i2QYRqTmdLQUOWNcABKpyrx+aNWCZTomQj5IMVDlbOXUXyk20dJbO5zevRR1gSbpdSWG+xZOW+uxKJNeontvY9qJbVntgUL/7wDGlCtq8eZVVj1CM/h0hmKHOHupizSUfP2TWzjhY9JGBMqfH3yTQsOjvvh0gpHWXJbCo9sU0tRRW/xo96aoYAVn84w/U13++QK1fKZl3lPUJWkjU+dOR3EqzSOSHwyaorNPAIhRt+eCjD76X+en3K2dlFfXlaqzxKmhF0O1VXYULHLyHo/Vw0JufFnBhkcQi7Xs5B0bNvGG80HdV0CnH3cTEmdVAVXi87uoVarGAvBVods7zkgaznLUNa8QuDtZbXiipoq0VRMDjGyWE83hHWMtZ4Yn6Zo83DCLJtd6QVOl9S70j6v5BcSIrjEtJCk3Ab4TPad/wwkbSvN9GobwXaW6xsm6snFbEgH6DxtEzaMa0dynTIRLU3G40TQyHjhlBLn0YmDB1I34APXd8Q4VKKX7OAxQuQQlMxQHP2WEZj/wgb0CLtyO86wqL/35Xw/1Ja4ujZfa6RwelKIyzj/eDhspr1JjaeDm+0KuTa4P5y5kBqcCQ2JYwoDQJ4jNAnMywVIQL4c3oLbUTl6TSs0LHkYvc00JnWFdDFKbXNblivcHjsjRdPl9x5RPKNE1046t359YffVYeQINhVNo6glGRvzJGQD4LKjxsuAimeeFTBqghMzN8oVspjjzjhCxUAozZdvSCbZrfWNFg4VcPV8DLD+okMo02x2OmBnBy1NrkNN+vmUexeoPLqT3LhYgwGjUrTdb3CMe9O2R3lb+a8Pw2aZdEf+Zhlbpoj Q5/sfcEr b/6Ur4bz0FWeRa0k8nWGcq2HGReHMocWdVkAaDQUKjy0AsCqM71YOmKUSNA+brkt6+bPDUZ/amzS/KeaCaR2xzUlJuZtC+UjTpd7ItU9YkIlkTkhCYOfkkogIAo/0wQsO6jMnqgoXJ+g/BkC5+mKm2H90vgkFcV6J4UVz/pzOjGQxAC8PzrJggJQ9tc5VWU+xvwwdpUfUaWhjdeNgBieV/rWHRUo3QXyVAvSEr91lRUzpplRtqRhuDml9P2Zid7Y6u7qWmY8maAVKZurd+LDI8b4zkqe0emhrobcU1l+lUlQYdszv7/Z82a0LhE3FJGPwWlNZvgViAX5IIr6IJ+cJ1anL7XZVIJNhbGomaEaL0JNxe7VEk4jYnpN9qpbXfzenbSVTIo+v0teWACd7sDq4ev9qBRCNYsNJPV2Xz1Ibgm7S6e7m7kXVs4JIGPB0r4asbKBV/Nc7Sq12VtZZ5MuN2d+S1l3M1G2Cd8oTBryBx8ivXTsgXFBHIfGf6axW4sHST9y2R1VYjY2wTq8v+WirWbQak1tSIQhlXD7ejcyCW+79pjkX4HUxTDNKK9Zyy0PMzkGRcdG9LkzENZxr4Rt5ngm81KxRBiAdgxFSsMpa7acebADgFzNcsfAEL51J+fPlkXMSfPElMi9Wa2z6WGuqFn+8J9xPqv7k8t6ra9AOs+SzVdYU7gcQWv4kXt7F8alLP8nTb0so2murFPs= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000004, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: The vm_insert_page method is only usable on vmas with the VM_MIXEDMAP flag, so we introduce a new type to keep track of such vmas. The approach used in this patch assumes that we will not need to encode many flag combinations in the type. I don't think we need to encode more than VM_MIXEDMAP and VM_PFNMAP as things are now. However, if that becomes necessary, using generic parameters in a single type would scale better as the number of flags increases. Acked-by: Lorenzo Stoakes (for mm bits) Signed-off-by: Alice Ryhl --- rust/kernel/mm/virt.rs | 70 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/rust/kernel/mm/virt.rs b/rust/kernel/mm/virt.rs index 6df145fea128..3e494e40b530 100644 --- a/rust/kernel/mm/virt.rs +++ b/rust/kernel/mm/virt.rs @@ -4,7 +4,14 @@ //! Virtual memory. -use crate::{bindings, types::Opaque}; +use crate::{ + bindings, + error::{to_result, Result}, + page::Page, + types::Opaque, +}; + +use core::ops::Deref; /// A wrapper for the kernel's `struct vm_area_struct` with read access. /// @@ -85,6 +92,67 @@ pub fn zap_page_range_single(&self, address: usize, size: usize) { ) }; } + + /// Check whether the `VM_MIXEDMAP` flag is set. + /// + /// This can be used to access methods that require `VM_MIXEDMAP` to be set. + #[inline] + pub fn as_mixedmap_vma(&self) -> Option<&VmAreaMixedMap> { + if self.flags() & flags::MIXEDMAP != 0 { + // SAFETY: We just checked that `VM_MIXEDMAP` is set. All other requirements are + // satisfied by the type invariants of `VmAreaRef`. + Some(unsafe { VmAreaMixedMap::from_raw(self.as_ptr()) }) + } else { + None + } + } +} + +/// A wrapper for the kernel's `struct vm_area_struct` with read access and `VM_MIXEDMAP` set. +/// +/// It represents an area of virtual memory. +/// +/// # Invariants +/// +/// The caller must hold the mmap read lock or the vma read lock. The `VM_MIXEDMAP` flag must be +/// set. +#[repr(transparent)] +pub struct VmAreaMixedMap { + vma: VmAreaRef, +} + +// Make all `VmAreaRef` methods available on `VmAreaMixedMap`. +impl Deref for VmAreaMixedMap { + type Target = VmAreaRef; + + #[inline] + fn deref(&self) -> &VmAreaRef { + &self.vma + } +} + +impl VmAreaMixedMap { + /// Access a virtual memory area given a raw pointer. + /// + /// # Safety + /// + /// Callers must ensure that `vma` is valid for the duration of 'a, and that the mmap read lock + /// (or stronger) is held for at least the duration of 'a. The `VM_MIXEDMAP` flag must be set. + #[inline] + pub unsafe fn from_raw<'a>(vma: *const bindings::vm_area_struct) -> &'a Self { + // SAFETY: The caller ensures that the invariants are satisfied for the duration of 'a. + unsafe { &*vma.cast() } + } + + /// Maps a single page at the given address within the virtual memory area. + /// + /// This operation does not take ownership of the page. + #[inline] + pub fn vm_insert_page(&self, address: usize, page: &Page) -> Result { + // SAFETY: The caller has read access and has verified that `VM_MIXEDMAP` is set. The page + // is order 0. The address is checked on the C side so it can take any value. + to_result(unsafe { bindings::vm_insert_page(self.as_ptr(), address as _, page.as_ptr()) }) + } } /// The integer type used for vma flags. From patchwork Fri Nov 22 15:40:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 13883305 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0DBA1E6916C for ; Fri, 22 Nov 2024 15:41:17 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 15FCD6B00B3; Fri, 22 Nov 2024 10:41:15 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 111F16B00B6; Fri, 22 Nov 2024 10:41:15 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id EF3806B00B8; Fri, 22 Nov 2024 10:41:14 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id CE7826B00B3 for ; Fri, 22 Nov 2024 10:41:14 -0500 (EST) Received: from smtpin27.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 5787FC1870 for ; Fri, 22 Nov 2024 15:41:14 +0000 (UTC) X-FDA: 82814142432.27.D0AB6FB Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) by imf25.hostedemail.com (Postfix) with ESMTP id 52D3CA0008 for ; Fri, 22 Nov 2024 15:40:33 +0000 (UTC) Authentication-Results: imf25.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=Pz6KPYRa; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf25.hostedemail.com: domain of 3F6ZAZwkKCKYGROIKXeNRMUUMRK.IUSROTad-SSQbGIQ.UXM@flex--aliceryhl.bounces.google.com designates 209.85.219.202 as permitted sender) smtp.mailfrom=3F6ZAZwkKCKYGROIKXeNRMUUMRK.IUSROTad-SSQbGIQ.UXM@flex--aliceryhl.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1732289885; a=rsa-sha256; cv=none; b=IdUU2jSym/imepkUfB4q5ZjLMofsnrcHSyIsNKux67ctYny9LT8qoqpr3+BpNxS7saSm8z Us43GWPmlDBpgHK2OPE83AmFtBe//PdZm+3+Z0BVoT/RIUXLvdebj0gfIY9JmhOh1tMQRt jeT9xt8cimjp+2hjPOJ8wVf81MzDg4Y= ARC-Authentication-Results: i=1; imf25.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=Pz6KPYRa; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf25.hostedemail.com: domain of 3F6ZAZwkKCKYGROIKXeNRMUUMRK.IUSROTad-SSQbGIQ.UXM@flex--aliceryhl.bounces.google.com designates 209.85.219.202 as permitted sender) smtp.mailfrom=3F6ZAZwkKCKYGROIKXeNRMUUMRK.IUSROTad-SSQbGIQ.UXM@flex--aliceryhl.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1732289885; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=St2nivlEGlwAOUor5slXoMT0nSTJUF24z+m1sub+EPE=; b=crwpbokR97DxVnYFwTuSKLm1J+Pq9LQPctSeoGPwKXc159pIVAYtwATEUcCnRb+jTzhd0z O000ggP+fiyxf8le5GqgFmSyS0w8z5p7V7Su65xWygmrb4yhlGA8MOG7gcDpkEZxmXbgCQ jEQ9LRf4YWdj9UnOy7+grC+yFTi0f5Y= Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-e3859de1c11so3977211276.1 for ; Fri, 22 Nov 2024 07:41:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1732290071; x=1732894871; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=St2nivlEGlwAOUor5slXoMT0nSTJUF24z+m1sub+EPE=; b=Pz6KPYRa246zh5HSo9BOn7Q3sNFSE2Viz0rjqtwr5bHcNuV6s3DQZePye0c/QQSqBg JF/2E7hGU/IwJCIbU4BE4PZ/jcaK4RMsGCciSCrcgsUcTDMtqyBHwlF1l+f/I+5UXUBv QDi/usXUcv+X8vtUUHtRJorFiCi6C9LzT9ZBiAraGhmOakLX5sIqyEoILQNMI/xRAyQe 3TNBnqiBFH9WT47Dq3NrNLKX2jhqYVtXOiGhXr8jCKPh29x81qUnkHDcP37qviExwywa SFyM7Ln2yMTlvvlu5rinFL6YKrtBauxKLByEVVYuyB9xMOYRaGFq24CsSosIeYZn3y26 apeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732290071; x=1732894871; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=St2nivlEGlwAOUor5slXoMT0nSTJUF24z+m1sub+EPE=; b=j37wbhQ/1RKYuo+qHQf6eoUjllhxh5ZRt2wiJcjZNzXlUqhunOI2KgHtR/OsBq+MIo kPDzDzu66gcBoTw3yWNkwse/1i5xDqER8VGho/RmwbG+huMgqScFzMvcx/4LgmI42uNh 8MUeBOtb6xhDcjMITy2evPR3ytgllui/4J3+xsokIA9oSEL8G2z9s/30i+OSyZ1uQwiy jqEprumwYZZG+9x+W2g6UJaGyI4gZx+s7pel3f/j6AveT4nQZJ/FA32TGG9kUrg9wg3a wBkmGO7BhdJckhKYflH3eLoKxTRj9t2VnLIRPep5vXrw160SQjNlwsXokX+laxEk+K+M KCVA== X-Forwarded-Encrypted: i=1; AJvYcCXIW8BMOsE0mnAQ7QzVRMz+78kCR6LrPLl2igvKZsMWjOUa3/q3YD4xD5U3pqbLCZV0we3WHCZywA==@kvack.org X-Gm-Message-State: AOJu0YzZISpar1WVD53NfpQw3aWzJ6nt9SGWi9isKWHdATJqrpLkPOQU j5iXJQpWlHeAKcquC0eOR0n/bgijr32JecrcWHFVwBh96eMBsdumnpbyp2jQasVu5EOw6Dv91Ae RgXxrZZslki5Ehw== X-Google-Smtp-Source: AGHT+IGihGzFbF764Ujgj/U6cdWN/yYJN8fQNEHsMDvsZY7MAEQSnHOETorjJsB9VNEV6/q+QcUl9/lfdUnOIbU= X-Received: from aliceryhl.c.googlers.com ([fda3:e722:ac3:cc00:68:fe9:ac10:f29e]) (user=aliceryhl job=sendgmr) by 2002:a25:d80d:0:b0:e38:14f9:cd0f with SMTP id 3f1490d57ef6-e38f8bd8497mr2055276.6.1732290071512; Fri, 22 Nov 2024 07:41:11 -0800 (PST) Date: Fri, 22 Nov 2024 15:40:29 +0000 In-Reply-To: <20241122-vma-v9-0-7127bfcdd54e@google.com> Mime-Version: 1.0 References: <20241122-vma-v9-0-7127bfcdd54e@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=3903; i=aliceryhl@google.com; h=from:subject:message-id; bh=fkBx2F6iPu2x+Ij6OXEgUbDcOuLkhOhWgbDBfI9k5bI=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBnQKYIUymIZaDH58EKhKDYnMp2XcdauVFk9Sm61 K6mH7jVt0qJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ0CmCAAKCRAEWL7uWMY5 RgCfEACMPTyXW8HWQtwKk1nhcmhNoYFoxeHTiCbS+WoDdEOJSxJ3c+x20o6T0joQfWF8aB8rSS6 TASaxo1CMMJ3r+AoFuMY78oczohJuVeXyUhJYgUitIgivvPiZNixny1hlMWK0Xrj6gIkjjB8DTt jkShgEo5cB33v67l0sRgK4wmY1SauayQ1ntYHyWSybXHtGfF15xJ3/nhxtiJ6rZaW+//wB/mucA ufgaHuVbWelVOe8GUxHBfG+R7rvn1Gjt0BqCDOXbQttgKSLD5SyHoCyGDZq4UasnoQ5A/X4sk3v nS5AFaB7/Mg6hyyl4KYCIIKxl3EYd16h5ZFbo+I+ql56DHocbFh5CI7Ua008D79AQ7cM6njhjyX HZJNHusiqgZhJvlRJni+AS1QFL/iwVXkWRIXOx08LHJz2pTnYNIYsyEBlKI9TajaIn114X4JcFQ 9+tFvuikoWe3KltS+cRPIKw0yuhtnwOW8vrudu8qk8UDp+pqBa8KQUuUO/08gSQxQYsKSBjcT7+ Ek79cFhxL5FHrSgMjpezkk1oD6SyO4zAtCU10r04fonsgBprYzdRJO2mmucn3aUjaTxDCI/vbHs ZAh6Omw23AffKbI5tymnUbecXpHG+lxRMHay6RHD3Ue9KH3GvLvC5pyFaqY5NsXg3WVT95KLASX 5Qz6Pc2WbMCv8HQ== X-Mailer: b4 0.13.0 Message-ID: <20241122-vma-v9-4-7127bfcdd54e@google.com> Subject: [PATCH v9 4/8] mm: rust: add lock_vma_under_rcu From: Alice Ryhl To: Miguel Ojeda , Matthew Wilcox , Lorenzo Stoakes , Vlastimil Babka , John Hubbard , "Liam R. Howlett" , Andrew Morton , Greg Kroah-Hartman , Arnd Bergmann , Christian Brauner , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl , Andreas Hindborg X-Stat-Signature: hfxghia6e6byo44dykapfi7ojt6k1s5u X-Rspamd-Queue-Id: 52D3CA0008 X-Rspamd-Server: rspam08 X-Rspam-User: X-HE-Tag: 1732290033-391370 X-HE-Meta: U2FsdGVkX1/8gF4IO73splE/1jyQLlOuMb2L2sw/4HdEcZOjLQlCDAPz70nyTpJUkZVqgXDnBJ7zwkJQR+xKQO3TVN1VUVZTmOMd/bydmHhfl7ECT4bhm+EpQbFu541s28OogQnSE0HmFLbVZGmQKm9Lj+lAo1ySzp4RA9t0pcZTkLQoOPxF4BtdbX5cbW2LlKEOqRxQvGVHSybL03uH71yCTc/aJUndjVGMxbzSiXmK1//Ed1JJ5tMc/DTMXfy6D963UuyOJRRqPPGly0tEDbtKhO3ZA/3v6EkSfvhOGXOYMI3NFUiXi3UuL5Qa1Ju6CUApFcsOAUuZOulfEITHPC/oJ/yAEEMgCFJFS+l8dJbqoJMmgRrYng5hpoTvbpo4QvKVfqwOSDv/PNR1igT0J49zT3v3x1HxybBVUVggzCEVrbTlVT/M2vFR37WT8wlx7NiTg7BJhHgakts9x08CgAe4R6ztwypt2AQ8V+KdqdtHQczfuSfs1Fk6ZoA7HjHdIad2zJBH1I9YDSE5qUcGXxoiCW9v14ByHMhjS1EMqz0LnjoBGwBL55Ks1TrduTCXpV3xJPHqmNdGcPLb/0LXDgKVH8pnMIg1yYKB6fEMqS6y3jz8qxMNDjIN9uRf1CCBU8NFEZQX7yxYIg2OHI8w3JSxm75kkqfFkjYdxT4JZTDeOMp7AJyAHkCVEggfV8btg2ufd72RrOL16Oe9Pt51nezzDyoiAC4WQP2AvGOs4E+Mh3KiAnWxgO7Kmf+kqOXi05/yEZm19IZ+dnLxwv4MG1iWdzYhxGvtSAH/1SWxCAu2esYQE7po1Hc5Rz0t31p2JSKo1po5HR7++fRaudy9NV2l3I8wZ1zsf5E3YCNOOb8YtWr60AiEyt3xE2jZI0gQBuZi0mg4iafGSlayl/6V1Zu8lcwkwRbH3Pt3OohFj0NTdPqGDUhjLnldSLmT7QG6r65uWHvK8QB0YnVXrje Id3HOYRA RMxSsosM0BluMnhn1TfB70lPc/sULv1O/Wk6yZ9TIsfQYx6pwnc4jbQoVnCU5OOy1LWGAulTvsqRd5++WWfu/6aPltGj8W6+V165N2jv/QpG7PvOHE8rDAnq0f1H4+/4K/zRtVHM9suhZ4P5dudRFy/EVd1sSRiDBSGtDMrV2tzS5xAIJPbeGXRGUnNw8AinGccfsZvqcd4i7loB+tsx+aEbLrABtpAywEutP4F6rO5csKrXII6/5+RgqnvJw1Lur2C9vo/4PKtCNwK+YDNbyQrESitkA9xYBeWCZUi2zpC+zlhh4GbGQII9k4iKUvMsNbNVBv7oNZ6WwUboWywlXvBAT9XdVjIegBHmpiiKW3tjuOwCblZAVC3JDrg1YsXq3dhj3dWDVmPwdXVcM3k2xdWISqqs4ESwlS0Y2MmXVFqu1ozfPYwj35LCvBQTv7w3ExlkCHTUcV/wMtbfiXvFIeITQbWmrCPPBoIVdobve6+hU+UCo5MhQXAIrg25U8sL6rDaybA1ShUZgq5XnOkSUUCrohjxkw+mf/5ephTGnRn+cKP9aHzI0iPUGB8L9HS0rl9/r6SZ9o0BA6SbcOSDdEL+MJFXs2VoTKpt67MgLwckhaNrEPlX6GXaU8TspRoLHwmbGc6hJzkOd1fDRPcJyhfZSYYUha4CjfzNjYcs2nSJregk25r5PRrFWCywlMFtLzJ5ZZH1ffmX+pv8= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Currently, the binder driver always uses the mmap lock to make changes to its vma. Because the mmap lock is global to the process, this can involve significant contention. However, the kernel has a feature called per-vma locks, which can significantly reduce contention. For example, you can take a vma lock in parallel with an mmap write lock. This is important because contention on the mmap lock has been a long-term recurring challenge for the Binder driver. This patch introduces support for using `lock_vma_under_rcu` from Rust. The Rust Binder driver will be able to use this to reduce contention on the mmap lock. Acked-by: Lorenzo Stoakes (for mm bits) Signed-off-by: Alice Ryhl --- rust/helpers/mm.c | 5 +++++ rust/kernel/mm.rs | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/rust/helpers/mm.c b/rust/helpers/mm.c index 7b72eb065a3e..81b510c96fd2 100644 --- a/rust/helpers/mm.c +++ b/rust/helpers/mm.c @@ -43,3 +43,8 @@ struct vm_area_struct *rust_helper_vma_lookup(struct mm_struct *mm, { return vma_lookup(mm, addr); } + +void rust_helper_vma_end_read(struct vm_area_struct *vma) +{ + vma_end_read(vma); +} diff --git a/rust/kernel/mm.rs b/rust/kernel/mm.rs index ace8e7d57afe..425b73a9dfe6 100644 --- a/rust/kernel/mm.rs +++ b/rust/kernel/mm.rs @@ -13,6 +13,7 @@ use core::{ops::Deref, ptr::NonNull}; pub mod virt; +use virt::VmAreaRef; /// A wrapper for the kernel's `struct mm_struct`. /// @@ -170,6 +171,32 @@ pub unsafe fn from_raw<'a>(ptr: *const bindings::mm_struct) -> &'a MmWithUser { unsafe { &*ptr.cast() } } + /// Attempt to access a vma using the vma read lock. + /// + /// This is an optimistic trylock operation, so it may fail if there is contention. In that + /// case, you should fall back to taking the mmap read lock. + /// + /// When per-vma locks are disabled, this always returns `None`. + #[inline] + pub fn lock_vma_under_rcu(&self, vma_addr: usize) -> Option> { + #[cfg(CONFIG_PER_VMA_LOCK)] + { + // SAFETY: Calling `bindings::lock_vma_under_rcu` is always okay given an mm where + // `mm_users` is non-zero. + let vma = unsafe { bindings::lock_vma_under_rcu(self.as_raw(), vma_addr as _) }; + if !vma.is_null() { + return Some(VmaReadGuard { + // SAFETY: If `lock_vma_under_rcu` returns a non-null ptr, then it points at a + // valid vma. The vma is stable for as long as the vma read lock is held. + vma: unsafe { VmAreaRef::from_raw(vma) }, + _nts: NotThreadSafe, + }); + } + } + + None + } + /// Lock the mmap read lock. #[inline] pub fn mmap_read_lock(&self) -> MmapReadGuard<'_> { @@ -238,3 +265,32 @@ fn drop(&mut self) { unsafe { bindings::mmap_read_unlock(self.mm.as_raw()) }; } } + +/// A guard for the vma read lock. +/// +/// # Invariants +/// +/// This `VmaReadGuard` guard owns the vma read lock. +pub struct VmaReadGuard<'a> { + vma: &'a VmAreaRef, + // `vma_end_read` must be called on the same thread as where the lock was taken + _nts: NotThreadSafe, +} + +// Make all `VmAreaRef` methods available on `VmaReadGuard`. +impl Deref for VmaReadGuard<'_> { + type Target = VmAreaRef; + + #[inline] + fn deref(&self) -> &VmAreaRef { + self.vma + } +} + +impl Drop for VmaReadGuard<'_> { + #[inline] + fn drop(&mut self) { + // SAFETY: We hold the read lock by the type invariants. + unsafe { bindings::vma_end_read(self.vma.as_ptr()) }; + } +} From patchwork Fri Nov 22 15:40:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 13883306 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id D5852E6916F for ; Fri, 22 Nov 2024 15:41:19 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 1D62A6B00B8; Fri, 22 Nov 2024 10:41:18 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 1859A6B00BA; Fri, 22 Nov 2024 10:41:18 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id F1D7E6B00BB; Fri, 22 Nov 2024 10:41:17 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id CE44C6B00B8 for ; Fri, 22 Nov 2024 10:41:17 -0500 (EST) Received: from smtpin07.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 908F7121834 for ; Fri, 22 Nov 2024 15:41:17 +0000 (UTC) X-FDA: 82814142222.07.A6CC979 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) by imf05.hostedemail.com (Postfix) with ESMTP id D4E18100007 for ; Fri, 22 Nov 2024 15:39:32 +0000 (UTC) Authentication-Results: imf05.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=oTLgeNx6; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf05.hostedemail.com: domain of 3GaZAZwkKCKgITQKMZgPTOWWOTM.KWUTQVcf-UUSdIKS.WZO@flex--aliceryhl.bounces.google.com designates 209.85.221.73 as permitted sender) smtp.mailfrom=3GaZAZwkKCKgITQKMZgPTOWWOTM.KWUTQVcf-UUSdIKS.WZO@flex--aliceryhl.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1732289888; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=zQjQrA8l6WUO1Dv46YWyP2KzKGLvaWN5xjw1wa5cSc8=; b=e3zNxv5GDlslSnr/AOKEwdJgOYqCRi/oSefOyDGOonBK4cPrFotkYC5dM101Z3XSs9jNq7 +q/QfxYz5wlEGs/s6W2cqwi8RrOaviZhsuk/iGHQor8crSQEqJLstDHm5K+kDO9nKXsFSt wutvzxbQCrUdgUdPhmuHwVU6VorTmXQ= ARC-Authentication-Results: i=1; imf05.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=oTLgeNx6; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf05.hostedemail.com: domain of 3GaZAZwkKCKgITQKMZgPTOWWOTM.KWUTQVcf-UUSdIKS.WZO@flex--aliceryhl.bounces.google.com designates 209.85.221.73 as permitted sender) smtp.mailfrom=3GaZAZwkKCKgITQKMZgPTOWWOTM.KWUTQVcf-UUSdIKS.WZO@flex--aliceryhl.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1732289888; a=rsa-sha256; cv=none; b=X/DCHWf0mFltOsWH6DN/sXZWWR6UlpCSxR/JZrt2RxGJWUtTpiUSmkN8Tq00GnmNYwGqWN 0MTF1pWx061cWpxFqo35ZLSpJ68hiyOdbUxiCiAiAJrB3lw328W2NlxD2CRuhbIllGHcSJ Y7Kj7VTp4tM3lMupO+G8YxplAdTtVlU= Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-382480686f2so1261101f8f.1 for ; Fri, 22 Nov 2024 07:41:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1732290074; x=1732894874; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=zQjQrA8l6WUO1Dv46YWyP2KzKGLvaWN5xjw1wa5cSc8=; b=oTLgeNx6bxV7I9hXaHsHRHO1x0v+Qa9TArTHrVYNPoYIJsDZzw4E9VUeFUI8SNPge2 9IHOwMSa6JLPw41epEUjckMOZ7Pros+9p7cOkojVXLrqmHKKkB2emZ68HoLSuAG+qoFx KvIfANtjhrmZU82liVXUr2e18R0GKudvpOQhuAIDqyV2Jhxt/H99ofH+daROQHtNd0Yi qBNJK4k+Y6zdlpmrQTicxSigjlozm42LLyEh06hUzjhrDM8r/63Enqx8ut5nO52lS2au HbpyqZiVkcBVY9/ggEUHS8y9IXAoeNU7A1iszblOZAljB3HMAvk3cYGUAAJ1Nl3OTdsI a43Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732290074; x=1732894874; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=zQjQrA8l6WUO1Dv46YWyP2KzKGLvaWN5xjw1wa5cSc8=; b=oghae+76WkNLD5oYpdjqpHJAB0J4rET2BNuzUDCiSig3yz/5FPRL8qdZZmCVfROxks /u5YLuV9CLbU3JrgVDREH0HidD8O1KYkLVG3w+KxzS25KsWGmk51xVifkGBgqPt+sd5f TpLU02D6XdPHcG67Klyza0twFg9mzecWwmwmUEO6BN1d0mohNIWgPCfka4YQ4bKdZinb mCmIA2aGzGlLlPDgZB4F1KIn+eLeUuT8t+a9TrOa6f+uFCmpTR17NOy/G+SnrqMWNpSN eCbTZ88EMuLl0bGC1TmGv+rb+3CvQVs8KXVlI1EkgPjnwpmcNjuUOUMs1DgbPNddBFdv 52yQ== X-Forwarded-Encrypted: i=1; AJvYcCUeGZJkK0t7luWMdEmi8VTgL+rPjz4+iWqWXGQAR/yRxMSZFOuwkfuDHYMGZ6k9Wy9jTDM7ozRoIw==@kvack.org X-Gm-Message-State: AOJu0YzC/FWiFZLkHUiTGs6/4eSKnMGD5NGp/BcSqrMD1iCzryVEh6k+ etAfdeMmMhXhxaNFjmhIWmVnIAix5cVaxEnd1Y4wrutj6CxJKZU+t38RnMRbVJKc6sgCKWP/6Ot w72vqtr8TN+H6gQ== X-Google-Smtp-Source: AGHT+IH2pPS49cAT9mdCjiMFAVekUdtncedHBNDeVISatyX0fCCBayouO8NUq4KgmU1yCNwvAR5MiYLmHLx8PcE= X-Received: from aliceryhl.c.googlers.com ([fda3:e722:ac3:cc00:68:fe9:ac10:f29e]) (user=aliceryhl job=sendgmr) by 2002:a5d:5e0c:0:b0:382:449d:a6ab with SMTP id ffacd0b85a97d-38260b452d1mr878f8f.1.1732290073825; Fri, 22 Nov 2024 07:41:13 -0800 (PST) Date: Fri, 22 Nov 2024 15:40:30 +0000 In-Reply-To: <20241122-vma-v9-0-7127bfcdd54e@google.com> Mime-Version: 1.0 References: <20241122-vma-v9-0-7127bfcdd54e@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=3090; i=aliceryhl@google.com; h=from:subject:message-id; bh=e90cBT06DiQlSWUKjCW8KaJiJvXBHZuG2g717B8IAkc=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBnQKYJ73Kuhs7y8NsLUpQQMtbfBgw4kDNtzBVg2 tUbFMPyS9eJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ0CmCQAKCRAEWL7uWMY5 RkzaEACBEXTOYc+UZmggaAf5RKHc4bX3sRd3bEoHGg1TwzgV8P69eolFeBEDIMT4ozAtxjnoZMO 8H6ODCr80sTJ/14jsNEMfD8riO17u4t2Rct81AB6ASqN4eCABDEd93DFjjrtgNZxE5acubWPzlT rFWtgWhwIcyUvUkhX1ipVexr4/ZItTLyezntWLg4kBqVJ6uLepiaJctIk53F4rU8p9UZnAfC1P1 sPbE95Jb4S0oJhIGQoFaF6VtlUEV3joZaYJl1gGkuFnbWy6y1ije3pGCnWYv/099C2FtXKzKMEB e5mTT5LYuqJhZ3zf3gjfrNICehst0DXZPDIbpvzs199wF3CzRntxGAcRQkDApOhBkZj73Ntx6oj fO/MGb7TVIZgLhToYA91lnHYjCs18cIAwieUxn0k0tfq5NPUfYUYAad+koxMCGOauUvnCCB/DqC 2idZYlEiasHpiaOmj1judPSffxEnMkvDFLZtW2xroCdVECOMMYuFmW5fFv9hj5n2+yL3kmmcsoJ Sz/nfsJI5NF41/S/qA61Mo3l0d1XRZwMpxnEdzVm/KU47CaGRXonGb5rsfDf12bRSmzzvXthP/V vqtIKmQT4av/5On0EURF0tsQcFkV2DKivHNmMubOcOhsj3jFGHajd8ny39WSl7qKcFxdd3gePsV 7fPwbNtETlyL+wQ== X-Mailer: b4 0.13.0 Message-ID: <20241122-vma-v9-5-7127bfcdd54e@google.com> Subject: [PATCH v9 5/8] mm: rust: add mmput_async support From: Alice Ryhl To: Miguel Ojeda , Matthew Wilcox , Lorenzo Stoakes , Vlastimil Babka , John Hubbard , "Liam R. Howlett" , Andrew Morton , Greg Kroah-Hartman , Arnd Bergmann , Christian Brauner , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl , Andreas Hindborg X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: D4E18100007 X-Stat-Signature: c9kcn5xijp3aw94gd76r59zwr3xj9s7n X-Rspam-User: X-HE-Tag: 1732289972-555263 X-HE-Meta: U2FsdGVkX1+5UmwOu1mpwprw9T1xLBrI0e2yZWPARmyInD3tzGnYZjBgrig2HT5k2njo96Ssz1c3ZlMaAk8k6S0n/P1zWjlaw/iFmHtIyEO9v2AnbC3W7iHpG0xSuBR5PYAKHLEvpvLQtrn8SJogtKlgindJC0FbQwZ02s6p3RYsLgp1kLybcGYFq7YPfenuuyXSEECd9pG1V+b9bJ2stp7xZEtrBS92bvpG4Aa41x01ldcM3TkqlivvYqB0+MPSICU2rqjMOSo2O6C9w6ZReQJBSRQnAFBpCOntlwHbLWEv5Tus5qoJ4A5KpkUbF9aKUjwh00jysdJnzIhpXujmx7ciVROBCE9gZzgGow9UOnvZnbvEFqmHGweBUoLCnbthBq5H364J4kgpCjUiPRPvQg9DXyQydxA3UiH8O1ZuRmQbnAldc4zqlB+SbRu1fwoVwVfdn2U0I/zvK3JHQk9lnsJYmnKuXOezXMNWd6XyIWXGUClRS0hWvKrYKgMsKA7ko1OdLxiw+5WIj74csXCBT00YJ8HHoLnYcCSF46vajypQoTWfEXAdIkjMTIp6yUU14qRJDtZHOI10SQ7CWVsnWyUVKZ5CmMKZFDAvPukNcqgHRJp7UaZVZ80oOBQR9a99M1g+maqR6vbCTbvmCZ7ocVBAWI8rJ+z5qp0nW07M5XofTyPQ4LC4fdq7THStvVg9lPIhaXolhJGZPA9Mr5t2VMMciiAXPH3L8GI0n/e1FUYiHkWyEU/+rtMbg54IowzP2nWQb936doR+WD0GzGbZuxPz6m2LM0I/A7aQ3wEBxvpdKtdaReT1mmy1DyE+17P5mQ7hCXNunyvYgLiYpi6MnbcFVosOnN6npdMJalMoBhDtLgE1S0V3vYf0mdBq57k/S1pu7igFtJ3npJYhoXErhWauS6h9hlLYhhgvWXklxoQXZjbmsVLioQv9V15dibFTknmUPmR80Mi0E0BIXb2 sM80NAqb 7QqRkPeVqa6Lz4OApQesPhp3gJvfHvF5luRemnlilwJVle1xdY467bRkW+pS+/zpMJbstsOFx94MC6UB5cUsU/Jc8ubiPci4tZf436f6OKAHjmwXQqaSuExe8zh16iMyHuaGkPg5YQ1R5pCMWHnheApwluU5GsE/Wln0fSCC3gLTIXwJegoSk57Lhgp9o3Tc8ncsFY76RlbCYQNSAZcas861NBhb+QPJa25S+CFgznE2sOxumNdiP1VMVifpWH9bHMQE5CfdTAePvH5v5D+t0KMBBSyTzo1gR718DfXkxFoMrIB9wtAIjT3flbmIcCZrtqluMAwxeRRuObi2fa1lqAdgojKfOjCacbuSnmRv6xVftSwxcNOOzX9Tr3ADFeaDD2cLttoHP0EIPrc6MYunKnfC+pNDfFC5q6e1Qr6w1956DBrYFFSyIfT5x2PLgFM+tJQRLCpZQdAwsTo/kjTT+0p5GAWCtV52SJoiX5w7qjfM1XueOE0QOuRBCLz1f2fuuHL2fQm867jNqhimPIOkZn3q2f+qPsM+UxSxR5DQgQCK13/HTmu+9/EZsn1ic02maEVoYF8xy14XpiReV2nbr+Yz7I/HANSGT/FTBAg6lsIkiZGRglWClMhS2lL2+EbVYSoxOmpOX0q3hs+tTFiV0AOISLtYiLV7aIexZekLGWumvmyxPXLEOG3qQlt4fE1sH3ltaPubIMKh2zFI= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Adds an MmWithUserAsync type that uses mmput_async when dropped but is otherwise identical to MmWithUser. This has to be done using a separate type because the thing we are changing is the destructor. Rust Binder needs this to avoid a certain deadlock. See commit 9a9ab0d96362 ("binder: fix race between mmput() and do_exit()") for details. It's also needed in the shrinker to avoid cleaning up the mm in the shrinker's context. Acked-by: Lorenzo Stoakes (for mm bits) Signed-off-by: Alice Ryhl --- rust/kernel/mm.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/rust/kernel/mm.rs b/rust/kernel/mm.rs index 425b73a9dfe6..50f4861ae4b9 100644 --- a/rust/kernel/mm.rs +++ b/rust/kernel/mm.rs @@ -98,6 +98,48 @@ fn deref(&self) -> &Mm { } } +/// A wrapper for the kernel's `struct mm_struct`. +/// +/// This type is identical to `MmWithUser` except that it uses `mmput_async` when dropping a +/// refcount. This means that the destructor of `ARef` is safe to call in atomic +/// context. +/// +/// # Invariants +/// +/// Values of this type are always refcounted using `mmget`. The value of `mm_users` is non-zero. +#[repr(transparent)] +pub struct MmWithUserAsync { + mm: MmWithUser, +} + +// SAFETY: It is safe to call `mmput_async` on another thread than where `mmget` was called. +unsafe impl Send for MmWithUserAsync {} +// SAFETY: All methods on `MmWithUserAsync` can be called in parallel from several threads. +unsafe impl Sync for MmWithUserAsync {} + +// SAFETY: By the type invariants, this type is always refcounted. +unsafe impl AlwaysRefCounted for MmWithUserAsync { + fn inc_ref(&self) { + // SAFETY: The pointer is valid since self is a reference. + unsafe { bindings::mmget(self.as_raw()) }; + } + + unsafe fn dec_ref(obj: NonNull) { + // SAFETY: The caller is giving up their refcount. + unsafe { bindings::mmput_async(obj.cast().as_ptr()) }; + } +} + +// Make all `MmWithUser` methods available on `MmWithUserAsync`. +impl Deref for MmWithUserAsync { + type Target = MmWithUser; + + #[inline] + fn deref(&self) -> &MmWithUser { + &self.mm + } +} + // These methods are safe to call even if `mm_users` is zero. impl Mm { /// Call `mmgrab` on `current.mm`. @@ -171,6 +213,13 @@ pub unsafe fn from_raw<'a>(ptr: *const bindings::mm_struct) -> &'a MmWithUser { unsafe { &*ptr.cast() } } + /// Use `mmput_async` when dropping this refcount. + #[inline] + pub fn into_mmput_async(me: ARef) -> ARef { + // SAFETY: The layouts and invariants are compatible. + unsafe { ARef::from_raw(ARef::into_raw(me).cast()) } + } + /// Attempt to access a vma using the vma read lock. /// /// This is an optimistic trylock operation, so it may fail if there is contention. In that From patchwork Fri Nov 22 15:40:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 13883307 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id DB959E6916D for ; Fri, 22 Nov 2024 15:41:22 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 09D638D000C; Fri, 22 Nov 2024 10:41:22 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id ECE548D0007; Fri, 22 Nov 2024 10:41:21 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id D460C8D000C; Fri, 22 Nov 2024 10:41:21 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id AFF4E8D0007 for ; Fri, 22 Nov 2024 10:41:21 -0500 (EST) Received: from smtpin17.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 6B66B121929 for ; Fri, 22 Nov 2024 15:41:21 +0000 (UTC) X-FDA: 82814141340.17.DABF9F6 Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.201]) by imf14.hostedemail.com (Postfix) with ESMTP id 07463100004 for ; Fri, 22 Nov 2024 15:40:16 +0000 (UTC) Authentication-Results: imf14.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b="Qz/tDIxH"; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf14.hostedemail.com: domain of 3HKZAZwkKCKsLWTNPcjSWRZZRWP.NZXWTYfi-XXVgLNV.ZcR@flex--aliceryhl.bounces.google.com designates 209.85.128.201 as permitted sender) smtp.mailfrom=3HKZAZwkKCKsLWTNPcjSWRZZRWP.NZXWTYfi-XXVgLNV.ZcR@flex--aliceryhl.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1732289939; a=rsa-sha256; cv=none; b=Eo2ABd4dvsxzcBRd/NEwhZAHA27/vNdYuT21Q36z5xpm1vTRb9E3A0UEw+vm44Rq7gqjOo VZJ92meALJxtNU3SaWGDNSbJwmFTlhAfTk5lyClEbIzJ6A/rjMMFHFOSfkFbvmWwyOU+Pr asFxEIM1SnQ6icHjGsGRcnEb/9ggeRE= ARC-Authentication-Results: i=1; imf14.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b="Qz/tDIxH"; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf14.hostedemail.com: domain of 3HKZAZwkKCKsLWTNPcjSWRZZRWP.NZXWTYfi-XXVgLNV.ZcR@flex--aliceryhl.bounces.google.com designates 209.85.128.201 as permitted sender) smtp.mailfrom=3HKZAZwkKCKsLWTNPcjSWRZZRWP.NZXWTYfi-XXVgLNV.ZcR@flex--aliceryhl.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1732289939; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=L4qSVcgbBLdeeMk9S8eo1cKOTa/uPhWh7RI1+zhYfKE=; b=KewzLiGLwHBFCSZX26fxCAUVwuC4h4EtnsxFAfUvoNeLH+c3dHbuIiylB/wudyHu2aa96E fH1yfGn/q2y9tqleAsS5Sbt/l4z7SfYb1zGJKfRN7EzF+CNp5qwO4Q/CIMo5aCl4PAsF7v s1ekg/dl051ZdVDIJCH20+Hu8aDjiXg= Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-6eeb5ee73f0so35145487b3.3 for ; Fri, 22 Nov 2024 07:41:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1732290076; x=1732894876; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=L4qSVcgbBLdeeMk9S8eo1cKOTa/uPhWh7RI1+zhYfKE=; b=Qz/tDIxHF6gL0pzPVIBA2qbi42wyBN7Uw+fZzV8a70OZTxnd9LRl57CXxWWC5EZ7d9 r5pleRaKlfVb597y0e5n9l3OqKDnp/hCXBre1ZTmA+yT6WKzGH6Qi8da0TqXXeb71iDw g4P4jCjJuqfRU4zO6qpOzXVGcmGpRzeKlEfLdH3FouBBD/LxWlbhxLP8OqJof/AAiPWh RAeH7ym60u6/eOpwRPjUpOusJidTmsAxZKv4osFQFiMdQJ3ttN3y/sfBhxoE+cDh3akW SoxhXJQL/WfQwu+0qRcUo2ngz/oJ3I78PMhj0voTCek+CWzZ6IZOKBRbGTMJGt3KT/uV U3EQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732290076; x=1732894876; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=L4qSVcgbBLdeeMk9S8eo1cKOTa/uPhWh7RI1+zhYfKE=; b=ahcvZsO0tmUHX6uRzZHhzRfERPWzJFGVI/Eo5ultU6L48Wf73Y/vZKth9wlp7zbz0W IuRXZNDqm/40Krn3Qb4aUVXCTN4fncZ7ysl12Diva4RUgDzrQkFO7cE8MjzrwklpjDwW fthflorFAH7TjW0nmQfJysltBIPbFmPsLrnAX10Jsxx+1Iggen8mU8joGgcSZVeezRPP /W8Guqs6LGUF+O8iAupR94WajoMkbW7/pohdtI7DIfl79qqeDBUuEucUF+mkRx2qUvCb Ln3B5Idav3MLDrEen/Us80SVUDjYZGq0SiaiV61DhEXkHkKrDZ3rpe9w+eXJ2VLkzUh2 qm8g== X-Forwarded-Encrypted: i=1; AJvYcCXGuP6iaBgoaM3ZvR7gZPnXZLNCt6VRWIjB7wqSNm6eqwBNZUm3HlbLGlTBsznVsRnjdgPJziR1fA==@kvack.org X-Gm-Message-State: AOJu0YzmIT/Aiiu/1NRu7Pjd+2hsQtMuCsNyn/MVu+PPak3L93Xhne7F dOeZ/QiVHLfYcfe+d3snJ62FFkzW6MrmBRJ0Ge9Zp8RgmGoOIy9fhSP3B+2Q9HC9+Y269gbj7ay IQ0x6QxoYUdjPbw== X-Google-Smtp-Source: AGHT+IEzCJ8qWwWmshtRsITg+icfUQjN5P4TA8fmdquEW+McT4r0JS2lWAyQ7jrcDuQUs5kS2JoVK2CCYBJKDgo= X-Received: from aliceryhl.c.googlers.com ([fda3:e722:ac3:cc00:68:fe9:ac10:f29e]) (user=aliceryhl job=sendgmr) by 2002:a81:d809:0:b0:6e2:12e5:356f with SMTP id 00721157ae682-6eee0a3cd59mr78657b3.3.1732290076176; Fri, 22 Nov 2024 07:41:16 -0800 (PST) Date: Fri, 22 Nov 2024 15:40:31 +0000 In-Reply-To: <20241122-vma-v9-0-7127bfcdd54e@google.com> Mime-Version: 1.0 References: <20241122-vma-v9-0-7127bfcdd54e@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=7936; i=aliceryhl@google.com; h=from:subject:message-id; bh=8XMIdsAyhjsVKz2sE1Ods0Tz2Vq4I2NxznUSr3oMZoc=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBnQKYKwgMhFK1o/1aUXbls2k8sejghL5FzITqk6 S2R7cFzIkiJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ0CmCgAKCRAEWL7uWMY5 RgGdD/4iPoTTUbdLe33P5pBqMrDOdAKUntngkTdsYYX2OucalMMc62TwR9LizWRDXfNwM/sGDD/ 87pFB785Ie1GL1dBGmpBpL8gr8XP08IDdKU9PYdiWkrcl1M857BBrRZr5fvznourPha8Ge75nMF fUYwl16MYhoFseaPFlUXgdpty952Hj07bkZ3cbr/Dqaj+MHqd00kbuW3EhwLxiFieJRIA45bot+ ZUe+itpME+XKjA5eahHCbDq1h0yvWglatQsdgDi85VQesQtdZ0Awk9bWnS5n07udlTTvnqt2St0 HO74zVpaB/N+ERz3pBpj2ArIj5C8yo37m8gDSFiUsZ8cCkvBRYY8c9xia19JKX/pX4/kiSn74yu u5Wd9SN2cX/FGXGn1EXcbY8cmy242VYZ4LuF9ZKeUqA7YaKml4fBbSdYumBnHnsJhc1ZrBhPDpi rlqY2MgjKdUrO0KgIyDT0TdHU8Xcd4Q1cyRFQgg9AajEuLT9XLsKvhjNOqRnoKiVEO7xFvj19OP kQZOMqGPIuNlKhMPOGFMEVzwsGrJL3Qg2ViTs051E9a7EMgY/P0F+4ruzh3mNn1FTwrKAbYAKzo r0tx5ODyv4xYh6z0aAkpluZ/ILnd980jLVIk7IXf9lncUD+K9DFxBjBnN7MjDpOMjwaoYQwvsUE V+xrKnZ7t1hXKuQ== X-Mailer: b4 0.13.0 Message-ID: <20241122-vma-v9-6-7127bfcdd54e@google.com> Subject: [PATCH v9 6/8] mm: rust: add VmAreaNew for f_ops->mmap() From: Alice Ryhl To: Miguel Ojeda , Matthew Wilcox , Lorenzo Stoakes , Vlastimil Babka , John Hubbard , "Liam R. Howlett" , Andrew Morton , Greg Kroah-Hartman , Arnd Bergmann , Christian Brauner , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl , Andreas Hindborg X-Rspamd-Queue-Id: 07463100004 X-Stat-Signature: pmy5xfxunoiaf79u8tt3nyo6xzbpbbzg X-Rspam-User: X-Rspamd-Server: rspam05 X-HE-Tag: 1732290016-90178 X-HE-Meta: U2FsdGVkX1/UehagwQw7Si9CO631X3cR3XO/hEptkO3tdyARhV7vUk42kaQlg8osulz0H0hWeDykVtXEasYn0Z2RUUikN+Y8MIhvRTZU5oCsGsGaKr8I0TO3X+r+tPZ6pZIM5p6hrDN7Re5SmR7Wyn1S2sLEFf+nNMGfUFZHw/jEuUO8/1aH+Lx2YLq3SEmNKUzbjX/j8klwnwWsTSq+R0djVpluo85Vhw2+tWoj8y8Ek8+vUBMu94iYW0aQYD56nrTupoZw66NU95fi2Gqv5ct17cPfD37zdAgC+lA2COO6vMZLm1EKZ6euzEM8kp6Bb3Ps3dzSvLDg51eGY0cte5tXVcQIYsZPOj2swRvknN4kr+0NXoL1EL8OnnKWbAy271pMfPW/vEqw70YvSZ8lBCxkEgCWwqSecHnNV1zGNL7dlQow33BWKSNqGuOGOBHLKSsviPhzhx4cz9lqVSd6u8Ls5YN294BrBK2d9IAXM7nCMWks+smPB/2lmkNfec9TNeui8g6yIONxWm13FwMtvkLhGDdZYsFowtl1PM6BRk1VTrMbzewetrp9lAx28rtixqqkXhyyzFn+F7LPJohyhCnMtQUhT0PEDpioAPsJc5gBxfkOL1StQrKx+c3q6MXccfeXPY0FRvZpuq8ug4rX6emNGUBCswlaDfBPi8ULpcITIXGTIe7LKzKjEAkLOfjR7NaE8ok5CG9X6t+XzMKeUwv5BkDrNP75Pp+DGWshzJi+J8KqNPLYpkGqKLB68GEYKCtJpVcgfl0C6g9OKtQoUqkiHXtb9UwGV/cOtFCGjb1Zzo4RVtBnEYMwH8OO9eJ5Uk6aZ91OsvRFVSp9C9d3zA9Y0snnzeUBW8b03w96MqVTJDOCh8ge1BUc5EJW4opHbJkF/YR5ItCCtNGiwxsCUjq8QcQQ8YitWIumhxNuNqGsSC7SPTGym7EupquAkvEntVKfnrNzARClyt8mo5E wJFNu2Sa LyqCpMYJG30AW2h5wu/dcny/MIlTGk5JvnqsqWNFkLbtukA352DnJMavGzyZCdl9LXqqE2LwfQIh13ahYS9sDz18kXJ7V9ZE7dPmmn93I+Q1tvvi11PKt0zLANdbDaqCgnySgr1iBIsl5D9JHzc8kR7n8I9UiAmSubMZmZiJpbj6Y7llP+kixVhc16mChW41VIFMwPhXp3oisXebuTrk4Sw7eNQ7G++e3S0F7cjTZSGEKrm0Oz4HZZJ0B09wp8heeVJwyqwadj8VgEn00vMzOZ6u+sJ1bmzENGi8rWxTE6V+xl2IsjrPXahzWtdei7Zel0rv37Ds3cpOBNlgqv4tY/87IGaz0F98qbCw0DV8WeVak6QrH+LUJI0uJEEecMpWQSg5fJ0dWdjqYs5J5x/y1DT0tLbqa3cUAxANBZ/SdlZocTmKhOOU2z6tu5F+l3VixJ3TsLIEUzMmaetkpBxIrw3HX526mLUMfR3jEdoSayfnGx3olD3WH0AsLwhwrd/0Tbc4YcLIC322snAJWP/KaTEmqhCci0ePLmjL0OIKXViPBAt2mpb/bsuoPWjSbMDfAL573KYyU0tu3Wd0mZU1zcRkBqOCz4MKnM49zfLRe91tDwOaZtuySVV/Wmq0CuJDaM3H3ItUWAz6gzdKEN9p+9QCYMf8tkmpLWdEIJo3SXfGr2fWycWf1B8wxng== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: This type will be used when setting up a new vma in an f_ops->mmap() hook. Using a separate type from VmAreaRef allows us to have a separate set of operations that you are only able to use during the mmap() hook. For example, the VM_MIXEDMAP flag must not be changed after the initial setup that happens during the f_ops->mmap() hook. To avoid setting invalid flag values, the methods for clearing VM_MAYWRITE and similar involve a check of VM_WRITE, and return an error if VM_WRITE is set. Trying to use `try_clear_maywrite` without checking the return value results in a compilation error because the `Result` type is marked #[must_use]. For now, there's only a method for VM_MIXEDMAP and not VM_PFNMAP. When we add a VM_PFNMAP method, we will need some way to prevent you from setting both VM_MIXEDMAP and VM_PFNMAP on the same vma. Signed-off-by: Alice Ryhl Acked-by: Lorenzo Stoakes (for mm bits) --- rust/kernel/mm/virt.rs | 179 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 178 insertions(+), 1 deletion(-) diff --git a/rust/kernel/mm/virt.rs b/rust/kernel/mm/virt.rs index 3e494e40b530..2a49c29a49c7 100644 --- a/rust/kernel/mm/virt.rs +++ b/rust/kernel/mm/virt.rs @@ -6,7 +6,7 @@ use crate::{ bindings, - error::{to_result, Result}, + error::{code::EINVAL, to_result, Result}, page::Page, types::Opaque, }; @@ -155,6 +155,183 @@ pub fn vm_insert_page(&self, address: usize, page: &Page) -> Result { } } +/// A builder for setting up a vma in an `f_ops->mmap()` hook. +/// +/// # Invariants +/// +/// For the duration of 'a, the referenced vma must be undergoing initialization in an +/// `f_ops->mmap()` hook. +pub struct VmAreaNew { + vma: VmAreaRef, +} + +// Make all `VmAreaRef` methods available on `VmAreaNew`. +impl Deref for VmAreaNew { + type Target = VmAreaRef; + + #[inline] + fn deref(&self) -> &VmAreaRef { + &self.vma + } +} + +impl VmAreaNew { + /// Access a virtual memory area given a raw pointer. + /// + /// # Safety + /// + /// Callers must ensure that `vma` is undergoing initial vma setup for the duration of 'a. + #[inline] + pub unsafe fn from_raw<'a>(vma: *const bindings::vm_area_struct) -> &'a Self { + // SAFETY: The caller ensures that the invariants are satisfied for the duration of 'a. + unsafe { &*vma.cast() } + } + + /// Internal method for updating the vma flags. + /// + /// # Safety + /// + /// This must not be used to set the flags to an invalid value. + #[inline] + unsafe fn update_flags(&self, set: vm_flags_t, unset: vm_flags_t) { + let mut flags = self.flags(); + flags |= set; + flags &= !unset; + + // SAFETY: This is not a data race: the vma is undergoing initial setup, so it's not yet + // shared. Additionally, `VmAreaNew` is `!Sync`, so it cannot be used to write in parallel. + // The caller promises that this does not set the flags to an invalid value. + unsafe { (*self.as_ptr()).__bindgen_anon_2.__vm_flags = flags }; + } + + /// Set the `VM_MIXEDMAP` flag on this vma. + /// + /// This enables the vma to contain both `struct page` and pure PFN pages. Returns a reference + /// that can be used to call `vm_insert_page` on the vma. + #[inline] + pub fn set_mixedmap(&self) -> &VmAreaMixedMap { + // SAFETY: We don't yet provide a way to set VM_PFNMAP, so this cannot put the flags in an + // invalid state. + unsafe { self.update_flags(flags::MIXEDMAP, 0) }; + + // SAFETY: We just set `VM_MIXEDMAP` on the vma. + unsafe { VmAreaMixedMap::from_raw(self.vma.as_ptr()) } + } + + /// Set the `VM_IO` flag on this vma. + /// + /// This marks the vma as being a memory-mapped I/O region. + #[inline] + pub fn set_io(&self) { + // SAFETY: Setting the VM_IO flag is always okay. + unsafe { self.update_flags(flags::IO, 0) }; + } + + /// Set the `VM_DONTEXPAND` flag on this vma. + /// + /// This prevents the vma from being expanded with `mremap()`. + #[inline] + pub fn set_dontexpand(&self) { + // SAFETY: Setting the VM_DONTEXPAND flag is always okay. + unsafe { self.update_flags(flags::DONTEXPAND, 0) }; + } + + /// Set the `VM_DONTCOPY` flag on this vma. + /// + /// This prevents the vma from being copied on fork. This option is only permanent if `VM_IO` + /// is set. + #[inline] + pub fn set_dontcopy(&self) { + // SAFETY: Setting the VM_DONTCOPY flag is always okay. + unsafe { self.update_flags(flags::DONTCOPY, 0) }; + } + + /// Set the `VM_DONTDUMP` flag on this vma. + /// + /// This prevents the vma from being included in core dumps. This option is only permanent if + /// `VM_IO` is set. + #[inline] + pub fn set_dontdump(&self) { + // SAFETY: Setting the VM_DONTDUMP flag is always okay. + unsafe { self.update_flags(flags::DONTDUMP, 0) }; + } + + /// Returns whether `VM_READ` is set. + /// + /// This flag indicates whether userspace is mapping this vma as readable. + #[inline] + pub fn get_read(&self) -> bool { + (self.flags() & flags::READ) != 0 + } + + /// Try to clear the `VM_MAYREAD` flag, failing if `VM_READ` is set. + /// + /// This flag indicates whether userspace is allowed to make this vma readable with + /// `mprotect()`. + /// + /// Note that this operation is irreversible. Once `VM_MAYREAD` has been cleared, it can never + /// be set again. + #[inline] + pub fn try_clear_mayread(&self) -> Result { + if self.get_read() { + return Err(EINVAL); + } + // SAFETY: Clearing `VM_MAYREAD` is okay when `VM_READ` is not set. + unsafe { self.update_flags(0, flags::MAYREAD) }; + Ok(()) + } + + /// Returns whether `VM_WRITE` is set. + /// + /// This flag indicates whether userspace is mapping this vma as writable. + #[inline] + pub fn get_write(&self) -> bool { + (self.flags() & flags::WRITE) != 0 + } + + /// Try to clear the `VM_MAYWRITE` flag, failing if `VM_WRITE` is set. + /// + /// This flag indicates whether userspace is allowed to make this vma writable with + /// `mprotect()`. + /// + /// Note that this operation is irreversible. Once `VM_MAYWRITE` has been cleared, it can never + /// be set again. + #[inline] + pub fn try_clear_maywrite(&self) -> Result { + if self.get_write() { + return Err(EINVAL); + } + // SAFETY: Clearing `VM_MAYWRITE` is okay when `VM_WRITE` is not set. + unsafe { self.update_flags(0, flags::MAYWRITE) }; + Ok(()) + } + + /// Returns whether `VM_EXEC` is set. + /// + /// This flag indicates whether userspace is mapping this vma as executable. + #[inline] + pub fn get_exec(&self) -> bool { + (self.flags() & flags::EXEC) != 0 + } + + /// Try to clear the `VM_MAYEXEC` flag, failing if `VM_EXEC` is set. + /// + /// This flag indicates whether userspace is allowed to make this vma executable with + /// `mprotect()`. + /// + /// Note that this operation is irreversible. Once `VM_MAYEXEC` has been cleared, it can never + /// be set again. + #[inline] + pub fn try_clear_mayexec(&self) -> Result { + if self.get_exec() { + return Err(EINVAL); + } + // SAFETY: Clearing `VM_MAYEXEC` is okay when `VM_EXEC` is not set. + unsafe { self.update_flags(0, flags::MAYEXEC) }; + Ok(()) + } +} + /// The integer type used for vma flags. #[doc(inline)] pub use bindings::vm_flags_t; From patchwork Fri Nov 22 15:40:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 13883308 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id DA7E8E6916D for ; Fri, 22 Nov 2024 15:41:25 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 61BB88D000D; Fri, 22 Nov 2024 10:41:23 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 5CA6E8D0007; Fri, 22 Nov 2024 10:41:23 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 41D888D000D; Fri, 22 Nov 2024 10:41:23 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 1D0878D0007 for ; Fri, 22 Nov 2024 10:41:23 -0500 (EST) Received: from smtpin15.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay09.hostedemail.com (Postfix) with ESMTP id D93C58181E for ; Fri, 22 Nov 2024 15:41:22 +0000 (UTC) X-FDA: 82814143902.15.3DF68A3 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) by imf12.hostedemail.com (Postfix) with ESMTP id B7EDA4001E for ; Fri, 22 Nov 2024 15:40:55 +0000 (UTC) Authentication-Results: imf12.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b="mMMJp3i/"; spf=pass (imf12.hostedemail.com: domain of 3HqZAZwkKCK0NYVPRelUYTbbTYR.PbZYVahk-ZZXiNPX.beT@flex--aliceryhl.bounces.google.com designates 209.85.221.74 as permitted sender) smtp.mailfrom=3HqZAZwkKCK0NYVPRelUYTbbTYR.PbZYVahk-ZZXiNPX.beT@flex--aliceryhl.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1732290017; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=Jn+jmdJoGY3YsjVzLAxhBr/vpe9LejwdH758cgsIixQ=; b=PECZot7ZGqKKkz3mIpviZ+pAODBszaZLAuyAmPpnklAgyK3KxWcQD7OdoUxOgKtE48f3xP XuXRhT4Q5NELMnYdfumK97StrQELr8GWCfvTGF0yJjg/px/aHfnFDwaJGVyle9C2a0pV1P /diLaYtqrDDziQ1xq4MY6XAgPA8d3oc= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1732290017; a=rsa-sha256; cv=none; b=iuE+1MVZb+tYOof0FIDKqmy+sfHSW1KltXgSFazQFyvp6oi/0e7WFEC+b9wCAlY9c9kQ7l 7DhFZVRPWvF7Kp4Bo7D3FbU8R5Bc90666fvQOaKxsxJqbXQFtFJ6U+KJukexxKvtCJ3CIb As4LCUublx8kUnPJ5iPikzun9JDyxtM= ARC-Authentication-Results: i=1; imf12.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b="mMMJp3i/"; spf=pass (imf12.hostedemail.com: domain of 3HqZAZwkKCK0NYVPRelUYTbbTYR.PbZYVahk-ZZXiNPX.beT@flex--aliceryhl.bounces.google.com designates 209.85.221.74 as permitted sender) smtp.mailfrom=3HqZAZwkKCK0NYVPRelUYTbbTYR.PbZYVahk-ZZXiNPX.beT@flex--aliceryhl.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-382357b294aso1110076f8f.3 for ; Fri, 22 Nov 2024 07:41:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1732290078; x=1732894878; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Jn+jmdJoGY3YsjVzLAxhBr/vpe9LejwdH758cgsIixQ=; b=mMMJp3i/f2JX8NLT6Vc8MOHXtqE/9J5MZ1DUH+C264BQ1XWa9UnDqfx5Dj53xrKueo 4xVnTW2IPfsXelQbK95zTEFTWfvxjLz/xk6tjbVRBcKk9QR0NeyqGrCzD3Y/Xmuhppzo 9wzk7ogr5tk6QS/RazNIE9ojyLDzp0CyHzDGTmZLkjG0JYw4t4wt0dWoVjKXJgGjssLK rbz7CfPNrNN9UBpLlSGo/F44VSIHocVEy8I4MQ+GhnnH8FTP6iAEvjORXPBX55xwSAXN PTInVPgXC88ibcTqgbPu3Yqpsh+l6UnzfLhZD1CdH55GhSEKHHef2n95ZX0aIhffUtzw JpZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732290078; x=1732894878; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Jn+jmdJoGY3YsjVzLAxhBr/vpe9LejwdH758cgsIixQ=; b=crTYFviPXlb7bVQkbfKk3Hi4772yfCx5CeDDyOZiNYeShP4KQ/b1GalL95USi5QmCN Le6enSrDGbhpdcXznDfX2W3ITkZ1GlCJ5NbWoXISOOABG64gmCsnFcnE/xd0kw7rmRUZ gtSjp7ILj1mrOLzlHsPNSRZejpndTClhIwdBQUcNk4k5FvhTPeC02eGvmbJ5tHG3kHfV KcRzlO+zLmumOK78dOQUYGOp3zhNQt6gry+o5P0M0yPlJGGYyCSDh4qOE8XxzMCWaeIh Ci2fopBbr5VSAWgc/AM1T8zrKRCuyUw0aO988aUFGRmzCaCrtlhpwe2yjwRw/PQR25Dl tQ9A== X-Forwarded-Encrypted: i=1; AJvYcCUcAetIiaQxJFK0uhPpKZrrfbEOGqlQZzEoKDBR1AnSe0c8Ez1Z9b/dQB1m91NeSGKohvaCJrBUmQ==@kvack.org X-Gm-Message-State: AOJu0YydBvHzR7iYNPZYCV6RAMBlagX/BpFHMugOYoTdmP9MICHefZfG zXcD7u1QXLkjnUXVj7LUJZxM0NYYDKP6puTn+HmhKlg8QskYkBnKpcIxescIStALABaWSI/g6iN OtiSTsFoKIPMZsw== X-Google-Smtp-Source: AGHT+IEDL6wyaXq4KVeCa+5cSaT1eT6HwgjeW/qH+ytywyB3jjXDr+R/rDF3sLSLr/FXsbnoKOvq0/msM05k6g4= X-Received: from aliceryhl.c.googlers.com ([fda3:e722:ac3:cc00:68:fe9:ac10:f29e]) (user=aliceryhl job=sendgmr) by 2002:a5d:468d:0:b0:374:c0b5:565 with SMTP id ffacd0b85a97d-38260bdfb03mr927f8f.9.1732290078524; Fri, 22 Nov 2024 07:41:18 -0800 (PST) Date: Fri, 22 Nov 2024 15:40:32 +0000 In-Reply-To: <20241122-vma-v9-0-7127bfcdd54e@google.com> Mime-Version: 1.0 References: <20241122-vma-v9-0-7127bfcdd54e@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=2821; i=aliceryhl@google.com; h=from:subject:message-id; bh=CackrY4N4HrwWKJd4mh44KeNaf6Y+uJ77q1hA2gtWCE=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBnQKYKX/KFzHUB/ScZLT3bwuduBq3gubqN9dGbb zhWJO4uzlqJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ0CmCgAKCRAEWL7uWMY5 RmMND/9qq+Sg908pb5iHFBsP7RY9cC5qNfZFzfWuBMKlhj48SWuaTddtGzGW+uv7CCplsCcgeHt HAc286bLeHj6SasQPWO5wZ1yfZ9lc/TEdx2iQTqII9TNxR36DXtL5SZprMoBXYVjQ2Tywws7lHY xlQMpm1oy10QRFyuA3mbbrIGpz9LxAx+SNJ3AXDcKnehoHsIxXQiGSTN2db7DA+AuFl2jYjV5lB VIMg44+BKCwfbBhCZtkpUj0U/EHsDy7A5LhsBKv1rFUGccDleWk7uPBbj/LXktuYJ6nYsCBxS9s h5j4yvM/qN4whXwUmWP0Go6PcPTEATyx+1v5ekMf+mhLwWf3qCcpStayFbm0BNFi07zT+4nsZvM E228lqBxIZHtoO2z91VI8fJpZPMSi41fki2pzwndXccNGEL+EyHY7OyKAhtunktx6JOtW+TYRCP mWZ7+rFxasmzyRndH3DcUNWreRDBKAAr2m0cX5l/2Mx2kQRt+ZbWLBDlSp1fcGwHy9p15TDDLPD SEPyL8FilnUErOT3rB+EoH3cywn1kC5I4rTeacyutzbqiCk6fcOTZ0bA8ZjX1uo5vgrXQrfcHqt BBIvXbcN36yINaxKYxh30yS6jPryfIoudkn5gxuUKV7Oo3BewdDxanK/Wgrg2EZeqqo5PeQTEMl mqmg/Y0+Mk6IEMA== X-Mailer: b4 0.13.0 Message-ID: <20241122-vma-v9-7-7127bfcdd54e@google.com> Subject: [PATCH v9 7/8] rust: miscdevice: add mmap support From: Alice Ryhl To: Miguel Ojeda , Matthew Wilcox , Lorenzo Stoakes , Vlastimil Babka , John Hubbard , "Liam R. Howlett" , Andrew Morton , Greg Kroah-Hartman , Arnd Bergmann , Christian Brauner , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl , Andreas Hindborg X-Stat-Signature: iwsfiwm83wrn6qfax699mgchnbs198ge X-Rspam-User: X-Rspamd-Queue-Id: B7EDA4001E X-Rspamd-Server: rspam02 X-HE-Tag: 1732290055-659232 X-HE-Meta: U2FsdGVkX18d/sJCgTfKZeGJMUMF0gFQFa2A4aQ+ZTBO1egaQxPyux8m9bjnzojeulUaR4Lj0TLeUjr7NzR7DPAtol6fWTylIMSvWD5Gn8otMgkc/Pc8nD7bY62uhIzKYrrrXlNkuzv84b+5EcucJG8GIx2eW+sGi7Wwzimn23XLqaroC54VKltzEQay3zEPmZo+XuUvgTjUb5Q9DLn64GPUi5wRA2pkgLHXp14PC8f/Se15ql2ZBbKi/RcUJ0dBycyX6Aw8twTnkC1EqoGSZe9jxA83TaKGqTtMOjTk/2jHpSsSD87EDWrObZx06BaOkbCODPX1QDreXgWsvhAFXY4t8GbO9EUjF1pbTrmXSba3ihwRIZYa9KARZKKDwlPmAmUy5UEZ7VhvWpMIV0Gmal2xNBNWPd2PPUkMduh0TQKazZCS0M3o0txIkAooTvfkGm3m9+/L5JxXfRAZUL+SOvvFpj/xZtY6uIt9AhA5HoY+szP/7e3bqSfnl1RbZlF032j8rnDquiwSjFf6rr1UJtY8cE4M8/d8B3P5GJTC2s8GwhDUjvBpraHZQN7Kkhki8fp/Qk01JcjM2utG/xGRHlCRd40Z3DjaXxez4tYWX5DOjDusxdlPvjVH1d7pqsnSncXN2mI1sH+ZxvXonR9bC4uTtxG+mXBqTHOER5TheBdPg6UkHWIClZG0+P0jEPE3CdCzMnQjVF2s2I8Y8EYwqhweT3VUkuPHkLGQoqarDCDsZnBk5MFOmDUG1FPSyxu5x1k88VJcivVnngLr3selQPXdpa2YFRFbK0YghhD1OjZF6FbemKD0MtjpeJPY9IqlOcK+Ul6uZnOTkjFQPkJRjctwogebPjClXkBcVlOFNs39d4fCUJgRFX1UE1WsbxsSnW2XY1oGeD+63kjlBQdlPs7WiHTW4f34fRsqqJRB0Slrso6NgOlOuB9lOeEfzl03uGmNSLgvmATm9SLGJ9c SBn34zNX oPyH6PVqlw0jWk+8js91CZB9eVm/FuuuegY7nOIqMCGCCNCCpKBKiXad8mLJOZcRMPAfMC8cUyqen5N82yKMgjVzWoKprdTdjfbxXcdk5DqBvb1rIWrC8SFVFHDrB/+QV6U16stc5PCxgYns7coexdwngc0r2Z0hO/TE59m4IM5cHUuPCtaWrbcbXJSrrbaxVKz77WgtgEHRJ9XWW7AtQFUiuDR4t8splEynbZibBISzXW8qzqdrqqfA5TcKvkjal7MzDywWldVn4xEm/Wzn1WngChkOb+WHef0SsRFxDlOkHAVRxJBaFlUBrOc7VnI3Il8q1lmCEkHkfh4/dKCTRaI8Z8Ibu1QUQxOHf+91NJqz7eVdxihYqrDaqltUaj6oGNWo4pCXTZMZ3ryF20rLNzjgH61n3KA2QyRitm8b5d107r3YG+FMni/DI/LLFDRvVBNJH2D2wclgk4zAbuCPmoyJX//o0f6bYDqfA7FC76HjwsI5kqR+ybYK42ZyAbsFwYfT7gpT+NG2zUHPRzgHXKrrcUp4mhAbR66T6Z7AGpJjLFkxvkkcOx9KoUUgFxlt+GBCWeR+fBpFeZzY63kdMoTWT648RgLy2BvqZ+3M8yu9a5zhq73zjQqD3GdfmbelCtW8/mDnVEsFZT4KUXSiG0UfhEQuiyhV/0USV X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Add the ability to write a file_operations->mmap hook in Rust when using the miscdevice abstraction. The `vma` argument to the `mmap` hook uses the `VmAreaNew` type from the previous commit; this type provides the correct set of operations for a file_operations->mmap hook. Acked-by: Lorenzo Stoakes (for mm bits) Signed-off-by: Alice Ryhl --- rust/kernel/miscdevice.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs index 7e2a79b3ae26..4e4b9476e092 100644 --- a/rust/kernel/miscdevice.rs +++ b/rust/kernel/miscdevice.rs @@ -11,6 +11,7 @@ use crate::{ bindings, error::{to_result, Error, Result, VTABLE_DEFAULT_ERROR}, + mm::virt::VmAreaNew, prelude::*, str::CStr, types::{ForeignOwnable, Opaque}, @@ -110,6 +111,11 @@ fn release(device: Self::Ptr) { drop(device); } + /// Handle for mmap. + fn mmap(_device: ::Borrowed<'_>, _vma: &VmAreaNew) -> Result { + kernel::build_error(VTABLE_DEFAULT_ERROR) + } + /// Handler for ioctls. /// /// The `cmd` argument is usually manipulated using the utilties in [`kernel::ioctl`]. @@ -156,6 +162,7 @@ impl VtableHelper { const VTABLE: bindings::file_operations = bindings::file_operations { open: Some(fops_open::), release: Some(fops_release::), + mmap: maybe_fn(T::HAS_MMAP, fops_mmap::), unlocked_ioctl: maybe_fn(T::HAS_IOCTL, fops_ioctl::), #[cfg(CONFIG_COMPAT)] compat_ioctl: if T::HAS_COMPAT_IOCTL { @@ -216,6 +223,27 @@ impl VtableHelper { 0 } +/// # Safety +/// +/// `file` must be a valid file that is associated with a `MiscDeviceRegistration`. +/// `vma` must be a vma that is currently being mmap'ed with this file. +unsafe extern "C" fn fops_mmap( + file: *mut bindings::file, + vma: *mut bindings::vm_area_struct, +) -> c_int { + // SAFETY: The mmap call of a file can access the private data. + let private = unsafe { (*file).private_data }; + // SAFETY: Mmap calls can borrow the private data of the file. + let device = unsafe { ::borrow(private) }; + // SAFETY: The caller provides a vma that is undergoing initial VMA setup. + let area = unsafe { VmAreaNew::from_raw(vma) }; + + match T::mmap(device, area) { + Ok(()) => 0, + Err(err) => err.to_errno() as c_int, + } +} + /// # Safety /// /// `file` must be a valid file that is associated with a `MiscDeviceRegistration`. From patchwork Fri Nov 22 15:40:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 13883309 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1453AE6916D for ; Fri, 22 Nov 2024 15:41:29 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 29C608D000E; Fri, 22 Nov 2024 10:41:25 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 249578D0007; Fri, 22 Nov 2024 10:41:25 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 0C36E8D000E; Fri, 22 Nov 2024 10:41:25 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id E0B3B8D0007 for ; Fri, 22 Nov 2024 10:41:24 -0500 (EST) Received: from smtpin06.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 95487C1817 for ; Fri, 22 Nov 2024 15:41:24 +0000 (UTC) X-FDA: 82814143188.06.FA7BAAE Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) by imf26.hostedemail.com (Postfix) with ESMTP id 6B6B314000F for ; Fri, 22 Nov 2024 15:40:41 +0000 (UTC) Authentication-Results: imf26.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=yg7pYCUd; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf26.hostedemail.com: domain of 3IKZAZwkKCK8PaXRTgnWaVddVaT.RdbaXcjm-bbZkPRZ.dgV@flex--aliceryhl.bounces.google.com designates 209.85.221.74 as permitted sender) smtp.mailfrom=3IKZAZwkKCK8PaXRTgnWaVddVaT.RdbaXcjm-bbZkPRZ.dgV@flex--aliceryhl.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1732290014; a=rsa-sha256; cv=none; b=8lblgJwOHct9MoME9TrSTX2U58M3qd/CiU5R8FRcZ74r0jlZyd/3dWQELMN0QZSeciaTx+ Cbif1ygc4l9N0aiWLhQzKC3PuGxzTJe6OxuZOneYEoryc+K9jJ0+SCDaiRBf5lysgOkgmW WN3oEf3vtcJDazdUT+6jqfTHzYPmJPA= ARC-Authentication-Results: i=1; imf26.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=yg7pYCUd; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf26.hostedemail.com: domain of 3IKZAZwkKCK8PaXRTgnWaVddVaT.RdbaXcjm-bbZkPRZ.dgV@flex--aliceryhl.bounces.google.com designates 209.85.221.74 as permitted sender) smtp.mailfrom=3IKZAZwkKCK8PaXRTgnWaVddVaT.RdbaXcjm-bbZkPRZ.dgV@flex--aliceryhl.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1732290014; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=roehYhV9fbym2F/vf27bAbe0CuzVSCLFEeCVaGrDIRQ=; b=z+Y9PiOTBJ8qSfs81DDnIColSex3s45SLcFcWWWAmhLCeP4P0GD4kdBNfEGaP2uImR8LkN 19kak3z0Z1FFrSqbk1D5ku0rDY9p6W/s/nLfcDtWA0Ms9f5EpVd4Nhhxm4/7i8kvNt6EXz P0L4GTUkZseHff8hzuS8cwjld1kSY18= Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-38236ca50d5so1086696f8f.0 for ; Fri, 22 Nov 2024 07:41:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1732290081; x=1732894881; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=roehYhV9fbym2F/vf27bAbe0CuzVSCLFEeCVaGrDIRQ=; b=yg7pYCUdO3kHMCUUCJG3/gMPwyHixrv+cb/0SxbFyYwWsZfDfwo/c7N2bz1OdXDM52 HSthU3fyr4UcEP6qS568vJJLJ8bhnHr6lYhh+tCBnk8KwAeWD4InbYeSaUCZqD6eSpk4 PbUUq0ezRZgR1wu1asSsr1T35HRhxoBVmGe20FKEdxoErmqYj6UzCd3d4r/6dKnWoY8/ N9LpRCOYi+OAG66YqCKFgVHZwAgwlEPQoNl5I8NBQIaW7QGbGGnEv6Y6sYuygVRytrNk TT9KEGPGpF/+99hSXeTxFDW1jG/YB2yyLfeMdBB6x0iGCiNzW9RzY+pH5uLIvliRqOfy ABsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732290081; x=1732894881; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=roehYhV9fbym2F/vf27bAbe0CuzVSCLFEeCVaGrDIRQ=; b=YGTWkAbJXpX2+pxHXC2dMINm3mKOctfIkoaHsMZc6Tl1jdb/NZbAIyO19WaGo575CN IHKQntbJF6fpBQ7ifN5P1cMJIT0yHuufKMXSEolaQu692q/r41s91RIUFJWZbPdUlScL QY8MmzVX21BBe84BvmPtr01HRfBUkBxuPhYNn3AuMD3QMx9wHJ9Wf+LCoThI/c1DMGTW OOZUGbd2kREzIFYWTBGR0EDVBq08fv8A+Np/xHnvCCaVN9EYBczTQJJDcf6BBm+0qosj mbrfFrLsgasSX/1OgSe24FulqVQfZYajgJi9gOyFhUP98ffhT2HiJmc/QBQ0ePBPRWD5 mr1w== X-Forwarded-Encrypted: i=1; AJvYcCXi+DvvH+8JbMq6vdVDTY5OPYriUDbWVl/a2cEKRWgmxueCr8WnsmxNS94Jpr0OLu6PWpx1FG6Hjg==@kvack.org X-Gm-Message-State: AOJu0YwZoYuTH73vuameyu8IAQN6cA3zWNhdHLtNgpx/E/i3EJSVJarz 1myZ30X60toM4Za3uQlMnnzgKJziRd+r2Pjd+1Yktc5ECv8HxV+i1JRXgdDZ7Edjm/bRxR2izTj /q50RPgcfeqAR/g== X-Google-Smtp-Source: AGHT+IF6HBbIQggNCbWVHzfdpf5qfU2oWZDDUICEvmMpzMP0kJSXWVx7hqPiHvLxeddSVZjHgvUjH2UBZr7vJN0= X-Received: from aliceryhl.c.googlers.com ([fda3:e722:ac3:cc00:68:fe9:ac10:f29e]) (user=aliceryhl job=sendgmr) by 2002:adf:fd05:0:b0:382:49ff:ef75 with SMTP id ffacd0b85a97d-38260bc27dcmr780f8f.7.1732290080932; Fri, 22 Nov 2024 07:41:20 -0800 (PST) Date: Fri, 22 Nov 2024 15:40:33 +0000 In-Reply-To: <20241122-vma-v9-0-7127bfcdd54e@google.com> Mime-Version: 1.0 References: <20241122-vma-v9-0-7127bfcdd54e@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=5755; i=aliceryhl@google.com; h=from:subject:message-id; bh=ELmBMFzYYsNvMdFa8fNaCj9uRohYnanctvoUqVOPrOk=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBnQKYLQtIIMMayOTF0V1fptgYQ4tpbvUzXCBxvI JXOixUouJmJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ0CmCwAKCRAEWL7uWMY5 Rk7MEAC8HmptGWWIAH1NODYFTSG83oi5q2l+ljeKmvdiUHP1c39MD8JUUr8ZQY56Km1mjeH+R45 Bb+bq62Q5v4yR0Bmrf1RlL2cPshEqIV3SaIF1AMB972ROETbmB/IEny0owtXKbAJE8nuaGxBiW9 +Ni0SAFbcP30X2a80Cb2WQGk3ItYkrP3LfPzt43YJ52Y/9anw8UIoT3Q2tLGXMEaFRJ1qOqlsOh 2FxJkSANzWvBix5B/6xqMTf7BrLH60791UzrqLbz0FwyO2GFLZptvL45fwTdb8VCQAONjeNC6Px Q1YQnxM1+zc2qDrMjuFIaJ32y7wOsJNtrLDek249qEOCPFs4y7HYAUbOSy3fNlNcw8TLo7k48Sd 4+RbUJdtj/5k/Vw22wFASM8UZVyfIkvGegvIh2ETxFgNYbg6kFuOAVrxZJBBLN/TdeUgoZDOwpJ sACEu6DJGOnIWvhCKW0OVnw8hrEitbQC5tQz9YVTx2ejH9bDVn96NOSyhlvdNefp6z17zABlNUF 4qyGR6ezIJwaFa/6wtS0DYVYNM8+gGHWc2VjK7VLBH4KUkkAsFmk9F0xl0I87cgYZgWdh44pyge jLxj5Oa4qTkuqPfIZGEV8t+xZFHHKjHnp4P7oWDrnqJgAG26hj0Nv+fEuSr0tclsMTN/ap3OBJC wNxW0WcRdIeDHWQ== X-Mailer: b4 0.13.0 Message-ID: <20241122-vma-v9-8-7127bfcdd54e@google.com> Subject: [PATCH v9 8/8] task: rust: rework how current is accessed From: Alice Ryhl To: Miguel Ojeda , Matthew Wilcox , Lorenzo Stoakes , Vlastimil Babka , John Hubbard , "Liam R. Howlett" , Andrew Morton , Greg Kroah-Hartman , Arnd Bergmann , Christian Brauner , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl , Andreas Hindborg X-Rspam-User: X-Rspamd-Queue-Id: 6B6B314000F X-Rspamd-Server: rspam01 X-Stat-Signature: kht59tiizsfiah68mnuiqsahdumsfqdk X-HE-Tag: 1732290041-614904 X-HE-Meta: U2FsdGVkX1+XbjPe9v/Et3gNkqJaSvCEMsCWAgrGmygof9PIKHxvAUdQyCV1SFemcoCW/82GfJiC94jlWUenRC/B7jBydr9VYSfkqqvm05kAt1TQ6ILwRVnKvhUqcIwsiVM0hEbm0ssb8gj5kNySvFeE/pxk7uqQcdFfu5tA58gyNdOT+R6+Y7GxLEsQAxyejnxrE+yy8k/Lx3sXhO/bQ79Asm2WcEdBUOvmA0/VQLaNMf53i+sxOgwJT4pUQu6y2D1mGOZlWy7XeJ+0bqlLIGo099s4t3G6+948uwCN2NDuKM6kGQEdeI8tiVQ0RvBoqadffpr9BO5fcOEZBo0MvF2ZWBFM+kaxj5d3YFnzoTlpZZV8Ir34O0m6JmSvarBBKTGsqMiqQXtYuTKVf2S35uLg9tlQnyLWNhOXrxhCq1NEMXYggxWAerumT9eAVURn84QyAw4WhXlK60Dy9RLeBxW7Hn5z7h9t7ibnc5Xmz3is7oTKHY9ePR+VsQseb5mHQ6KM8F9sal0+LiDnKBSLPstyD/gY4TAEwATe3TPtPsh2ujtZV2tlUQATQGit4AWSM+qCtBB4Vs0mwxIWSfTthaJkReJotSQHX0eO/nbn65I6D56TBQiflrWr45+9eoIOz2kBxeIeLcjaemkBPxdmzuf6sbIX8fHH7w25QYsXLlYLumem2DZgy6v2kjH9LNSL02sNgpDUSLrmccCV7BAiwPt12rDnRFxjLonLEC7Jm+HNeIazLho9n/mgvq+gTxxO4M7R6KPIFNO6HvQgYDnxMJvRisMeNR1bZ7XYd8BMz2cAz6BLQUQDiBjyA8gsE7xVLdI1UTNiuxYQJrED6DsERGjPHcQ5Y0Jlh9ztR5jGLnrTwAXKfcb20dkB2srD8ETT/tC3NEDK4LzNO8pmXz11l/frvbgKv6zPEemaZFLLKGMvRifEevltOtMMgFBlvyxrKRBuPHVIaN8xvqyoMR8 WxniwDE9 nWConpVT3i1qcXLM6li7gLjmDOIvFl6qJjQT4MoZ0tIqj6z5uXS4/8BBbbPugPrUPY7VCpC+yr2pL0bT630qmRKu+6iueP+XArGvtueadyD84VIFrqJiM/mBYMwBJU2HCuDlQQ1AvGJVUVOu3GG4Xp5K6c1nwi6Y8ywMZwucEi3tpdZfyBoMOUmBlyVbWYAEeiNiG3jrwtnsxi9N7xs7wZsv4lDVuI8fdWuc9FOPGm1uwfrXVejOOi+6bfok/3nGKY7yXztxY+K92pwfyXlG7BUwalGULF5iIorC6SBLb16S31eMVfe/miBpMEcFzavKB4hywtfTUPozfNBQ//1qoQnMoyx0lNVY7Od9SqyuQJ6mLxH+/S7EZVOW1GXRc1sBlh5j/NjWwckeqF5txGdSceYi26el1hRXxMzEhyM1OC+1wm5U6EmPF2zY537DfdtMx0l+70ukt19mRlPwemCAHMZvJG/JwqQU1sFQ2/94RZpICMzCNw6U35LHaqTnrQCoK7FBKcASf6bVKtQCi7VH+tGY9HV/ruAJQyGmRtaP2gF8/0/67lf+y4FyP+HLunoj0/eM1DGe2C0zvBzpQXo5LkqqnbtCcJWa6arBEhm7qFyQiu2H1ZP/vS9GHf7JYfIllUBzrPxgqWw0lor0= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000002, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Introduce a new type called `CurrentTask` that lets you perform various operations that are only safe on the `current` task. Use the new type to provide a way to access the current mm without incrementing its refcount. With this change, you can write stuff such as let vma = current!().mm().lock_vma_under_rcu(addr); without incrementing any refcounts. Signed-off-by: Alice Ryhl Acked-by: Lorenzo Stoakes --- Reviewers: Does accessing task->mm on a non-current task require rcu protection? Christian: If you submit the PidNamespace abstractions this cycle, I'll update this to also apply to PidNamespace. --- rust/kernel/mm.rs | 22 ------------------ rust/kernel/task.rs | 64 ++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/rust/kernel/mm.rs b/rust/kernel/mm.rs index 50f4861ae4b9..f7d1079391ef 100644 --- a/rust/kernel/mm.rs +++ b/rust/kernel/mm.rs @@ -142,28 +142,6 @@ fn deref(&self) -> &MmWithUser { // These methods are safe to call even if `mm_users` is zero. impl Mm { - /// Call `mmgrab` on `current.mm`. - #[inline] - pub fn mmgrab_current() -> Option> { - // SAFETY: It's safe to get the `mm` field from current. - let mm = unsafe { - let current = bindings::get_current(); - (*current).mm - }; - - if mm.is_null() { - return None; - } - - // SAFETY: The value of `current->mm` is guaranteed to be null or a valid `mm_struct`. We - // just checked that it's not null. Furthermore, the returned `&Mm` is valid only for the - // duration of this function, and `current->mm` will stay valid for that long. - let mm = unsafe { Mm::from_raw(mm) }; - - // This increments the refcount using `mmgrab`. - Some(ARef::from(mm)) - } - /// Returns a raw pointer to the inner `mm_struct`. #[inline] pub fn as_raw(&self) -> *mut bindings::mm_struct { diff --git a/rust/kernel/task.rs b/rust/kernel/task.rs index 9e59d86da42d..103d235eb844 100644 --- a/rust/kernel/task.rs +++ b/rust/kernel/task.rs @@ -94,6 +94,26 @@ unsafe impl Send for Task {} // synchronised by C code (e.g., `signal_pending`). unsafe impl Sync for Task {} +/// Represents a [`Task`] obtained from the `current` global. +/// +/// This type exists to provide more efficient operations that are only valid on the current task. +/// For example, to retrieve the pid-namespace of a task, you must use rcu protection unless it is +/// the current task. +/// +/// # Invariants +/// +/// Must be equal to `current` of some thread that is currently running somewhere. +pub struct CurrentTask(Task); + +// Make all `Task` methods available on `CurrentTask`. +impl Deref for CurrentTask { + type Target = Task; + #[inline] + fn deref(&self) -> &Task { + &self.0 + } +} + /// The type of process identifiers (PIDs). type Pid = bindings::pid_t; @@ -121,27 +141,25 @@ pub fn current_raw() -> *mut bindings::task_struct { /// # Safety /// /// Callers must ensure that the returned object doesn't outlive the current task/thread. - pub unsafe fn current() -> impl Deref { - struct TaskRef<'a> { - task: &'a Task, - _not_send: NotThreadSafe, + pub unsafe fn current() -> impl Deref { + struct TaskRef { + task: *const CurrentTask, } - impl Deref for TaskRef<'_> { - type Target = Task; + impl Deref for TaskRef { + type Target = CurrentTask; fn deref(&self) -> &Self::Target { - self.task + // SAFETY: The returned reference borrows from this `TaskRef`, so it cannot outlive + // the `TaskRef`, which the caller of `Task::current()` has promised will not + // outlive the task/thread for which `self.task` is the `current` pointer. Thus, it + // is okay to return a `CurrentTask` reference here. + unsafe { &*self.task } } } - let current = Task::current_raw(); TaskRef { - // SAFETY: If the current thread is still running, the current task is valid. Given - // that `TaskRef` is not `Send`, we know it cannot be transferred to another thread - // (where it could potentially outlive the caller). - task: unsafe { &*current.cast() }, - _not_send: NotThreadSafe, + task: Task::current_raw().cast(), } } @@ -203,6 +221,26 @@ pub fn wake_up(&self) { } } +impl CurrentTask { + /// Access the address space of this task. + /// + /// To increment the refcount of the referenced `mm`, you can use `ARef::from`. + #[inline] + pub fn mm(&self) -> Option<&MmWithUser> { + let mm = unsafe { (*self.as_ptr()).mm }; + + if mm.is_null() { + None + } else { + // SAFETY: If `current->mm` is non-null, then it references a valid mm with a non-zero + // value of `mm_users`. The returned `&MmWithUser` borrows from `CurrentTask`, so the + // `&MmWithUser` cannot escape the current task, meaning `mm_users` can't reach zero + // while the reference is still live. + Some(unsafe { MmWithUser::from_raw(mm) }) + } + } +} + // SAFETY: The type invariants guarantee that `Task` is always refcounted. unsafe impl crate::types::AlwaysRefCounted for Task { fn inc_ref(&self) {