From nobody Mon Feb 9 11:26:47 2026 Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) (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 0C3AB1D7996; Thu, 19 Dec 2024 21:08:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734642529; cv=none; b=PPZDFQp7mb1n3t2EBDhUD4aUkVJ/zjoLMnKjV0CPzi99nS0H6KR1W7v+jvJFEVsis6/QFjRc7rLRYBP+3OfFwBAxf7zGxYIylfW2JZlJBW4COjP3VjnNxz0eOjRoYfIBn6rPjmJv49UTW9rR9S+svrznSmq2i98wbbCQbD5+l8I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734642529; c=relaxed/simple; bh=/ikI70Vx9VTFvUYOPIJla9o/5OEbZwWpK+cUvQgY7gU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PkiZnSE7SLNMrARpBxhpk0xRBbcP289k/ThhdhiesrIgWJ7PMtpceFPHFJZnZmEO9BVTNDBDK2WdyX5JxzDy6wtn5PwiaFw0kSHqxeCH47gdz7suHqZRlVShXGzDP7CNR00yk/P/+FK8n2B3fUML4q5O7TWKH7NzTF77bUGFqMk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jej0g/nl; arc=none smtp.client-ip=209.85.214.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jej0g/nl" Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-216426b0865so11705105ad.0; Thu, 19 Dec 2024 13:08:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1734642527; x=1735247327; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=x9QXxVgtSe8H/UdvxZZA8sF6VvONdQXEw9VUMmlZNJA=; b=jej0g/nlx/WfXOxl70GbhSNx7SMkpRb0gLLtlvFo7ZTYjIoIkpsKGREbVW/+ibktj9 jNsQyYReJXKUfoGeacAXBkW2Kp9eFRGPn2b90lGVqiVrdfm5VCd/nRhcq2sMXQTPqB/D pEmLp/D3jrb8F8kd0QEwwy0S+m3egfChubsZiCdhBW6myXbus+LiPdDUh/pJQRZdvuQ8 wcVmvfpSJbn2P8LDVMahMR3LtxUFZFr8JYB/q+WEHRpwfPj1kYbGyyX/UexEpMCm1WQh T4LlzmPDxNOOq4kaewU8HW8AqDiEdo0gF+cwsLGU7x4GbPBT0ztOBlMe7konx5W5gVqU 4HNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1734642527; x=1735247327; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=x9QXxVgtSe8H/UdvxZZA8sF6VvONdQXEw9VUMmlZNJA=; b=J1SOucft28O01RSV7KvjkZnYFM70RyWVnJeV/Q6FuwAmoD/JZAuhl7/bx/j3njE1FB vhm3JHlPtyfjqjxpAiSP1EuzH2/rfLEZQoV4GWFihcnH9SBoeKfOkPeUO5k3WePlZ/Cs 9L26xfj/vGBIujO6HIf2D03SmKsca8epvUn52ociX1muhKFapUInhG1h7ewUCrcBXdHn CZMAQz3FfDhVuYY6MlVKo3YLbA/kcfBCJ6JBpzHgD7pXOI+5UikU7rUEvQn0Ne81bo4r 8h+ZWh2rzH/wI3rcixb4qYb4Mu4CjB7M3aQeC190mwLbfv5CRxtQNfHRPICTjnoqoB4E Y6WQ== X-Forwarded-Encrypted: i=1; AJvYcCVwy8JI/teGj8165gf2xy9UdeGwE5K81oy3Qvqf5K05BoVUhfCegNtT9sKCDyawQ6u5XDq7lNa+46GHY68SyA==@vger.kernel.org X-Gm-Message-State: AOJu0Yz6EYQcGSzjVNZgUBSLVXopneZQX2O6MZNi+/Jp2P0FP57BfvGg d7QdBd7LVTWcwhjO8b8hGm7hQL203XxIsw1UQBL8Aqa0W1UjhPOB X-Gm-Gg: ASbGnctLc/CPEVnQxoB+dtIfAzKQx9Nmk1i5wwiK19jOPR0+F00yY6Y+b38ynNeI407 2xdvFbnG6nQevUR7UMmXxnzRN77SS1IgZqVKMZfOUVSJseXYop5wq1uDOeEGkhYB59qjh/VnqWX 2Zb9dn+G/xBvU0BHEH8YrHzWt6GiUdAFWkqBGP3D7lbQJ6o00W2kdNXbtdcNlLMZUlyhmXfBJv5 sp6LNYdaD01BqdH0o4pwJ/fXMYcZLzooXVVffo0oV4IzzdGNkOiHv+Qj6bhQ7ZdLQ== X-Google-Smtp-Source: AGHT+IGz0Q+3DpfXii21esDiAC06Fva51alHJG6cESFMtMV5fGT0zFttkPVJt7mH0xNMF9ojhQsEbA== X-Received: by 2002:a17:902:f607:b0:212:5786:7bbe with SMTP id d9443c01a7336-219e6ea1baamr2967705ad.24.1734642527196; Thu, 19 Dec 2024 13:08:47 -0800 (PST) Received: from mitchelllevy. ([174.127.224.194]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-219dc962cc3sm16831755ad.28.2024.12.19.13.08.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Dec 2024 13:08:46 -0800 (PST) From: Mitchell Levy Date: Thu, 19 Dec 2024 13:08:26 -0800 Subject: [PATCH RFC 1/3] rust: percpu: introduce a rust API for per-CPU variables Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241219-rust-percpu-v1-1-209117e822b1@gmail.com> References: <20241219-rust-percpu-v1-0-209117e822b1@gmail.com> In-Reply-To: <20241219-rust-percpu-v1-0-209117e822b1@gmail.com> To: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Andrew Morton , Dennis Zhou , Tejun Heo , Christoph Lameter Cc: linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-mm@kvack.org, Mitchell Levy X-Mailer: b4 0.14.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1734642524; l=9725; i=levymitchell0@gmail.com; s=20240719; h=from:subject:message-id; bh=/ikI70Vx9VTFvUYOPIJla9o/5OEbZwWpK+cUvQgY7gU=; b=xAlZKloO7jsOKjUts/I2F2rmsZdyqA6z5zN+M95gp6DPAS4r3zekMmTKtwUJ4JUDfydbIxXyf 1eSJ1IX89SzAF7KNMdQ14WNrPwGjDOzG/6mUKhoDSddY6GeZ337Ivqm X-Developer-Key: i=levymitchell0@gmail.com; a=ed25519; pk=n6kBmUnb+UNmjVkTnDwrLwTJAEKUfs2e8E+MFPZI93E= Add a CpuGuard type that disables preemption for its lifetime. Add a PerCpuVariable type used for declaring per-CPU variables and a declare_per_cpu! macro for its use. Add a PerCpuRef that allows actual use of the per-CPU variable and an usafe_get_per_cpu_ref! helper macro to convert PerCpuVariable to PerCpuRef. Signed-off-by: Mitchell Levy --- rust/helpers/helpers.c | 1 + rust/helpers/preempt.c | 14 ++++ rust/kernel/lib.rs | 3 + rust/kernel/percpu.rs | 161 ++++++++++++++++++++++++++++++++++++= ++++ rust/kernel/percpu/cpu_guard.rs | 29 ++++++++ 5 files changed, 208 insertions(+) diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c index dcf827a61b52..1db0dcd8f11f 100644 --- a/rust/helpers/helpers.c +++ b/rust/helpers/helpers.c @@ -19,6 +19,7 @@ #include "mutex.c" #include "page.c" #include "pid_namespace.c" +#include "preempt.c" #include "rbtree.c" #include "refcount.c" #include "security.c" diff --git a/rust/helpers/preempt.c b/rust/helpers/preempt.c new file mode 100644 index 000000000000..2c7529528ddd --- /dev/null +++ b/rust/helpers/preempt.c @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include + +void rust_helper_preempt_disable(void) +{ + preempt_disable(); +} + +void rust_helper_preempt_enable(void) +{ + preempt_enable(); +} + diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index e1065a7551a3..3634e1412d60 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -49,6 +49,9 @@ #[cfg(CONFIG_NET)] pub mod net; pub mod page; +// Only x86_64 is supported by percpu for now +#[cfg(CONFIG_X86_64)] +pub mod percpu; pub mod pid_namespace; pub mod prelude; pub mod print; diff --git a/rust/kernel/percpu.rs b/rust/kernel/percpu.rs new file mode 100644 index 000000000000..08fcc8797078 --- /dev/null +++ b/rust/kernel/percpu.rs @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: GPL-2.0 +//! This module contains abstractions for creating and using per-CPU varia= bles from Rust. In +//! particular, see the define_per_cpu! and unsafe_get_per_cpu_ref! macros. +pub mod cpu_guard; + +use crate::percpu::cpu_guard::CpuGuard; +use crate::unsafe_get_per_cpu_ref; + +use core::arch::asm; +use core::marker::PhantomData; +use core::ops::{Deref, DerefMut}; + +/// A PerCpuRef is obtained by the unsafe_get_per_cpu_ref! macro used on a= PerCpuVariable defined +/// via the define_per_cpu! macro. +/// +/// This type will transparently deref(mut) into a &(mut) T referencing th= is CPU's instance of the +/// underlying variable. +pub struct PerCpuRef { + offset: usize, + deref_type: PhantomData, + _guard: CpuGuard, +} + +/// A wrapper used for declaring static per-cpu variables. These symbols a= re "virtual" in that the +/// linker uses them to generate offsets into each cpu's per-cpu area, but= shouldn't be read +/// from/written to directly. The fact that the statics are immutable prev= ents them being written +/// to (generally), this struct having _val be non-public prevents reading= from them. +/// +/// The end-user of the per-CPU API should make use of the define_per_cpu!= macro instead of +/// declaring variables of this type directly. +#[repr(transparent)] +pub struct PerCpuVariable { + _val: T, // generate a correctly sized type +} + +impl PerCpuRef { + /// You should be using the unsafe_get_per_cpu! macro instead + /// + /// # Safety + /// offset must be a valid offset into the per cpu area + pub unsafe fn new(offset: usize, guard: CpuGuard) -> Self { + PerCpuRef { + offset, + deref_type: PhantomData, + _guard: guard, + } + } + + /// Computes this_cpu_ptr as a usize, ignoring issues of ownership and= borrowing + fn this_cpu_ptr_usize(&self) -> usize { + // SAFETY: this_cpu_off is read only as soon as the per-CPU subsys= tem is initialized + let off: PerCpuRef =3D unsafe { unsafe_get_per_cpu_ref!(this_= cpu_off, CpuGuard::new()) }; + let mut this_cpu_area: usize; + // SAFETY: gs + off_val is guaranteed to be a valid pointer by the= per-CPU subsystem and + // the invariants guaranteed by PerCpuRef (i.e., off.offset is val= id) + unsafe { + asm!( + // For some reason, the asm! parser doesn't like + // mov {out}, [gs:{off_val}] + // so we use the less intuitive prefix version instead + "gs mov {out}, [{off_val}]", + off_val =3D in(reg) off.offset, + out =3D out(reg) this_cpu_area, + ) + }; + this_cpu_area + self.offset + } + + /// Returns a pointer to self's associated per-CPU variable. Logically= equivalent to C's + /// this_cpu_ptr + pub fn this_cpu_ptr(&self) -> *const T { + self.this_cpu_ptr_usize() as *const T + } + + /// Returns a mut pointer to self's associated per-CPU variable. Logic= ally equivalent to C's + /// this_cpu_ptr + pub fn this_cpu_ptr_mut(&mut self) -> *mut T { + self.this_cpu_ptr_usize() as *mut T + } +} + +impl Deref for PerCpuRef { + type Target =3D T; + fn deref(&self) -> &Self::Target { + // SAFETY: By the contract of unsafe_get_per_cpu_ref!, we know tha= t self is the only + // PerCpuRef associated with the underlying per-CPU variable and t= hat the underlying + // variable is not mutated outside of rust. + unsafe { &*(self.this_cpu_ptr()) } + } +} + +impl DerefMut for PerCpuRef { + fn deref_mut(&mut self) -> &mut Self::Target { + // SAFETY: By the contract of unsafe_get_per_cpu_ref!, we know tha= t self is the only + // PerCpuRef associated with the underlying per-CPU variable and t= hat the underlying + // variable is not mutated outside of rust. + unsafe { &mut *(self.this_cpu_ptr_mut()) } + } +} + +/// define_per_cpu! is analogous to the C DEFINE_PER_CPU macro in that it = lets you create a +/// statically allocated per-CPU variable. +/// +/// # Example +/// ``` +/// use kernel::define_per_cpu; +/// use kernel::percpu::PerCpuVariable; +/// +/// define_per_cpu!(pub MY_PERCPU: u64 =3D 0); +/// ``` +#[macro_export] +macro_rules! define_per_cpu { + ($vis:vis $id:ident: $ty:ty =3D $expr:expr) =3D> { + $crate::macros::paste! { + // Expand $expr outside of the unsafe block to avoid silently = allowing unsafe code to be + // used without a user-facing unsafe block + static [<__init_ $id>]: $ty =3D $expr; + + // SAFETY: PerCpuVariable is #[repr(transparent)], so we ca= n freely convert from T + #[link_section =3D ".data..percpu"] + $vis static $id: PerCpuVariable<$ty> =3D unsafe { + core::mem::transmute::<$ty, PerCpuVariable<$ty>>([<__init_= $id>]) + }; + } + }; +} + +/// Goes from a PerCpuVariable to a usable PerCpuRef. $id is the identifie= r of the PerCpuVariable +/// and $guard is an expression that evaluates to a CpuGuard. +/// +/// # Safety +/// Don't create two PerCpuRef that point at the same per-cpu variable, as= this would allow you to +/// accidentally break aliasing rules. Unless T is Sync, the returned PerC= puRef should not be used +/// from interrupt contexts. +/// +/// If $id is `extern "C"` (i.e., declared via declare_extern_per_cpu!) th= en the underlying per-CPU +/// variable must not be written from C code while a PerCpuRef exists in R= ust. That is, the +/// underlying per-CPU variable must not be written in any IRQ context (un= less the user ensures +/// IRQs are disabled) and no FFI calls can be made to C functions that ma= y write the per-CPU +/// variable. The underlying PerCpuVariable created via declare_extern_per= _cpu must also have the +/// correct type. +#[macro_export] +macro_rules! unsafe_get_per_cpu_ref { + ($id:ident, $guard:expr) =3D> {{ + let off =3D core::ptr::addr_of!($id); + PerCpuRef::new(off as usize, $guard) + }}; +} + +/// Declares a PerCpuVariable corresponding to a per-CPU variable defined = in C. Be sure to read the +/// safety requirements of unsafe_get_per_cpu_ref!. +#[macro_export] +macro_rules! declare_extern_per_cpu { + ($id:ident: $ty:ty) =3D> { + extern "C" { + static $id: PerCpuVariable<$ty>; + } + }; +} + +declare_extern_per_cpu!(this_cpu_off: u64); diff --git a/rust/kernel/percpu/cpu_guard.rs b/rust/kernel/percpu/cpu_guard= .rs new file mode 100644 index 000000000000..6f7d320a5c9a --- /dev/null +++ b/rust/kernel/percpu/cpu_guard.rs @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 +//! Contains abstractions for disabling CPU preemption. See CpuGuard. + +/// A RAII guard for bindings::preempt_disable and bindings::preempt_enabl= e. Guarantees preemption +/// is disabled for as long as this object exists. +pub struct CpuGuard { + // Don't make one without using new() + _phantom: (), +} + +impl CpuGuard { + /// Create a new CpuGuard. Disables preemption for its lifetime. + pub fn new() -> Self { + // SAFETY: There are no preconditions required to call preempt_dis= able + unsafe { + bindings::preempt_disable(); + } + CpuGuard { _phantom: () } + } +} + +impl Drop for CpuGuard { + fn drop(&mut self) { + // SAFETY: There are no preconditions required to call preempt_ena= ble + unsafe { + bindings::preempt_enable(); + } + } +} --=20 2.34.1 From nobody Mon Feb 9 11:26:48 2026 Received: from mail-pl1-f178.google.com (mail-pl1-f178.google.com [209.85.214.178]) (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 F04401D7E45; Thu, 19 Dec 2024 21:08:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734642530; cv=none; b=RwzUeuv3KB5dxvh/FstXB/4vvSSR+eJNlEt4YUKizomOw7MlL6wTr9ovEikOz9AVsVAtSSPUTHiOR/Yuq9N2rUS0KG2XT7shLthZbm1PFKV7CsQn5Rm9WJ93Gia/Uh3XdKVG/ICmRWfcfEIGu2XK4iBnLe5HQcDkIENGuPayEtg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734642530; c=relaxed/simple; bh=lY27LEhr/RrYnOIR8z3fQ4J3MpeoCX1CqLVxrfhFCU8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AeMQxfboSbCuFBk902xvmZgMP+d4NbDkh+FHu+D4a+hfdAB+DW26ScsTMOa5eJgO2Y/I1B8iYFj6fO6v9rm70bBkgvTa0kVFj3ju5B8CaifklSieHH/V7KKJtdFg7ZEegIRCdjMhpdH/DASfFbEqW5KMAiQaZzH2vOfrNIsLUgw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=h8tQUDtY; arc=none smtp.client-ip=209.85.214.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="h8tQUDtY" Received: by mail-pl1-f178.google.com with SMTP id d9443c01a7336-21654fdd5daso11915735ad.1; Thu, 19 Dec 2024 13:08:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1734642528; x=1735247328; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=SeeL6HPCkGqR+iss0d46HW94C36VOktwSeHKqW1zTWU=; b=h8tQUDtYOfy7WqoqloRvXvxcMLqIEibqwpMk5qRpLA9i2POBqfCXTMCdoXBYD9Sq3i /eJYJZ0ZgckslgkFTUOH8Q9vt+pcwMEbaiEW/YFkjwSI01rfmklDwwhg8PvIpomfIIQl QfKoIVsVXzhNl/7AHw5udnBtNQ21BWyOb/ztHboUoLvgCYhJptt+o1VSIeNAItcyeZ7v RPT4aEJLNGlhx9zDWHBzCXRWI8DP/RjKJ4i4mt4v415SREti+/90BcRKzeZTN6xLvvMo 1jinkBZSqZCS+hOn1CcbxUA7QQMqFRZGlYzq5MzQIrQJjWAUFMT+5SDDa1voY6VGfr3C aagw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1734642528; x=1735247328; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=SeeL6HPCkGqR+iss0d46HW94C36VOktwSeHKqW1zTWU=; b=Lu4V8lLI3440gqU1r4xzNbWO4+jU8HDRo9p2NrswUyXTSOfRVl329ORgFfeNANTzm/ RuFQ4Vk9uco+SdlaoVYSrAGk3b4JtiDFVpo52teTgskv90+XWpSBUXq7JyDmjLqLyOBL aY+RdaC34aXNM3ElryG1T/JqGhjlIO5fB9XFqfQqlSjb9qCIixKvCQLxBVSPm2cbI05Y NQfiuv+7Ng+upw2k6iHxuXJRAxOqvyapP0/Z0ZTZ5tGfys7E4QQPs19QA9iaQc1sTc5m AFUdb2RmCOqTvWdS8kwKCcqXjt17gnUnl7cC7TfjRyUxVLheJvlj0b8OZ+KW+3lzU+JJ KUHA== X-Forwarded-Encrypted: i=1; AJvYcCXUYHfIgpu80D8nKTEvvDBQilbV4Wtz4XqXYZcf732m5ROPeEs5uTOw4XTaPibbHZYLTqlsusqY6qi5Lt9IHQ==@vger.kernel.org X-Gm-Message-State: AOJu0YxSQtNq2SB9snyGMeLGRadXmPtYfxIxBUGeaMFzmSua96HqFJlU uSe0eLoBun0llhynDqrAM0IttTUfQDlmN8vjLmV9oCQAekixLovU X-Gm-Gg: ASbGncvFksIu8mGxIkbiQjvZIEn8r9VeE9FjeBEFoldVX83DE/DofhHjsJk9pkwcjJp 8UbizelVBry4Trm5kE9b3NsNZWyWggM6iWMNZTe1xAlWkDw7Zytbh2GvD/7DmcXxrXMNNw5Kc10 IEMA5W9bi/oTSXS9tAN7zfqKxaYs7RGV2G5z+ZyEdNm4ty4mTlIFrSyWGWhBIFiilnZrk7r5Nrw OzchHycMBVvSSYiIgnulNAAm4u+a8PoSfQPHiKL/4WzILeYF6ychBSVGYdKr3rtjA== X-Google-Smtp-Source: AGHT+IF/1tM3WCgqS4vfhViKK0R9nsVTEMtAfdNwyZiWjLZy3SwsOJSvD1LICQhf2BHaA/XvshYH/Q== X-Received: by 2002:a17:902:ebc6:b0:216:1cf8:8b8 with SMTP id d9443c01a7336-219e6ebe15emr3313535ad.27.1734642528276; Thu, 19 Dec 2024 13:08:48 -0800 (PST) Received: from mitchelllevy. ([174.127.224.194]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-219dc962cc3sm16831755ad.28.2024.12.19.13.08.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Dec 2024 13:08:47 -0800 (PST) From: Mitchell Levy Date: Thu, 19 Dec 2024 13:08:27 -0800 Subject: [PATCH RFC 2/3] rust: rust-analyzer: add lib to dirs searched for crates Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241219-rust-percpu-v1-2-209117e822b1@gmail.com> References: <20241219-rust-percpu-v1-0-209117e822b1@gmail.com> In-Reply-To: <20241219-rust-percpu-v1-0-209117e822b1@gmail.com> To: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Andrew Morton , Dennis Zhou , Tejun Heo , Christoph Lameter Cc: linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-mm@kvack.org, Mitchell Levy X-Mailer: b4 0.14.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1734642524; l=916; i=levymitchell0@gmail.com; s=20240719; h=from:subject:message-id; bh=lY27LEhr/RrYnOIR8z3fQ4J3MpeoCX1CqLVxrfhFCU8=; b=mwtTmJIpnuguPatbGcieMpjbUb5v3yLgy1KPUvNYJhpLHNbxO1HwQtsnaFhqxc/yuAMoKljZH own5+keq+syBDNH0fM3Z66LWAo5xjtxa2gnmh6vJFnKBtyFvvi40Xs9 X-Developer-Key: i=levymitchell0@gmail.com; a=ed25519; pk=n6kBmUnb+UNmjVkTnDwrLwTJAEKUfs2e8E+MFPZI93E= When generating rust-project.json, also include crates in lib/ Signed-off-by: Mitchell Levy --- scripts/generate_rust_analyzer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_anal= yzer.py index 09e1d166d8d2..7d7ffb45fc0c 100755 --- a/scripts/generate_rust_analyzer.py +++ b/scripts/generate_rust_analyzer.py @@ -109,7 +109,7 @@ def generate_crates(srctree, objtree, sysroot_src, exte= rnal_src, cfgs): # Then, the rest outside of `rust/`. # # We explicitly mention the top-level folders we want to cover. - extra_dirs =3D map(lambda dir: srctree / dir, ("samples", "drivers")) + extra_dirs =3D map(lambda dir: srctree / dir, ("samples", "drivers", "= lib")) if external_src is not None: extra_dirs =3D [external_src] for folder in extra_dirs: --=20 2.34.1 From nobody Mon Feb 9 11:26:48 2026 Received: from mail-pl1-f169.google.com (mail-pl1-f169.google.com [209.85.214.169]) (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 6F265207DF2; Thu, 19 Dec 2024 21:08:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734642532; cv=none; b=HC2HfhXcKBjT9uw41B7eBgbQDxWNbAEpr9E8/o20LShxzZlxIsc0H32MXNjImVIVjOBgcWBiLowE9G2XJXrANNb47WDZWzWmT8Js4bEgwgpewEE9pU6uJBYL8Q+F6811hFk5JKrQaA2hLS0Y6BEq1sv54AiDReqRiTcmqBjjhrY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734642532; c=relaxed/simple; bh=Fg46h50fzfyqtIe9aDLmvc/Zzgw12ckY/xFnT5ZEMe0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=L2x6GxZ89kGppYze4MG3Hu7IVCj4xRkQ85WtovRnDlOzoYvLCCDZTFySfb3qW8egVICG1Ga7gIxpwX04CfKc36okTdD68Yum1OI2i0wBwVLH6QTOWzERd43st2UdehnKSrn8kqt4EijGaHvL2bPJfv6OvlSaRVmUMWr49S3HZR0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=j5TKHPiD; arc=none smtp.client-ip=209.85.214.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="j5TKHPiD" Received: by mail-pl1-f169.google.com with SMTP id d9443c01a7336-21661be2c2dso10238205ad.1; Thu, 19 Dec 2024 13:08:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1734642530; x=1735247330; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=8a+U3PThiCkoSQIjCSeZhobcfZFrIgDLb2tUjSaHx4Y=; b=j5TKHPiD50eex8hHULMDnT9MtFxPW7TWz+5R50/BJUTdKd4813OvmTQCQAw/TI+uep lnf4h0u1Tl3QmdDAJLLTdKYXUafFbX5TMJdEnhb/Oxj6uLby824Z4UhVyIgfmC8VfKbH LeJkN7c4Cg3AvIEwhZFUoj51h7MfTm8qw+iK6A7zSWXLuZEhM7wMv8QA+n074qarilBv DtppH+F+NFPHmixIDe8G+PWqUF22apoGLUqWU+aN2k72hcLPLQYWmZrUw1qBIsXQxM6g 665ZeT8nHfWJtFlx+E6hofkiujk1hdH8NdTdMQBV8An/94Gin/ZnKAP+HdLxIHPiH8hx mfsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1734642530; x=1735247330; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8a+U3PThiCkoSQIjCSeZhobcfZFrIgDLb2tUjSaHx4Y=; b=ska2WD5qJDgnCEl5Aws8RZBWXs8SGwhuzeRbg3ta1ScsBCz/YqpD3r1x1dXUFqzkdE PsYvW/jtbH3xek62yRhy3p4pXHrLMrB2jttl1rnrzLQelzwKNW9oanwO9GMoau4oBvTJ R2v7HhxKZ1PhE4MnYyqY03Iz6C0sK3oJI838+EzK2P3t7I59S5DfpgZ2xlPN2rXDBJTg MXVAARHMD2GhjY7u+hwOAbxgAl5wlIciZaSnlZ0tVQlCmH82nuep0BCLdAY7XrsPspJd bNqoPHldoveTit7cGNhZSSXGCNBh22Tfu+EpZek/3D/HFKtPXjk8E/Z6oNr4C73gIFRp nVSA== X-Forwarded-Encrypted: i=1; AJvYcCWsqMyrh5wavtBYGunkMn551YjNuako/76gosE/Ne9gfHp2JRv3NBXGwZwnhaGTbVm5kIA09/KLmD6cMcn/mQ==@vger.kernel.org X-Gm-Message-State: AOJu0Yy6/J6/yhSn29UI2RpozEhYIl2uXF7ZTi2An//pwme6qREI6Vdh fknH/rnxIGyis2UJxI6J5zb81nlilWRZDOFpuXwj9RFAFArR6EMa X-Gm-Gg: ASbGncuV1jbYLTgsF8xDi28QEp+lCE87YisgMu9VbmYokozmdfM03oQVwLQnVO9c/LG Tfc4V1scXSSW0NT567GiVPknsXaRAZ6ITob5qQILEi/ePovXiC98SArccAQzrGEEFqjDa46ebe8 q92K8+DcGhhEfrUKEZ2o6RYKtYVmjAIr8EzksBVaz/H9rVnrubYka16hPCpEtlzgdE3gqMOqq+A Z1xC4oOGzX2KSk26aAY/IGYyCwlKTQ+zgUGUOd28GTUFOx7fY5/1u3uy2AODqZnYQ== X-Google-Smtp-Source: AGHT+IFlNR+5xs9cq8NpBSRrS++zF1DZpmnXPo5bkWp0elc/Vz4dUHAxNDYhcGSHRx+In+/jxMSo4Q== X-Received: by 2002:a17:902:e5c7:b0:215:19ae:77bf with SMTP id d9443c01a7336-219e6e9df25mr3132215ad.19.1734642529695; Thu, 19 Dec 2024 13:08:49 -0800 (PST) Received: from mitchelllevy. ([174.127.224.194]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-219dc962cc3sm16831755ad.28.2024.12.19.13.08.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Dec 2024 13:08:49 -0800 (PST) From: Mitchell Levy Date: Thu, 19 Dec 2024 13:08:28 -0800 Subject: [PATCH RFC 3/3] rust: percpu: add a rust per-CPU variable test Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20241219-rust-percpu-v1-3-209117e822b1@gmail.com> References: <20241219-rust-percpu-v1-0-209117e822b1@gmail.com> In-Reply-To: <20241219-rust-percpu-v1-0-209117e822b1@gmail.com> To: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Andrew Morton , Dennis Zhou , Tejun Heo , Christoph Lameter Cc: linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-mm@kvack.org, Mitchell Levy X-Mailer: b4 0.14.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1734642524; l=3571; i=levymitchell0@gmail.com; s=20240719; h=from:subject:message-id; bh=Fg46h50fzfyqtIe9aDLmvc/Zzgw12ckY/xFnT5ZEMe0=; b=gRK8pwjQ4BF4Qdvi0zi3CaQNn7uKJ8Q0n/gQMpX5Cf5J3e0PE0ANTZflDXvPIbayToRUWQhb6 +IFU6CcSailB8h8pm97y0hJlg8MH3QTdhZycACwBxubTmMZBxvl+/zV X-Developer-Key: i=levymitchell0@gmail.com; a=ed25519; pk=n6kBmUnb+UNmjVkTnDwrLwTJAEKUfs2e8E+MFPZI93E= Add a short exercise for Rust's per-CPU variable API, modelled after lib/percpu_test.c Signed-off-by: Mitchell Levy --- lib/Kconfig.debug | 9 +++++++ lib/Makefile | 1 + lib/percpu_test_rust.rs | 65 +++++++++++++++++++++++++++++++++++++++++++++= ++++ 3 files changed, 75 insertions(+) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index f3d723705879..75a91f1766ce 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -2404,6 +2404,15 @@ config PERCPU_TEST =20 If unsure, say N. =20 +config PERCPU_TEST_RUST + tristate "Rust per cpu operations test" + depends on m && DEBUG_KERNEL && RUST + help + Enable this option to build a test module which validates Rust per-cpu + operations. + + If unsure, say N. + config ATOMIC64_SELFTEST tristate "Perform an atomic64_t self-test" help diff --git a/lib/Makefile b/lib/Makefile index a8155c972f02..0ea8d414763c 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -301,6 +301,7 @@ obj-$(CONFIG_RBTREE_TEST) +=3D rbtree_test.o obj-$(CONFIG_INTERVAL_TREE_TEST) +=3D interval_tree_test.o =20 obj-$(CONFIG_PERCPU_TEST) +=3D percpu_test.o +obj-$(CONFIG_PERCPU_TEST_RUST) +=3D percpu_test_rust.o =20 obj-$(CONFIG_ASN1) +=3D asn1_decoder.o obj-$(CONFIG_ASN1_ENCODER) +=3D asn1_encoder.o diff --git a/lib/percpu_test_rust.rs b/lib/percpu_test_rust.rs new file mode 100644 index 000000000000..60df44332d7a --- /dev/null +++ b/lib/percpu_test_rust.rs @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-2.0 +//! A simple self test for the rust per-CPU API. +use kernel::{ + define_per_cpu, percpu::cpu_guard::*, percpu::*, pr_info, prelude::*, = unsafe_get_per_cpu_ref, +}; + +module! { + type: PerCpuTestModule, + name: "percpu_test_rust", + author: "Mitchell Levy", + description: "Test code to exercise the Rust Per CPU variable API", + license: "GPL v2", +} + +struct PerCpuTestModule; + +define_per_cpu!(PERCPU: i64 =3D 0); +define_per_cpu!(UPERCPU: u64 =3D 0); + +impl kernel::Module for PerCpuTestModule { + fn init(_module: &'static ThisModule) -> Result { + pr_info!("rust percpu test start\n"); + + let mut native: i64 =3D 0; + let mut pcpu: PerCpuRef =3D unsafe { unsafe_get_per_cpu_ref!(= PERCPU, CpuGuard::new()) }; + + native +=3D -1; + *pcpu +=3D -1; + assert!(native =3D=3D *pcpu && native =3D=3D -1); + + native +=3D 1; + *pcpu +=3D 1; + assert!(native =3D=3D *pcpu && native =3D=3D 0); + + let mut unative: u64 =3D 0; + let mut upcpu: PerCpuRef =3D + unsafe { unsafe_get_per_cpu_ref!(UPERCPU, CpuGuard::new()) }; + + unative +=3D 1; + *upcpu +=3D 1; + assert!(unative =3D=3D *upcpu && unative =3D=3D 1); + + unative =3D unative.wrapping_add((-1i64) as u64); + *upcpu =3D upcpu.wrapping_add((-1i64) as u64); + assert!(unative =3D=3D *upcpu && unative =3D=3D 0); + + unative =3D unative.wrapping_add((-1i64) as u64); + *upcpu =3D upcpu.wrapping_add((-1i64) as u64); + assert!(unative =3D=3D *upcpu && unative =3D=3D (-1i64) as u64); + + unative =3D 0; + *upcpu =3D 0; + + unative =3D unative.wrapping_sub(1); + *upcpu =3D upcpu.wrapping_sub(1); + assert!(unative =3D=3D *upcpu && unative =3D=3D (-1i64) as u64); + assert!(unative =3D=3D *upcpu && unative =3D=3D u64::MAX); + + pr_info!("rust percpu test done\n"); + + // Return Err to unload the module + Result::Err(EINVAL) + } +} + --=20 2.34.1