From nobody Mon Dec 15 21:47:19 2025 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 054472475DE for ; Wed, 15 Jan 2025 13:36:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736948176; cv=none; b=hgkv+14Pk05e7Q6hlOLS6ToS5KI2wwzwvBIkDwGEIszO8iCKcocvF4fC6C5WAtZeiD9BS9kA3nl4QE0Dd/o7zORDagcDFv9zM084Tau7nVqVqoAfyLnz2X52X/s04Abm+AUGyRyfm6MtSAjYLxrLDXwlvkAgUxO8hT7MBl0E5Qs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736948176; c=relaxed/simple; bh=fLfkFNdLYfHgKfZa0dsXjtc9votv5zCA9qLsVLeeLkE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=mlpZvFqshAsInWokxe2TGfIlsTclEuFVAKIlbCg7xI5mf2slxxwpxwzeORrR3JSIdLnm4/qQR79DbUlGqFdEGU769Rw+PNtPR9mgEvS5NAzPF1Ko35Lb8w4ue5D2P3FNi6pJsV2iAK6ohFS+WcmBNVk+dVNbkG50Py5lTwuR6Gs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=UbID/AhC; arc=none smtp.client-ip=209.85.221.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="UbID/AhC" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-385e1339790so4317247f8f.2 for ; Wed, 15 Jan 2025 05:36:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1736948173; x=1737552973; darn=vger.kernel.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=WyGEiOkhmdNY/fU37LXSLgzBjmVwObw0G8SyyivcNjI=; b=UbID/AhCU5wGAdmP8a9yEH+ARVYetQUbaV316StcVGsm48Zj9nACuFSB6YMpxQsjIP 7put3y7fPNJ61fsM1Inm/MiB+KFmYV8XH2FshVKDbv2fxAa9qE0nLbsDTbGvz5JpI4zY 2NCM2Pb5ZFPnE1YcLvqc2HeyDPjYwNP38LQ9EPb2xKo7gRA3Vn+e7P4L7wxkymkDUvw/ 91Pqd2micGLS9WCmnhfLoKoIOTFCWP8TUE7Mu7D6Gjx0eQa2pjNZBP3kICoS2AFBDpbP mF8qFUJ9CetmQbXDq8W2aOuvLdcdpsdDXBBRyptR3epB0CA6umMMUEiHa0u2/rmr8XT0 SaIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1736948173; x=1737552973; 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=WyGEiOkhmdNY/fU37LXSLgzBjmVwObw0G8SyyivcNjI=; b=ItStWhw9ubA1Iy1eeGQzA8c91DYSqyCJ+5i5FFF9BWVV3/oCq9pIy4IAKkuO7DCeW4 fugTxsTPQhD7oGZCkqW4PsqoZM5dbYHZBw6L4cpTClbcOvGrZIsAA4OifC/lQreX8an6 TSYjUlzl8eYuiH3S8acFR8DDXRgu2HGgZoLb6NtrU1mHCB9WPKRNU8hto7UechdbYRJy QCo2aEExboPkrquhOR48Mwgi5rEI/3Jttr2wBv9kwWUqoI4HeBAnUCNkNB++JCcOyKLp tWWu9+OW9MRaUIT+zsgFBGlIZTmBzaEZwEBZ66jtDT5ycnuFQGbubwhtCcuHMncfDijM Arxw== X-Forwarded-Encrypted: i=1; AJvYcCWDmNw50iCs/hLh/zRsG0so8L0X5EEUNEyAPJ72HMmT2Uc/fgpZr9hS0VWSlGM+dojD/lPxoJEpT2MGrtI=@vger.kernel.org X-Gm-Message-State: AOJu0YyR9WMhZMUaFbTJlBMysnTccjzJWtMIKFKOyY04rc6LaA2FYJ2H bkHhkZRR9Z9ewlFZ91h8rr9m39KpojMPT91uPc1Hh8xMPz1s6EmZqpO/EDn5mp0IjyvA6Shp934 VlxiEs1Kv5dTYMg== X-Google-Smtp-Source: AGHT+IH6kBJKdmdDV5w19iOE843iDVldxJ9in2s0SPbV23iN1Txz+OJHqSf7ZYmSD6HRC4mZ8sg2KRgO82avk5s= X-Received: from wmbfl11.prod.google.com ([2002:a05:600c:b8b:b0:436:e755:a053]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:184e:b0:382:46ea:113f with SMTP id ffacd0b85a97d-38a872fc1b3mr27766198f8f.10.1736948173574; Wed, 15 Jan 2025 05:36:13 -0800 (PST) Date: Wed, 15 Jan 2025 13:35:07 +0000 In-Reply-To: <20250115-vma-v12-0-375099ae017a@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250115-vma-v12-0-375099ae017a@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=4078; i=aliceryhl@google.com; h=from:subject:message-id; bh=fLfkFNdLYfHgKfZa0dsXjtc9votv5zCA9qLsVLeeLkE=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBnh7m/l8GboGpN/qusvnLxbok1uTnWuhzUiY+SS PCNfbEvgfSJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZ4e5vwAKCRAEWL7uWMY5 Rg80D/9JzLVe2s09/Ey8IChe2f9AxrZWGc5rUDwgfHi/y8u+2zvnVesQGWFxUhTaCR435B8OVxl Ytf7xmAkpx69EK9ykOXhedM7v8VjGiD4aQDdY6PVvJPSn2MqV1yR+vLN6qIFWT6yBAVpVIkP1td +w5eKL6SIUPPOy8Soh/Dc4TAsEXq+JL9JEW80gfxcGXh3wsQzWc13ckoRPk5LdcT5GCVnLiaKYN wfkm3PWmgvVayaKk2PLF1RmN3hzwu9K2dn8BVptE+M6Fr0SafY6i8Oi0VE1ofzMxxUX29xyFkhZ uQWnNU/gdc93rgpgmNxxmRznFlMnBmEtNTH4kmI6YlrR8xXpdMPx2VIXTpg9vFHzrrcRI4c9dLD TiqK5aexQj6lRpVzWPdj7Sv6HE0sfCR+Orv7MPYgn8EGY+X69KmsutvARRFIvuCesfCmmBwHwfV Gfk2+CiL4ynj6qx9lZDg5DmW+68O3r/5DMyFtqB7uevUcSZ/HPmC9i5KcWTAtvVS3uL0EmKPePb fd8Gi72oo1oQ3OjvzaS0SBeHHlVE0FWz1n+TAOa+uPSShuMSx+4ki2JShfkmUWc2kfYxZYPNTpq lsHyUCXtL46uBkw221SbwO0R/tyz+0ABzNVR7dKEpjkbktYrrQ0dYY4V32dS0IsS1gpv0UJnqli M1k0GU7PNicgsmg== X-Mailer: b4 0.13.0 Message-ID: <20250115-vma-v12-4-375099ae017a@google.com> Subject: [PATCH v12 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 , Jann Horn , Suren Baghdasaryan Cc: Alex Gaynor , Boqun Feng , Gary Guo , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Benno Lossin , Andreas Hindborg , Trevor Gross , linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Alice Ryhl Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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) Reviewed-by: Jann Horn Signed-off-by: Alice Ryhl Reviewed-by: Andreas Hindborg --- rust/helpers/mm.c | 5 +++++ rust/kernel/mm.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 65 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_s= truct *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 ee1a062ec7d7..60dc66972576 100644 --- a/rust/kernel/mm.rs +++ b/rust/kernel/mm.rs @@ -18,6 +18,7 @@ use core::{ops::Deref, ptr::NonNull}; =20 pub mod virt; +use virt::VmAreaRef; =20 /// A wrapper for the kernel's `struct mm_struct`. /// @@ -160,6 +161,36 @@ pub unsafe fn from_raw<'a>(ptr: *const bindings::mm_st= ruct) -> &'a MmWithUser { unsafe { &*ptr.cast() } } =20 + /// Attempt to access a vma using the vma read lock. + /// + /// This is an optimistic trylock operation, so it may fail if there i= s 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 ok= ay given an mm where + // `mm_users` is non-zero. + let vma =3D 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, + }); + } + } + + // Silence warnings about unused variables. + #[cfg(not(CONFIG_PER_VMA_LOCK))] + let _ =3D vma_addr; + + None + } + /// Lock the mmap read lock. #[inline] pub fn mmap_read_lock(&self) -> MmapReadGuard<'_> { @@ -228,3 +259,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 =3D 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()) }; + } +} --=20 2.48.0.rc2.279.g1de40edade-goog