From nobody Sat Jul 25 15:51:37 2026 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) (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 486C141E6CC for ; Thu, 16 Jul 2026 12:34:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784205292; cv=none; b=Ag4/KjaTzaHzk1vP4g12+evXyVQxQU+z2inx+TMM6gZpDVHB/jbfgESHCILlL4VLFo7EsWmaIGJmCUVSO74eZHwtvXMM47fJYtkRQwr5UOS3n2cYiYLQv3ejNGIqhOK4I9ZnMi399ZBNvFoeuD+P0nCaEBaCoBILPBZHd3rGyRY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784205292; c=relaxed/simple; bh=F3XfE2qmquOsjgl5Z7SgmdoRF1G91H01/1f0xHWJi/c=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=qIOH4ufYlF50bedpaThnuLtmQAjgGYlm7t3+/9yXijRE8yPcxjtV8cUPGQftZQ7+gDecw4CloRIHXy9sDKi0dbmjTxCmvzY9jsxtQ5SdIuekhXtjHg5iMBiEAfkcoqDOUcf3Li50zJ/gAHWmKpZl6TXkg3TY2VBcxbCe4sKVZHs= 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=gTnHaGZ4; arc=none smtp.client-ip=209.85.221.74 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="gTnHaGZ4" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-47f4bff865cso1565619f8f.0 for ; Thu, 16 Jul 2026 05:34:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1784205286; x=1784810086; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=CcHRQa5oaNT52Q3NzivF4AOmmeBmFBenYIo8+2bH3+U=; b=gTnHaGZ4lbT7PsE/nDcuT33Dt/xLpTU7LktH4Wsd4g+VhwL9+gEYu4GYEPaSCFaW25 pSTYvf+jXp7t9eX7ZsISqiqAleMYJUZGbprm9HaZG4dF8rCObbkwUKREfOcw7VxAPa6b /09Gpc/N7gk2eLXmRpR0Zrahjf4LyHuCLYh1VmnEKpHzuAU7Zuqc/Ew5Bn2ExlbuMf6N osnalzWuiPiIEK6S8zqyiPj8q5tXoetD2pI2yDnAAYkrXHzuirLWBD16bZ5yG+C6d6bL vi+RZTuRM4HMSbw/nSJlx+vsSnq6cTMZrSsFwOl9SbejnuqknFj8SmPhc2Vzmfjl4kUC oo/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784205286; x=1784810086; h=content-type: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:content-type; bh=CcHRQa5oaNT52Q3NzivF4AOmmeBmFBenYIo8+2bH3+U=; b=QJSSAsz5t964uq2AEbCU3yL9wOWzQNqsirmHKcCvtv1wP90ryOiiGywIjyB1jZ7plc ZgaHcKeBU2InGzT8awkVtT1DBIH3xf74CpR/VKlqiXHlV3mCwlwNiH8mgM0oxWPtq3UA EkdtEI9gqMcHRd14q9tWiisPHgSG8inOJBFXZYNKQrKj90VSZsc5aRD1OT6pPZkeo4n0 kYtWEZ6IkXKAURGr3SjOp9KuFwwwzw4bgwYOdMuQI7suDq3V+m5b+JoG0jEXhHCcDXld 2JFo58cSjFgjTPBhkuBrlQdSQ1M20SE/nJ7NJjrU1bk2yzPiauBi50eephtRz/dkUb+c UYxA== X-Forwarded-Encrypted: i=1; AHgh+Ro8sQeM3p78zioklvvmuHxBpGjMU07Rd2ArGtBDFGi5dW55rrZM8IVrCjwyZO5+LHUsVYImpWOB2xS6rDo=@vger.kernel.org X-Gm-Message-State: AOJu0YwV+vnDBaA2WEq0n47n+TiKzWmAByHfeRwvHX/5mkxQmGFfHIk1 HbHNp3xsVissp+3j6pSkYoiBdmfJaA2W896pTnj7oMOHifPP7zBkV0z4nq88b09F4/WpuY09Ywr uyhfOqK8SxpP8mwByOw== X-Received: from wrvi4.prod.google.com ([2002:a5d:5584:0:b0:47f:3eaa:11e1]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:178b:b0:47f:2de3:b351 with SMTP id ffacd0b85a97d-47f4634dd31mr15994410f8f.26.1784205285556; Thu, 16 Jul 2026 05:34:45 -0700 (PDT) Date: Thu, 16 Jul 2026 12:34:25 +0000 In-Reply-To: <20260716-pr-ratelimited-v2-0-31c27a4543d2@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260716-pr-ratelimited-v2-0-31c27a4543d2@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=11207; i=aliceryhl@google.com; h=from:subject:message-id; bh=F3XfE2qmquOsjgl5Z7SgmdoRF1G91H01/1f0xHWJi/c=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBqWM/iVDgYXKSHMFQ2++zmGF5G3oQOlRAGCOgpA M4ZMwY8jLiJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCaljP4gAKCRAEWL7uWMY5 RtEaD/9KW/JA2rWruHWbEO2E5cC9DljvaeFIjSkd91BzBWwESyiGAoZ/GE22uEWmYWwfbD7GLRG 81WKqtnnhjnHUTQwEkvdSEowgyX2UzB9f1u3jdIOqijVamSyr5Uqm7TDjRR1x1qlLcLAfeqPKgQ UAWNWg0LIq9LQJnhy40tqtMpXVKlm9fld9awRpIOE8XanE25h4s7QGop8cVMOk/HeND5oBDi51W vnyArAzzLdmL6Y9aPMoV65o2m2SfP71XsdEuxR4GhY4br8MUPpHSLcXAmlOjw/NTEJ2g1wKsc37 26xjLuj0Opf/eh1KvzyadXWZkKNCt7bo1lyAWB/gDiIKEtus7it/NOkcRay0z9Dl1pYWgaoIpyv d+Odb95KAXwEwOvY3uvSgLB095MS4TJ1m0iZD4gnjPTkfHzwcrdUmwmMuYenCKwqng/CdSlkLan RetTh6ZYwA/Sy09UJLWxzr/6tZLXsFs55AfJBlOvxUvE+9U5DTcnJCpBRBtroAVaDn4RImH+vqP 4gJ7fiMENglhbp5zqQhBe66Gx39PDAliO9WdbEzCmWwFkWgoACiM/xa2RL1TsmXc+ZW0nZDAoIN Qlsx3PNTzD0uJzDCuOpCPIxouCBZcGoNsdVlxpuaVGdn0kyAy44snOUFHe4ufWo6edkQxHAk1wP xaIPtuud6ga9N0w== X-Mailer: b4 0.14.3 Message-ID: <20260716-pr-ratelimited-v2-1-31c27a4543d2@google.com> Subject: [PATCH v2 1/5] rust: sync: move lockdep types to rust/kernel/sync/lockdep.rs From: Alice Ryhl To: Greg Kroah-Hartman , Carlos Llamas , Boqun Feng , Gary Guo Cc: "=?utf-8?q?Onur_=C3=96zkan?=" , Andreas Hindborg , Benno Lossin , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Daniel Almeida , Danilo Krummrich , Ingo Molnar , Lyude Paul , Miguel Ojeda , Peter Zijlstra , Trevor Gross , Waiman Long , Will Deacon , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, Alice Ryhl Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The lockdep types are currently stored directly in rust/kernel/sync.rs, but there are starting to be too many of them to keep them in that file. Thus, move them to a submodule. For commonly used lockdep logic it's useful to keep re-exports in kernel::sync, and this also avoids the need to update any users. Reviewed-by: Gary Guo Reviewed-by: Boqun Feng Reviewed-by: Carlos Llamas Signed-off-by: Alice Ryhl --- rust/kernel/sync.rs | 135 +---------------------------------------= -- rust/kernel/sync/lockdep.rs | 139 ++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 141 insertions(+), 133 deletions(-) diff --git a/rust/kernel/sync.rs b/rust/kernel/sync.rs index 993dbf2caa0e..e87a7e339994 100644 --- a/rust/kernel/sync.rs +++ b/rust/kernel/sync.rs @@ -5,10 +5,6 @@ //! This module contains the kernel APIs related to synchronisation that h= ave been ported or //! wrapped for usage by Rust code in the kernel. =20 -use crate::prelude::*; -use crate::types::Opaque; -use pin_init; - mod arc; pub mod aref; pub mod atomic; @@ -16,6 +12,7 @@ pub mod completion; mod condvar; pub mod lock; +pub mod lockdep; mod locked_by; pub mod poll; pub mod rcu; @@ -28,135 +25,7 @@ pub use lock::global::{global_lock, GlobalGuard, GlobalLock, GlobalLockBac= kend, GlobalLockedBy}; pub use lock::mutex::{new_mutex, Mutex, MutexGuard}; pub use lock::spinlock::{new_spinlock, SpinLock, SpinLockGuard}; +pub use lockdep::{static_lock_class, LockClassKey}; pub use locked_by::LockedBy; pub use refcount::Refcount; pub use set_once::SetOnce; - -/// Represents a lockdep class. -/// -/// Wraps the kernel's `struct lock_class_key`. -#[repr(transparent)] -#[pin_data(PinnedDrop)] -pub struct LockClassKey { - #[pin] - inner: Opaque, -} - -// SAFETY: Unregistering a lock class key from a different thread than whe= re it was registered is -// allowed. -unsafe impl Send for LockClassKey {} - -// SAFETY: `bindings::lock_class_key` is designed to be used concurrently = from multiple threads and -// provides its own synchronization. -unsafe impl Sync for LockClassKey {} - -impl LockClassKey { - /// Initializes a statically allocated lock class key. - /// - /// This is usually used indirectly through the [`static_lock_class!`]= macro. See its - /// documentation for more information. - /// - /// # Safety - /// - /// * Before using the returned value, it must be pinned in a static m= emory location. - /// * The destructor must never run on the returned `LockClassKey`. - pub const unsafe fn new_static() -> Self { - LockClassKey { - inner: Opaque::uninit(), - } - } - - /// Initializes a dynamically allocated lock class key. - /// - /// In the common case of using a statically allocated lock class key,= the - /// [`static_lock_class!`] macro should be used instead. - /// - /// # Examples - /// - /// ``` - /// use kernel::alloc::KBox; - /// use kernel::types::ForeignOwnable; - /// use kernel::sync::{LockClassKey, SpinLock}; - /// use pin_init::stack_pin_init; - /// - /// let key =3D KBox::pin_init(LockClassKey::new_dynamic(), GFP_KERNEL= )?; - /// let key_ptr =3D key.into_foreign(); - /// - /// { - /// stack_pin_init!(let num: SpinLock =3D SpinLock::new( - /// 0, - /// c"my_spinlock", - /// // SAFETY: `key_ptr` is returned by the above `into_foreig= n()`, whose - /// // `from_foreign()` has not yet been called. - /// unsafe { > as ForeignOwnable>::borr= ow(key_ptr) } - /// )); - /// } - /// - /// // SAFETY: We dropped `num`, the only use of the key, so the resul= t of the previous - /// // `borrow` has also been dropped. Thus, it's safe to use from_for= eign. - /// unsafe { drop(> as ForeignOwnable>::from_fo= reign(key_ptr)) }; - /// # Ok::<(), Error>(()) - /// ``` - pub fn new_dynamic() -> impl PinInit { - pin_init!(Self { - // SAFETY: lockdep_register_key expects an uninitialized block= of memory - inner <- Opaque::ffi_init(|slot| unsafe { bindings::lockdep_re= gister_key(slot) }) - }) - } - - /// Returns a raw pointer to the inner C struct. - /// - /// It is up to the caller to use the raw pointer correctly. - pub fn as_ptr(&self) -> *mut bindings::lock_class_key { - self.inner.get() - } -} - -#[pinned_drop] -impl PinnedDrop for LockClassKey { - fn drop(self: Pin<&mut Self>) { - // SAFETY: `self.as_ptr()` was registered with lockdep and `self` = is pinned, so the address - // hasn't changed. Thus, it's safe to pass it to unregister. - unsafe { bindings::lockdep_unregister_key(self.as_ptr()) } - } -} - -/// Defines a new static lock class and returns a pointer to it. -/// -/// # Examples -/// -/// ``` -/// use kernel::sync::{static_lock_class, Arc, SpinLock}; -/// -/// fn new_locked_int() -> Result>> { -/// Arc::pin_init(SpinLock::new( -/// 42, -/// c"new_locked_int", -/// static_lock_class!(), -/// ), GFP_KERNEL) -/// } -/// ``` -#[macro_export] -macro_rules! static_lock_class { - () =3D> {{ - static CLASS: $crate::sync::LockClassKey =3D - // SAFETY: The returned `LockClassKey` is stored in static mem= ory and we pin it. Drop - // never runs on a static global. - unsafe { $crate::sync::LockClassKey::new_static() }; - $crate::prelude::Pin::static_ref(&CLASS) - }}; -} -pub use static_lock_class; - -/// Returns the given string, if one is provided, otherwise generates one = based on the source code -/// location. -#[doc(hidden)] -#[macro_export] -macro_rules! optional_name { - () =3D> { - $crate::c_str!(::core::concat!(::core::file!(), ":", ::core::line!= ())) - }; - ($name:literal) =3D> { - $crate::c_str!($name) - }; -} diff --git a/rust/kernel/sync/lockdep.rs b/rust/kernel/sync/lockdep.rs new file mode 100644 index 000000000000..784821cc2a39 --- /dev/null +++ b/rust/kernel/sync/lockdep.rs @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Utilities related to lockdep. +//! +//! C headers: [`include/linux/lockdep.h`](srctree/include/linux/lockdep.h) + +use crate::{ + prelude::*, + types::Opaque, // +}; + +/// Represents a lockdep class. +/// +/// Wraps the kernel's `struct lock_class_key`. +#[repr(transparent)] +#[pin_data(PinnedDrop)] +pub struct LockClassKey { + #[pin] + inner: Opaque, +} + +// SAFETY: Unregistering a lock class key from a different thread than whe= re it was registered is +// allowed. +unsafe impl Send for LockClassKey {} + +// SAFETY: `bindings::lock_class_key` is designed to be used concurrently = from multiple threads and +// provides its own synchronization. +unsafe impl Sync for LockClassKey {} + +impl LockClassKey { + /// Initializes a statically allocated lock class key. + /// + /// This is usually used indirectly through the [`static_lock_class!`]= macro. See its + /// documentation for more information. + /// + /// # Safety + /// + /// * Before using the returned value, it must be pinned in a static m= emory location. + /// * The destructor must never run on the returned `LockClassKey`. + pub const unsafe fn new_static() -> Self { + LockClassKey { + inner: Opaque::uninit(), + } + } + + /// Initializes a dynamically allocated lock class key. + /// + /// In the common case of using a statically allocated lock class key,= the + /// [`static_lock_class!`] macro should be used instead. + /// + /// # Examples + /// + /// ``` + /// use kernel::alloc::KBox; + /// use kernel::types::ForeignOwnable; + /// use kernel::sync::{LockClassKey, SpinLock}; + /// use pin_init::stack_pin_init; + /// + /// let key =3D KBox::pin_init(LockClassKey::new_dynamic(), GFP_KERNEL= )?; + /// let key_ptr =3D key.into_foreign(); + /// + /// { + /// stack_pin_init!(let num: SpinLock =3D SpinLock::new( + /// 0, + /// c"my_spinlock", + /// // SAFETY: `key_ptr` is returned by the above `into_foreig= n()`, whose + /// // `from_foreign()` has not yet been called. + /// unsafe { > as ForeignOwnable>::borr= ow(key_ptr) } + /// )); + /// } + /// + /// // SAFETY: We dropped `num`, the only use of the key, so the resul= t of the previous + /// // `borrow` has also been dropped. Thus, it's safe to use from_for= eign. + /// unsafe { drop(> as ForeignOwnable>::from_fo= reign(key_ptr)) }; + /// # Ok::<(), Error>(()) + /// ``` + pub fn new_dynamic() -> impl PinInit { + pin_init!(Self { + // SAFETY: lockdep_register_key expects an uninitialized block= of memory + inner <- Opaque::ffi_init(|slot| unsafe { bindings::lockdep_re= gister_key(slot) }) + }) + } + + /// Returns a raw pointer to the inner C struct. + /// + /// It is up to the caller to use the raw pointer correctly. + pub fn as_ptr(&self) -> *mut bindings::lock_class_key { + self.inner.get() + } +} + +#[pinned_drop] +impl PinnedDrop for LockClassKey { + fn drop(self: Pin<&mut Self>) { + // SAFETY: `self.as_ptr()` was registered with lockdep and `self` = is pinned, so the address + // hasn't changed. Thus, it's safe to pass it to unregister. + unsafe { bindings::lockdep_unregister_key(self.as_ptr()) } + } +} + +/// Defines a new static lock class and returns a pointer to it. +/// +/// # Examples +/// +/// ``` +/// use kernel::sync::{static_lock_class, Arc, SpinLock}; +/// +/// fn new_locked_int() -> Result>> { +/// Arc::pin_init(SpinLock::new( +/// 42, +/// c"new_locked_int", +/// static_lock_class!(), +/// ), GFP_KERNEL) +/// } +/// ``` +#[macro_export] +macro_rules! static_lock_class { + () =3D> {{ + static CLASS: $crate::sync::LockClassKey =3D + // SAFETY: The returned `LockClassKey` is stored in static mem= ory and we pin it. Drop + // never runs on a static global. + unsafe { $crate::sync::LockClassKey::new_static() }; + $crate::prelude::Pin::static_ref(&CLASS) + }}; +} +pub use static_lock_class; + +/// Returns the given string, if one is provided, otherwise generates one = based on the source code +/// location. +#[doc(hidden)] +#[macro_export] +macro_rules! optional_name { + () =3D> { + $crate::c_str!(::core::concat!(::core::file!(), ":", ::core::line!= ())) + }; + ($name:literal) =3D> { + $crate::c_str!($name) + }; +} --=20 2.55.0.229.g6434b31f56-goog From nobody Sat Jul 25 15:51:37 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.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 8475441F5DF for ; Thu, 16 Jul 2026 12:34:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784205294; cv=none; b=Go/G7N6l6rpGP/99JXFACTcCAa5DBK3OJET2JI54yoHmchREJZDgUJFqSlyz97XEyF0sxla7H2TnU0WEPQua9tLAjOIqJfJqjFxDDVa1fmJWLWFXjRafpmJW8d1E4yJQbokknoMEXXgkU0dfAtZmxRiqazJU7fgIydqI9yAFL3M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784205294; c=relaxed/simple; bh=VJEn9k0cad7bQSpM4TtNmV26i5N7k4ratpVcrf9ivaI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=pPk3vgywrCb/oph9rsf+NWyBfaB2DUUN9CABgvgkWPOWyJMNAGoY2IHHekC2I+pMxbMujuMH19K0SP61XKrPPedyPqQTv4TGNtdzPjYP3rViy/8P/MgGWqpB+i6QJ8dYGuTAXLolkyuTX19mhTPMjIkQfXF4tM+k2eZRiNO68do= 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=L8ZJKNJU; arc=none smtp.client-ip=209.85.128.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="L8ZJKNJU" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-493bf840a69so46727655e9.3 for ; Thu, 16 Jul 2026 05:34:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1784205287; x=1784810087; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=gbRCBYBDraMwLArP9KmBXsMFVhgFXmfSbkHCccVZDpg=; b=L8ZJKNJUI6KRiaL6nTvc1xP7efK7WxVYO3B9DFSTuaRKlEBhVHKd/O5CDOfEtNbykt oRs6ZV7RB+g2Q2a327GfOYPVJiIjXhJBblpJbhFhEuSTVFFLvpZgC7fclOUp5yv7WWhu yCkqbYIJAQ3ewmGOD7JmwDZsCKxcUsNLHYhSFfFNREc1So/VKURaEeD0XunOHnGJRCMM 6aemNXYvN3ONqeSvYDT9jh4/kWI9ri4fV/OaaYzI4MVc52SA0WeBxkDy1IvA3jKgzyKn ASrOXBxyLu9MS1OFBlgpiRrQRf22D77Iag8lLzXDfSHotZavprzksuaTpjXfXO3MuL4l vS4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784205287; x=1784810087; h=content-type: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:content-type; bh=gbRCBYBDraMwLArP9KmBXsMFVhgFXmfSbkHCccVZDpg=; b=CmZ5TYNcuT2kkmKe24SkMZ0b61tVewz4u6Q0TIO5U19UqPcDV3OwD3k4t3jmQtwmBN DFEvNAOamWbJk0UOSypnQCOt/Cw+jE3hbtyAnrnQoU9XOBm7/jCssqMdFxBpAk0WhFhv jt9kzGhmPsJBoU0VxHK64mhT2Q5RzhB820QS+SqQCCQ7wqMPf94vC1W1WABI00o+VXHp y9Blq0RXcrarZ2yL8bbXiWYgqwdokDXhPhk+XSZUq4dS65qnp4qUJHYSEoMflv8v25lU jF3/M+Ty3t6I9XELsRWl1KOQQ5PZ9SabyBZhej6BiqeDNFy61SF/bXo8NUqxfSIyzC4I 7jBA== X-Forwarded-Encrypted: i=1; AHgh+RoYaGyshPmzG/8DBny7IthvZR8Tjbr3mEs6CvIXY50bdZXI+9tUQaoYwM+DCGW9y/PhbRRSZV+XarHr13c=@vger.kernel.org X-Gm-Message-State: AOJu0YwHcj4/96Pm0rgYp13Dz/WRLTaP6Gfp7flK3TAt8k16ANkVqiaj vRo8106c5k1N/LAHOji7JWuVXQkd2VqtGSban+oYzFCs6VQJZxlGWKp6YGDLLQHZBTsgXaOV0re MDEnnBMYpFWXCMk0TCg== X-Received: from wmbdx5.prod.google.com ([2002:a05:600c:63c5:b0:490:b475:af08]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:46c7:b0:495:4044:11ff with SMTP id 5b1f17b1804b1-49540441383mr48255335e9.33.1784205286967; Thu, 16 Jul 2026 05:34:46 -0700 (PDT) Date: Thu, 16 Jul 2026 12:34:26 +0000 In-Reply-To: <20260716-pr-ratelimited-v2-0-31c27a4543d2@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260716-pr-ratelimited-v2-0-31c27a4543d2@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=5073; i=aliceryhl@google.com; h=from:subject:message-id; bh=VJEn9k0cad7bQSpM4TtNmV26i5N7k4ratpVcrf9ivaI=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBqWM/iXLyOlWEYBfW4/1jjGVlHKoI7/XEjhkDVl pFtZFTmD4mJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCaljP4gAKCRAEWL7uWMY5 Rl/JD/0VY9TlA5qNLV1iYoacv02nsZWTv+SRIGzqm+s+kzR1RWkOUFiwO48mdy5gYwICCDi8Ua6 3zbMg0DACh2HBmP31heQZVxYDh5J4vGlVAq7WgbAU49R+s8DB49I+5L0tp63L3d/wz9DHo3wDZ+ NsljI8JucpvHqjlkLbTqr5KysMBPFCi44/Y0op9cbU1ogIHoQD51dWmxXlL5YSJfXSUw3NQ9YJ4 k3ySpgq5NpK2Ru04XFNJXLSAag71s/V+s/JxVdo5jCbNrvwERwk3Mpq8nlM8dgEPrU9eNebvzo5 IGOQwkVryFbf3t6YubT07O3g7Bl457wY4Hrcv24Rt7GmoFGdG98FjO3dBuXoGDt6nceZmLOp0Wx 6wI5Uo2aZspYilqJerMB4js7Y5OSkNiLyX1eMEzjJG5ad+67vreeuos/AePEum8jVTgm+CotRh5 gprJWjbl9vk+w0AnRWFo6enPPXNvvMF44HzjdaqFbavk8Chlrk0djdBqVJ5/L7qOelm0+DzqdMX KatK37qHPxXgyGeFol59RWiIu3Q7P0oj2z+nANhPeC6a2VjyekKrGRg4sizxabqOINjOgR/wfh6 hBbaBKEDwOg7Et82naXVvI0fWpfFI1ickbaLpnIWvYOsnDkHv6Iw6hc29UsZslBqJ2/rgvID1N3 436izqQBoQSIZgA== X-Mailer: b4 0.14.3 Message-ID: <20260716-pr-ratelimited-v2-2-31c27a4543d2@google.com> Subject: [PATCH v2 2/5] rust: sync: add const constructor for raw_spinlock_t From: Alice Ryhl To: Greg Kroah-Hartman , Carlos Llamas , Boqun Feng , Gary Guo Cc: "=?utf-8?q?Onur_=C3=96zkan?=" , Andreas Hindborg , Benno Lossin , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Daniel Almeida , Danilo Krummrich , Ingo Molnar , Lyude Paul , Miguel Ojeda , Peter Zijlstra , Trevor Gross , Waiman Long , Will Deacon , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, Alice Ryhl Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The abstractions for pr_*_ratelimited! need to construct a global `struct ratelimit_state`, which contains a `raw_spinlock_t` field. Thus, add a const constructor for the `raw_spinlock_t` type. The SPINLOCK_OWNER_INIT constant isn't mirrored via a const helper because bindgen generates a 'static mut' instead of a constant from the pointer constant., The __ARCH_SPIN_LOCK_UNLOCKED constant cannot be translated by bindgen because it's a define for a struct without type annotations, so it's explicitly declared in Rust. Reviewed-by: Boqun Feng Reviewed-by: Carlos Llamas Signed-off-by: Alice Ryhl --- include/linux/spinlock_types_raw.h | 4 ++++ rust/bindings/lib.rs | 24 ++++++++++++++++++++++++ rust/kernel/sync/lock/spinlock.rs | 31 +++++++++++++++++++++++++++++++ rust/kernel/sync/lockdep.rs | 22 ++++++++++++++++++++++ 4 files changed, 81 insertions(+) diff --git a/include/linux/spinlock_types_raw.h b/include/linux/spinlock_ty= pes_raw.h index e5644ab2161f..942c229c90bb 100644 --- a/include/linux/spinlock_types_raw.h +++ b/include/linux/spinlock_types_raw.h @@ -11,6 +11,10 @@ =20 #include =20 +/* + * Keep in sync with rust/kernel/sync/lock/spinlock.rs + */ + context_lock_struct(raw_spinlock) { arch_spinlock_t raw_lock; #ifdef CONFIG_DEBUG_SPINLOCK diff --git a/rust/bindings/lib.rs b/rust/bindings/lib.rs index 854e7c471434..adde41e41edc 100644 --- a/rust/bindings/lib.rs +++ b/rust/bindings/lib.rs @@ -77,3 +77,27 @@ mod bindings_helper { None } }; + +// Explicitly list architectures where this logic is checked correct. +#[cfg(any( + CONFIG_ARM, + CONFIG_ARM64, + CONFIG_LOONGARCH, + CONFIG_PPC, + CONFIG_RISCV, + CONFIG_S390, + CONFIG_X86, +))] +pub const __ARCH_SPIN_LOCK_UNLOCKED: arch_spinlock_t =3D { + // SAFETY: The `arch_spinlock_t` type can be zeroed. + #[allow(unused_mut)] + let mut lock: arch_spinlock_t =3D unsafe { core::mem::zeroed() }; + + #[cfg(not(CONFIG_SMP))] + #[cfg(CONFIG_DEBUG_SPINLOCK)] + { + lock.slock =3D 1; + } + + lock +}; diff --git a/rust/kernel/sync/lock/spinlock.rs b/rust/kernel/sync/lock/spin= lock.rs index ef76fa07ca3a..697efa7e04c6 100644 --- a/rust/kernel/sync/lock/spinlock.rs +++ b/rust/kernel/sync/lock/spinlock.rs @@ -4,6 +4,8 @@ //! //! This module allows Rust code to use the kernel's `spinlock_t`. =20 +use kernel::prelude::*; + /// Creates a [`SpinLock`] initialiser with the given name and a newly-cre= ated lock class. /// /// It uses the name if one is given, otherwise it generates one based on = the file name and line @@ -144,3 +146,32 @@ unsafe fn assert_is_held(ptr: *mut Self::State) { unsafe { bindings::spin_assert_is_held(ptr) } } } + +/// Helper for creating a raw unlocked `bindings::raw_spinlock_t`. +/// +/// For use in statics containing raw spinlocks. +#[doc(alias("__SPIN_LOCK_UNLOCKED", "DEFINE_SPINLOCK"))] +#[expect(dead_code)] +pub(crate) const fn raw_spin_lock_unlocked(name: &'static CStr) -> binding= s::raw_spinlock_t { + // Silence unused variable warnings. + #[cfg(not(CONFIG_DEBUG_LOCK_ALLOC))] + let _ =3D name; + + bindings::raw_spinlock_t { + raw_lock: bindings::__ARCH_SPIN_LOCK_UNLOCKED, + + #[cfg(CONFIG_DEBUG_SPINLOCK)] + magic: bindings::SPINLOCK_MAGIC, + #[cfg(CONFIG_DEBUG_SPINLOCK)] + owner_cpu: u32::MAX, + #[cfg(CONFIG_DEBUG_SPINLOCK)] + owner: usize::MAX as *mut c_void, + + #[cfg(CONFIG_DEBUG_LOCK_ALLOC)] + dep_map: kernel::sync::lockdep::raw_lockdep_map( + name, + kernel::sync::lockdep::LD_WAIT_SPIN, + kernel::sync::lockdep::LD_WAIT_INV, + ), + } +} diff --git a/rust/kernel/sync/lockdep.rs b/rust/kernel/sync/lockdep.rs index 784821cc2a39..d9222be0fb29 100644 --- a/rust/kernel/sync/lockdep.rs +++ b/rust/kernel/sync/lockdep.rs @@ -137,3 +137,25 @@ macro_rules! optional_name { $crate::c_str!($name) }; } + +/// Not checked, catch all. +pub const LD_WAIT_INV: u8 =3D bindings::lockdep_wait_type_LD_WAIT_INV as u= 8; +/// Spin loops, `raw_spinlock_t` etc +pub const LD_WAIT_SPIN: u8 =3D bindings::lockdep_wait_type_LD_WAIT_SPIN as= u8; + +/// Helper for declaring a raw `struct lockdep_map` for locks in statics. +/// +/// It's up to the caller to use the returned `struct lockdep_map` correct= ly. +#[cfg(CONFIG_DEBUG_LOCK_ALLOC)] +pub(crate) const fn raw_lockdep_map( + name: &'static CStr, + wait_type_inner: u8, + wait_type_outer: u8, +) -> bindings::lockdep_map { + // SAFETY: All zeros is valid for this type. + let mut map: bindings::lockdep_map =3D unsafe { core::mem::zeroed() }; + map.name =3D kernel::str::as_char_ptr_in_const_context(name); + map.wait_type_inner =3D wait_type_inner; + map.wait_type_outer =3D wait_type_outer; + map +} --=20 2.55.0.229.g6434b31f56-goog From nobody Sat Jul 25 15:51:37 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (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 9CDB541F5F7 for ; Thu, 16 Jul 2026 12:34:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784205294; cv=none; b=F6XLR7gLBqId+boIG4mTNqBYJgxOXWz8ahlZl7h3spbO7tm70ZmtnWPqpU/XWwdS8MewTtOpFy3jiqvC5jRWmmR8HQEWCldaQEG4WxTY8ICjn+wYVG/mB6p/ZNm2EUVTrurWn2mhdQaajGKwoo2CofwHZcc8CUmzdUhIduKWe0k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784205294; c=relaxed/simple; bh=3i3GDjIlwvozhnGmllgMo5tK2nwxQB1v2sugL7c30P4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=BsECW35AJeWvi9k8hfOnVUKd52mSBUIh6NZsJ5aw0h/8lys17Ez7vypRl0oACdLOPRRUQ1NAlIzTK64bGa4u1yv+/NtEsa8/wKKFY17UmNB2l/G2h/B/Qj7A6VIHuV1vVtsPY/FtGVZB8vct/v8p1sxwqdGWifpVqfl1ETBKhp8= 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=rSZV67NK; arc=none smtp.client-ip=209.85.128.74 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="rSZV67NK" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-493ce08a6b4so59871565e9.1 for ; Thu, 16 Jul 2026 05:34:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1784205289; x=1784810089; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=Cqy/U1/ec//K4h0kBammt9qPwKEI8xiFB29un8NNrvk=; b=rSZV67NKtbZIIkhMC874t2d3978DHAKEzkkZUH+Uq3cOVaUzwLztNVmBYNqKZj3i71 IyNDdSODY/nibqDOD3GRtmbRlhISW/ZvsBFVWeJ0BXUeCTZHgUql0azILHOJhp2Sql+/ tBVerQjaVhw3wbyNyUpjEqPREpIzPvrk+Yh1kmDr2OZAoc5gMp1GtM7whUe+THMfWSlE 6K45LkogkPRnRBrqWCKmrD3fD0A/buSzLLec+mzKugMNpa34WDzLAsKZrVD+CkcUqIlK HX1NWXC4eWdDr1uy5H3kfm4A0citsNY/MKBJRnt6HGZ9maXm8x6uWIIqYtTndOHUoscp MW1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784205289; x=1784810089; h=content-type: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:content-type; bh=Cqy/U1/ec//K4h0kBammt9qPwKEI8xiFB29un8NNrvk=; b=KxJj9iU18qOqbw6RpEg/fMvKks7W6j4oBdSpGPodyHUPowcfz7dL3K1q8R3S5VmiDi kvex3PCra4El79V9HZiFuuWEKzYpIWGsSV7nh5WwVtcVJbEZ+SHhbNK91aCljcl5Ls3E qHrPwQjGh93l9nWy37VVLeakZVErRhQ3O4g/Av6QwqcLi/4TJ6OvFuOlmqncO6kKzjO9 KcItuB8Yf7j0XPDl1Nc69oMzax6hbkOLqRuqe7NW9SA92kOpgy1wpozVVBzUZHh9WuvU lAu8n40WPIlrrqa8/GtOQbJSLNyj6JRA/120Jor+5T7q3jusznGuu6mg7Fuekgh6N43/ hrow== X-Forwarded-Encrypted: i=1; AHgh+RqyKazDPOZShYcyCCEXO/6H6yl7Mc7Mhw4UGt1+9SY5tMgSfjLZuV1MrDIiZlxxd0aJX3KAv+Chz4fc9oA=@vger.kernel.org X-Gm-Message-State: AOJu0YzapTySDVz7vA1EpFI12ZMmm14w5uQxKt5myIV6WYVUN8ULYUYm jqY69AzlFx5e8fSFRqsUiLQYNmL5XGnesLGuqrQopRhJZZU/yC6ORBiHQ3dHYeUVJcM7vSvAELr graOht+Wh6+jgD9cOnQ== X-Received: from wmep2.prod.google.com ([2002:a05:600c:4302:b0:489:1b01:386f]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3514:b0:493:c2cc:aecb with SMTP id 5b1f17b1804b1-49538cc87b2mr108722365e9.38.1784205288635; Thu, 16 Jul 2026 05:34:48 -0700 (PDT) Date: Thu, 16 Jul 2026 12:34:27 +0000 In-Reply-To: <20260716-pr-ratelimited-v2-0-31c27a4543d2@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260716-pr-ratelimited-v2-0-31c27a4543d2@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=10696; i=aliceryhl@google.com; h=from:subject:message-id; bh=3i3GDjIlwvozhnGmllgMo5tK2nwxQB1v2sugL7c30P4=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBqWM/i0aMkkwr8jJK6RXR5ijh+strMt/nx/VQQA hAJI1cgowWJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCaljP4gAKCRAEWL7uWMY5 RmvRD/9goH8Dtjs+5f/EJvJO14oTTVI9FhiOXxIXLsWwtEMMpXjN+133Er+4pnrIDiZzHP2LuoA YEqIzP18UmpsjgivoUfjlCQoUEUhy0PPbD9wlx4FD42Ae5CvLpOoc+xWBHwyTuC68kWEItiBbuU 6Yk17iTk8KE+pywMbiyZs2C/b+KlUIRqHFWSgtla0fom0aBgeHz1YeMZNOUhdwz0pFjE62HHJHA gwRji5npr4aOvq7iGSZPb6JHvn3BjmdkU6GqsvuIds3jl99z4JxqRO0yvkZM9Abemm3gFs6m23H KMLBsSXfPKnH4nSQR2TCICWHLiVLTPK/Ra5A4mlHcIfgKhhtOpdnSI6nlHYrXl3RYx/GUxdAlZx w89PzHDJ2kFblNNyPs5cOakClFZ8D6fl51ooQPW1b/jeEndvaw1ygsJ5qGmWb8sLAYFMTbrk5Is mwxDI+voHmMwPVdyj0eb9MUnbo9jHncHjT5KeSLKkZFnx7uRWlkjxUI6EIfRNBD1uHaZzBwORPA 4/9h/iEGkIVV5nZuIedrs8/v8/PqrR6WiGC8s0TFDwpdxUDYlvFONSjlL4y5oTyEN5wMc5dzWow LSsmyCQA4kg0O4ljX8DSV07iqzMoNNy8aGbJVMZ3476fLUqx3JuGPrUePFPaLHZKYeD53yMtWGA D/5Szpi0OLWKNmQ== X-Mailer: b4 0.14.3 Message-ID: <20260716-pr-ratelimited-v2-3-31c27a4543d2@google.com> Subject: [PATCH v2 3/5] rust: add pr_*_ratelimit! macros for printing From: Alice Ryhl To: Greg Kroah-Hartman , Carlos Llamas , Boqun Feng , Gary Guo Cc: "=?utf-8?q?Onur_=C3=96zkan?=" , Andreas Hindborg , Benno Lossin , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Daniel Almeida , Danilo Krummrich , Ingo Molnar , Lyude Paul , Miguel Ojeda , Peter Zijlstra , Trevor Gross , Waiman Long , Will Deacon , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, Alice Ryhl , Alvin Sun Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Printing can be very expensive if it occurs often, so printing that can be triggered by userspace should be rate limited. For this purpose, add a Rust wrapper around `struct ratelimit_state` and use it in the new macros. Tested-by: Alvin Sun Reviewed-by: Carlos Llamas Link: https://github.com/Rust-for-Linux/linux/issues/122 Signed-off-by: Alice Ryhl --- rust/helpers/helpers.c | 1 + rust/helpers/ratelimit.c | 14 +++ rust/kernel/lib.rs | 1 + rust/kernel/prelude.rs | 8 ++ rust/kernel/ratelimit.rs | 215 ++++++++++++++++++++++++++++++++++= ++++ rust/kernel/sync/lock/spinlock.rs | 1 - 6 files changed, 239 insertions(+), 1 deletion(-) diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c index 1d4ee51f576b..cbecf152f647 100644 --- a/rust/helpers/helpers.c +++ b/rust/helpers/helpers.c @@ -82,6 +82,7 @@ #include "processor.c" #include "property.c" #include "pwm.c" +#include "ratelimit.c" #include "rbtree.c" #include "rcu.c" #include "refcount.c" diff --git a/rust/helpers/ratelimit.c b/rust/helpers/ratelimit.c new file mode 100644 index 000000000000..e5052f568b81 --- /dev/null +++ b/rust/helpers/ratelimit.c @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include + +__rust_helper void rust_helper_ratelimit_state_init(struct ratelimit_state= *rs, + int interval, int burst) +{ + ratelimit_state_init(rs, interval, burst); +} + +__rust_helper void rust_helper_ratelimit_state_exit(struct ratelimit_state= *rs) +{ + ratelimit_state_exit(rs); +} diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 9512af7156df..f53dd564aef5 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -112,6 +112,7 @@ pub mod ptr; #[cfg(CONFIG_RUST_PWM_ABSTRACTIONS)] pub mod pwm; +pub mod ratelimit; pub mod rbtree; pub mod regulator; pub mod revocable; diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs index ca396f1f78a6..bcaa232205be 100644 --- a/rust/kernel/prelude.rs +++ b/rust/kernel/prelude.rs @@ -107,13 +107,21 @@ }, init::InPlaceInit, pr_alert, + pr_alert_ratelimited, pr_crit, + pr_crit_ratelimited, pr_debug, + pr_debug_ratelimited, pr_emerg, + pr_emerg_ratelimited, pr_err, + pr_err_ratelimited, pr_info, + pr_info_ratelimited, pr_notice, + pr_notice_ratelimited, pr_warn, + pr_warn_ratelimited, str::CStrExt as _, try_init, try_pin_init, diff --git a/rust/kernel/ratelimit.rs b/rust/kernel/ratelimit.rs new file mode 100644 index 000000000000..426992e452a2 --- /dev/null +++ b/rust/kernel/ratelimit.rs @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Rate limiting support. +//! +//! C header: [`include/linux/ratelimit.h`](srctree/include/linux/ratelimi= t.h) + +use crate::{ + bindings, + prelude::*, + types::Opaque, // +}; + +/// Defines a `static` containing a [`Ratelimit`]. +#[macro_export] +macro_rules! ratelimit_state_init { + ($name:ident, $interval:expr, $burst:expr $(,)?) =3D> { + static $name: $crate::ratelimit::Ratelimit =3D { + let name =3D $crate::c_str!(::core::stringify!($name)); + let interval =3D $interval; + let burst =3D $burst; + // SAFETY: This will be stored in static memory. + unsafe { $crate::ratelimit::Ratelimit::new_static(name, interv= al, burst) } + }; + }; +} +pub use ratelimit_state_init; + +/// Rate limiter state. +/// +/// # Invariants +/// +/// The `inner` field contains an initialized `struct ratelimit_state`. +#[pin_data(PinnedDrop)] +#[repr(transparent)] +pub struct Ratelimit { + #[pin] + inner: Opaque, +} + +// SAFETY: `Ratelimit` is safe to be sent to any task. +unsafe impl Send for Ratelimit {} + +// SAFETY: `Ratelimit` is safe to be accessed concurrently as it is protec= ted by an internal +// spinlock. +unsafe impl Sync for Ratelimit {} + +impl Ratelimit { + /// Constructs a [`Ratelimit`] with the specified configuration. + /// + /// If `interval` is zero, then no rate limit is applied. + #[inline] + pub fn new(interval: i32, burst: i32) -> impl PinInit { + // INVARIANT: This creates a `Ratelimit` containing an initialized= `struct ratelimit_state` + pin_init!(Self { + inner <- Opaque::ffi_init(|slot: *mut bindings::ratelimit_stat= e| { + // SAFETY: `slot` is a valid pointer to an uninitialized `= struct ratelimit_state`. + // The memory is pinned so it remains valid until `ratelim= it_state_exit` is called. + unsafe { bindings::ratelimit_state_init(slot, interval, bu= rst) }; + }), + }) + } + + /// Constructs a [`Ratelimit`] with the default configuration. + #[inline] + pub fn new_default() -> impl PinInit { + Ratelimit::new(Ratelimit::DEFAULT_INTERVAL, Ratelimit::DEFAULT_BUR= ST) + } + + /// Constructs a [`Ratelimit`] with the specified configuration. + /// + /// The name will be used for the lockdep name of the internal spinloc= k. See [`Self::new`] for + /// the meaning of `interval` and `burst`. + /// + /// # Safety + /// + /// The resulting value must be stored in static memory. + pub const unsafe fn new_static(name: &'static CStr, interval: i32, bur= st: i32) -> Self { + Self { + inner: Opaque::new(bindings::ratelimit_state { + lock: kernel::sync::lock::spinlock::raw_spin_lock_unlocked= (name), + interval, + burst, + ..pin_init::zeroed() + }), + } + } + + /// The default interval used for rate limiting. + pub const DEFAULT_INTERVAL: i32 =3D bindings::DEFAULT_RATELIMIT_INTERV= AL as i32; + + /// The default burst size. + pub const DEFAULT_BURST: i32 =3D bindings::DEFAULT_RATELIMIT_BURST as = i32; + + /// Check if an action should be rate-limited. + /// + /// Returns [`true`] if the action is allowed, and [`false`] if it sho= uld be suppressed. + #[inline] + pub fn ratelimit(&self) -> bool { + // We don't set `RATELIMIT_MSG_ON_RELEASE`, so the function name p= arameter is not used. + // + // SAFETY: `self.inner.get()` is a valid pointer to a `struct rate= limit_state`. + // The lifetime of `func` ensures the pointer remains valid for th= e duration of the call. + // The C function `___ratelimit` handles its own internal locking,= so it is safe to call + // concurrently. + unsafe { bindings::___ratelimit(self.inner.get(), c"Rust".as_char_= ptr()) !=3D 0 } + } +} + +#[pinned_drop] +impl PinnedDrop for Ratelimit { + #[inline] + fn drop(self: Pin<&mut Self>) { + // SAFETY: By the type invariants, this struct contains an initial= ized `struct + // ratelimit_state`. + unsafe { bindings::ratelimit_state_exit(self.inner.get()) }; + } +} + +/// Helper macro to implement ratelimited printing. +#[macro_export] +#[doc(hidden)] +macro_rules! print_ratelimited { + ($print_macro:ident, $($arg:tt)*) =3D> {{ + $crate::ratelimit::ratelimit_state_init!( + _rs, + $crate::ratelimit::Ratelimit::DEFAULT_INTERVAL, + $crate::ratelimit::Ratelimit::DEFAULT_BURST, + ); + if $crate::ratelimit::Ratelimit::ratelimit(&_rs) { + $crate::$print_macro!($($arg)*); + } + }}; +} + +/// Prints an emergency-level message (level 0) if allowed by a rate limit= er. +/// +/// [`Ratelimit`]: $crate::ratelimit::Ratelimit +#[macro_export] +macro_rules! pr_emerg_ratelimited ( + ($($arg:tt)*) =3D> ( + $crate::print_ratelimited!(pr_emerg, $($arg)*) + ) +); + +/// Prints an alert-level message (level 1) if allowed by a rate limiter. +/// +/// [`Ratelimit`]: $crate::ratelimit::Ratelimit +#[macro_export] +macro_rules! pr_alert_ratelimited ( + ($($arg:tt)*) =3D> ( + $crate::print_ratelimited!(pr_alert, $($arg)*) + ) +); + +/// Prints a critical-level message (level 2) if allowed by a rate limiter. +/// +/// [`Ratelimit`]: $crate::ratelimit::Ratelimit +#[macro_export] +macro_rules! pr_crit_ratelimited ( + ($($arg:tt)*) =3D> ( + $crate::print_ratelimited!(pr_crit, $($arg)*) + ) +); + +/// Prints an error-level message (level 3) if allowed by a rate limiter. +/// +/// [`Ratelimit`]: $crate::ratelimit::Ratelimit +#[macro_export] +macro_rules! pr_err_ratelimited ( + ($($arg:tt)*) =3D> ( + $crate::print_ratelimited!(pr_err, $($arg)*) + ) +); + +/// Prints a warning-level message (level 4) if allowed by a rate limiter. +/// +/// [`Ratelimit`]: $crate::ratelimit::Ratelimit +#[macro_export] +macro_rules! pr_warn_ratelimited ( + ($($arg:tt)*) =3D> ( + $crate::print_ratelimited!(pr_warn, $($arg)*) + ) +); + +/// Prints a notice-level message (level 5) if allowed by a rate limiter. +/// +/// [`Ratelimit`]: $crate::ratelimit::Ratelimit +#[macro_export] +macro_rules! pr_notice_ratelimited ( + ($($arg:tt)*) =3D> ( + $crate::print_ratelimited!(pr_notice, $($arg)*) + ) +); + +/// Prints an info-level message (level 6) if allowed by a rate limiter. +/// +/// [`Ratelimit`]: $crate::ratelimit::Ratelimit +#[macro_export] +macro_rules! pr_info_ratelimited ( + ($($arg:tt)*) =3D> ( + $crate::print_ratelimited!(pr_info, $($arg)*) + ) +); + +/// Prints a debug-level message (level 7) if allowed by a rate limiter. +/// +/// [`Ratelimit`]: $crate::ratelimit::Ratelimit +#[macro_export] +macro_rules! pr_debug_ratelimited ( + ($($arg:tt)*) =3D> ( + if cfg!(debug_assertions) { + $crate::print_ratelimited!(pr_debug, $($arg)*) + } + ) +); diff --git a/rust/kernel/sync/lock/spinlock.rs b/rust/kernel/sync/lock/spin= lock.rs index 697efa7e04c6..b9869f958ce0 100644 --- a/rust/kernel/sync/lock/spinlock.rs +++ b/rust/kernel/sync/lock/spinlock.rs @@ -151,7 +151,6 @@ unsafe fn assert_is_held(ptr: *mut Self::State) { /// /// For use in statics containing raw spinlocks. #[doc(alias("__SPIN_LOCK_UNLOCKED", "DEFINE_SPINLOCK"))] -#[expect(dead_code)] pub(crate) const fn raw_spin_lock_unlocked(name: &'static CStr) -> binding= s::raw_spinlock_t { // Silence unused variable warnings. #[cfg(not(CONFIG_DEBUG_LOCK_ALLOC))] --=20 2.55.0.229.g6434b31f56-goog From nobody Sat Jul 25 15:51:37 2026 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 5CE0A41F7F0 for ; Thu, 16 Jul 2026 12:34:53 +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=1784205295; cv=none; b=fyHvrDPAdt6Bdwr2XZ6iEz7Q7Y+eZTeJBdzv+6JhPFFctZ4xZGBaf/4xc77Q8MNGQxkLVtRsatR81qCKBvXwWmA2LZixLz0qc3O9k96PjFh1BcwhfDRYnhP3Mp95QSHjo63dVTzexTuktEOPlzP3Sg6Kh6dCXrVz5U+BrMs+yr4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784205295; c=relaxed/simple; bh=sPWTdk5viFFF5Xgw6GPE35F7F4u3/XG+ZSS6RXW19Rs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=NZSnmv/8jvTULPmr7DD+WgnbOZ859QQTjzEYrm7xqoAC73heENucZaZpo/fGpifcjhl7atSEgfpmnROYm3gUMnq9tHUVPcKVTk0iusjj8oc0E8E2VsUyIbzaAhFMwmdSxvTZw3DV+Bb+KicQd2bnmfnk9+IrU+bfv5pjI5KjpME= 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=VhqrqgxI; 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="VhqrqgxI" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-47f24a50f0cso5691638f8f.3 for ; Thu, 16 Jul 2026 05:34:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1784205291; x=1784810091; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=isRQFGzDT8CkPr6fpN8oIVeTrpIvrNhUjiJ8li5WdOo=; b=VhqrqgxIMzmAoU1L4QKyI34kZHqT2YnW0r1hfoxH9zxNbik50Q3OiVfb26jEQPVQJ2 VnSZXXvJv72wlDRoOB11FYjfURGySYCyT+iPPrA0h0S6oF0B/F3IS8nAVBxDVLwWgZZQ FKfpBxcum1FXACl49565n+IJxr528h5AvkNh7ofvOY3qFzxNlaHZ2gOuPgR68NLpoMi7 gBnU7kA+F3l2Kyp6Tuuh5k9chaJzlcnCIzd9WxkeTiDM+B2HnAxXVjNg9LHwDwoANIrj 7f6I+/QS2u+Wq+59Rx3m02U9k8Hdm0l7w0strDYbDYtYleMXsVcYsTwAn2KdopAgLHly Yb9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784205291; x=1784810091; h=content-type: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:content-type; bh=isRQFGzDT8CkPr6fpN8oIVeTrpIvrNhUjiJ8li5WdOo=; b=EdJdPcEP/kP3aXkXoUdiNtzUD6WZD4XsjqXa1noAfoMiwEx5I4PDbmtggu3/uGPOyd JOfiioaOVpP/Y56ydJcczinfLMMIcXvsVzfGzXg5+0RlGQ5G6nH8jRVpici5tUiSFT5L HqSqik4bya3JpTREL8IbWRydhjEhb4kT6/4f2P73UYict84u/OaWjfU/9WEkXipqCsO/ OA812KzTvAtJy9Gd2bV5YBQzeUcX5qgiiobRTk+N/XR6oWnp2tnIqLN6LKnc+TW9WWII t5ZJHio9vH4m1jvZxlAVhP40CklZhGsAoDUVPEwzchpON44bh7bEaq+FxcTEjbUQBFy5 lWsg== X-Forwarded-Encrypted: i=1; AHgh+Rri0p/MWRU1JHCLWJznEZBVrWp8TlbgfpbSqmT1Fn/I4oXx3JGXxB0zqM80dzmu3v0hUbRFFCGP/sH72yA=@vger.kernel.org X-Gm-Message-State: AOJu0YzzP3HAZw9yg1fXfs/ttVjzF/9mTya/u7Zz08Pz/tY4E1iUhGbV icMpDy1IODDr6f9SdwSfV40NfinMjbEDkCPN+zIK6W/ERK5Lxs+EJJdj6kX2AA+4BY0b2/7qSS4 eqlQTpwx4/LbpqO3/RA== X-Received: from wrqk14.prod.google.com ([2002:a5d:428e:0:b0:47f:4fe5:ee23]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a5d:588f:0:b0:472:edc7:b4c9 with SMTP id ffacd0b85a97d-47f4fd11350mr8667275f8f.38.1784205290405; Thu, 16 Jul 2026 05:34:50 -0700 (PDT) Date: Thu, 16 Jul 2026 12:34:28 +0000 In-Reply-To: <20260716-pr-ratelimited-v2-0-31c27a4543d2@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260716-pr-ratelimited-v2-0-31c27a4543d2@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=8538; i=aliceryhl@google.com; h=from:subject:message-id; bh=sPWTdk5viFFF5Xgw6GPE35F7F4u3/XG+ZSS6RXW19Rs=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBqWM/iwcDPRFZ5+rqpToLC8ZRknqMrFBsmrdSb0 nQRQz5OasWJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCaljP4gAKCRAEWL7uWMY5 RvTHEACErEEabcQ3ppkojTof8Pwo29bb8aq8peKoSdlj8Ts5YeTgAfivsf3YPBgvHYZsuXSfWt7 VlJ0XLT6ikF4OHpv43zrJiW/Yh7miVoyjRFRvw6yGlsO0tE7Ibzl1MMzNSMMNTvS3AxTgKwGvWl I2L9vRM12rd9IjOd2ynHuRDH0S2XmQXugF3UDHd1Anmx5vLd6PGxk8X5FHYdt79yLwe2Sg2MuPo 0CysFGcXnh58UniwcfG5VmMZZ2gCm1x+eoHccYe8viM+SqnNsRNYCSp7Mar8doioZaDP5sDGg7I yAPIwkPsWRpPChVA/EQ9kkx5zVvuyvGeepiWMNgcsDhm+cOuszX1CsosBDyTGfWmNYh4RCYVce8 QZtG+SBvoknj1Wdl/cJT0LPVdxQsiOUrV54GTxFWBWfm0YiMSTUMdE3MqM5YdaBVrFEacAxFz1N Gvq/8FpnAJHFNdG8W3IV0LFBUKa4sBGRJAAXlF9dvQNkepfezwSyO9eX7TnGgtzX+JhjCcRcA+r rhmcBjy4dUP7AV55C12RMnpZcqT6NwqZx1BMutv6YiW+VoxZo8Uo9sRtL6CuWa/XGbPQuBMZqRN Yd0S93pGQOMAem5rvDQN3GR0tJiplcoJrawc1AGwIjujaecDXb+1J7Bk+ppctReu33TUTiCq7ec 5Uh8UNM2usMxuJQ== X-Mailer: b4 0.14.3 Message-ID: <20260716-pr-ratelimited-v2-4-31c27a4543d2@google.com> Subject: [PATCH v2 4/5] rust_binder: consolidate transaction failure prints From: Alice Ryhl To: Greg Kroah-Hartman , Carlos Llamas , Boqun Feng , Gary Guo Cc: "=?utf-8?q?Onur_=C3=96zkan?=" , Andreas Hindborg , Benno Lossin , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Daniel Almeida , Danilo Krummrich , Ingo Molnar , Lyude Paul , Miguel Ojeda , Peter Zijlstra , Trevor Gross , Waiman Long , Will Deacon , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, Alice Ryhl Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable When a transaction fails, it currently hits multiple print statements meaning that a single failure can result in several lines in the kernel log. This is unnecessary, so consolidate them into one print used for all transaction failures. Signed-off-by: Alice Ryhl --- drivers/android/binder/error.rs | 4 --- drivers/android/binder/thread.rs | 55 ++++++++++++++-----------------= ---- drivers/android/binder/transaction.rs | 20 ++----------- rust/kernel/error.rs | 2 +- 4 files changed, 26 insertions(+), 55 deletions(-) diff --git a/drivers/android/binder/error.rs b/drivers/android/binder/error= .rs index 1296072c35d9..aed1c747640b 100644 --- a/drivers/android/binder/error.rs +++ b/drivers/android/binder/error.rs @@ -37,10 +37,6 @@ pub(crate) fn new_frozen_oneway() -> Self { source: None, } } - - pub(crate) fn is_dead(&self) -> bool { - self.reply =3D=3D BR_DEAD_REPLY - } } =20 /// Convert an errno into a `BinderError` and store the errno used to cons= truct it. The errno diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thre= ad.rs index a7a190e1b000..bcdf0adfaaff 100644 --- a/drivers/android/binder/thread.rs +++ b/drivers/android/binder/thread.rs @@ -26,7 +26,7 @@ use crate::{ allocation::{Allocation, AllocationView, BinderObject, BinderObjectRef= , NewAllocation}, defs::*, - error::BinderResult, + error::{BinderError, BinderResult}, process::{GetWorkOrRegister, Process}, ptr_align, stats::GLOBAL_STATS, @@ -1007,17 +1007,7 @@ pub(crate) fn copy_transaction_data( size_of::(), ); let secctx_off =3D aligned_data_size + offsets_size + buffers_size; - let mut alloc =3D match to_process.buffer_alloc(debug_id, len, inf= o) { - Ok(alloc) =3D> alloc, - Err(err) =3D> { - pr_warn!( - "Failed to allocate buffer. len:{}, is_oneway:{}", - len, - info.is_oneway(), - ); - return Err(err); - } - }; + let mut alloc =3D to_process.buffer_alloc(debug_id, len, info)?; =20 let mut buffer_reader =3D UserSlice::new(info.data_ptr, data_size)= .reader(); let mut end_of_previous_object =3D 0; @@ -1267,6 +1257,9 @@ fn transaction(self: &Arc, cmd: u32, reader: &m= ut UserSliceReader) -> Resu self.transaction_inner(&mut info) }; =20 + // This runs when return work is passed to the caller. This is not + // always the same as the transaction failing, as reply errors are + // delivered to the remote process. if let Err(err) =3D ret { self.push_return_work(err.reply); if err.reply !=3D BR_TRANSACTION_COMPLETE { @@ -1274,13 +1267,21 @@ fn transaction(self: &Arc, cmd: u32, reader: = &mut UserSliceReader) -> Resu if let Some(source) =3D &err.source { info.errno =3D source.to_errno(); =20 - { - let mut inner =3D self.inner.lock(); - inner.extended_error =3D - ExtendedError::new(info.debug_id as u32, err.r= eply, source.to_errno()); - } + self.inner.lock().extended_error =3D + ExtendedError::new(info.debug_id as u32, err.reply= , source.to_errno()); } + } + } =20 + if info.oneway_spam_suspect { + // If this is both a oneway spam suspect and a failure, we rep= ort it twice. This is + // useful in case the transaction failed with BR_TRANSACTION_P= ENDING_FROZEN. + info.report_netlink(BR_ONEWAY_SPAM_SUSPECT, &self.process.ctx); + } + // This runs when the transaction failed. + if info.reply !=3D 0 { + info.report_netlink(info.reply, &self.process.ctx); + if info.errno !=3D 0 { binder_debug!( FailedTransaction, "transaction {} to {}:{} failed {:?}, code {} size {}-= {}", @@ -1293,7 +1294,10 @@ fn transaction(self: &Arc, cmd: u32, reader: &= mut UserSliceReader) -> Resu }, info.to_pid, info.to_tid, - err, + BinderError { + reply: info.reply, + source: Error::try_from_errno(info.errno), + }, info.code, info.data_size, info.offsets_size @@ -1301,15 +1305,6 @@ fn transaction(self: &Arc, cmd: u32, reader: &= mut UserSliceReader) -> Resu } } =20 - if info.oneway_spam_suspect { - // If this is both a oneway spam suspect and a failure, we rep= ort it twice. This is - // useful in case the transaction failed with BR_TRANSACTION_P= ENDING_FROZEN. - info.report_netlink(BR_ONEWAY_SPAM_SUSPECT, &self.process.ctx); - } - if info.reply !=3D 0 { - info.report_netlink(info.reply, &self.process.ctx); - } - Ok(()) } =20 @@ -1390,12 +1385,6 @@ fn reply_inner(self: &Arc, info: &mut Transact= ionInfo) -> BinderResult { // At this point we only return `BR_TRANSACTION_COMPLETE` to t= he caller, and we must let // the sender know that the transaction has completed (with an= error in this case). =20 - pr_warn!( - "{}:{} reply to {} failed: {err:?}", - info.from_pid, - info.from_tid, - info.to_pid - ); let param =3D err.source.as_ref().map_or(0, |e| e.to_errno()); let ee =3D ExtendedError::new(info.debug_id as u32, err.reply,= param); orig.from diff --git a/drivers/android/binder/transaction.rs b/drivers/android/binder= /transaction.rs index 96d45c6816fe..19ad37b0b294 100644 --- a/drivers/android/binder/transaction.rs +++ b/drivers/android/binder/transaction.rs @@ -139,21 +139,13 @@ pub(crate) fn new( let txn_security_ctx =3D node_ref.node.flags & FLAT_BINDER_FLAG_TX= N_SECURITY_CTX !=3D 0; let mut txn_security_ctx_off =3D if txn_security_ctx { Some(0) } e= lse { None }; let to =3D node_ref.node.owner.clone(); - let mut alloc =3D match from.copy_transaction_data( + let mut alloc =3D from.copy_transaction_data( to.clone(), info, info.debug_id, allow_fds, txn_security_ctx_off.as_mut(), - ) { - Ok(alloc) =3D> alloc, - Err(err) =3D> { - if !err.is_dead() { - pr_warn!("Failure in copy_transaction_data: {:?}", err= ); - } - return Err(err); - } - }; + )?; if info.is_oneway() { if from_parent.is_some() { pr_warn!("Oneway transaction should not be in a transactio= n stack."); @@ -194,13 +186,7 @@ pub(crate) fn new_reply( allow_fds: bool, ) -> BinderResult> { let mut alloc =3D - match from.copy_transaction_data(to.clone(), info, info.debug_= id, allow_fds, None) { - Ok(alloc) =3D> alloc, - Err(err) =3D> { - pr_warn!("Failure in copy_transaction_data: {:?}", err= ); - return Err(err); - } - }; + from.copy_transaction_data(to.clone(), info, info.debug_id, al= low_fds, None)?; if info.flags & TF_CLEAR_BUF !=3D 0 { alloc.set_info_clear_on_drop(); } diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs index a56ba6309594..380cd3f7276b 100644 --- a/rust/kernel/error.rs +++ b/rust/kernel/error.rs @@ -135,7 +135,7 @@ pub fn from_errno(errno: crate::ffi::c_int) -> Error { /// Creates an [`Error`] from a kernel error code. /// /// Returns [`None`] if `errno` is out-of-range. - const fn try_from_errno(errno: crate::ffi::c_int) -> Option { + pub const fn try_from_errno(errno: crate::ffi::c_int) -> Option= { if errno < -(bindings::MAX_ERRNO as i32) || errno >=3D 0 { return None; } --=20 2.55.0.229.g6434b31f56-goog From nobody Sat Jul 25 15:51:37 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (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 376C1420496 for ; Thu, 16 Jul 2026 12:34:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784205297; cv=none; b=lM05rK3WJCie6U6qwuIm7v9rD3l2+VgxY691lkggrNxF9iYY0qtHowSPcLlfobvmRFlMir27a3WLacWsJnmwhq/RXRPzVvAUj4zdMTmovtt9QlzqvHajWd4ePqVxH3A39LtRFXhhswBYniUJqYW7xrNYMSlvu5BsIwjcgsyqW6s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784205297; c=relaxed/simple; bh=gOZzMQXUm49K1zkiCV6cQcshoBw9zQOkaGum7c57ims=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=TbqV/uHSJ5AcBcXMyhoiz5J5gt0rQwlhyDYM3mizwCuk71C0WluAvrYNrcudCUMYPVC0t5QBnE+vL/lB2ZytPSoFxghIjv3rFzbphcUFi5wiHs+sZ2zFa+7/U7YeEruWv646ZyIGNfIdXSYbW3bpWI9+NGqG90b3ovj3WUVJb0Q= 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=cRShq+Bd; arc=none smtp.client-ip=209.85.128.74 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="cRShq+Bd" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-493ce08a6b4so59872685e9.1 for ; Thu, 16 Jul 2026 05:34:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1784205292; x=1784810092; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=ez9u7FHcyrWFxwgzWCw/hykgM5JZmopGs7v+M7ddZh0=; b=cRShq+BdkB38ANO93uxZ9Nd7LT4roPo6e2oRdLrmZrH3NGZ9NFDV6tVXvFW1Nyc3Pi +cNiZtHNMPFUV5L0opSSx5WfnlD8UXuXR9n7nvUnNPVEbps9pO+u/yAHijpXIsya9h/X mEu1NKvP7pniDrniISoIfmPTFqPfca0cginmflIrvZSA5qAjYtoYE/lcbpVWdgrSspd0 XGxlx8tFZ6g2eNWKjcXZNCYuwj/mHHE+IJgjUen/iS4n31DqQK62FVC0xkndfcRglnJ5 OO/psI6tvFBcgC5BMXLD1Fc/mokbEvJs4oQrzccnP9Md23MAGQXAxc0iv+oI5Vn7NTDw heNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784205292; x=1784810092; h=content-type: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:content-type; bh=ez9u7FHcyrWFxwgzWCw/hykgM5JZmopGs7v+M7ddZh0=; b=CEJBWDu1puCiD6U3i4oUYuvfzd5QKoT8oWfi4kSvUC/4GnjWhRuVAS4F26aMvj3BMK agQdRy739aoPCwjokpJgAKmwRAq/iXhh/9rfUisvk5hU5kNG9zOyLkSmddkxwT3bqW0n /QZFgJ3D7xgER6yce+rrPTDxY/u/L52+HqRj2kmq4iEUbRr/M7iBYcz66DnpdfIh5roF pE9W0qklsnQmpclW4jXURRudE4U8KnThKsEFSJ2rY3XkPciYVaePJp7mQnH131VFC5sb Myzz+tyK6h6QlQobjkWKVTow3zWwI/OmPOCi1AY7cQbQy9yLuN6mCXQ5Jz2bAJDad2VA PF6g== X-Forwarded-Encrypted: i=1; AHgh+RoAycowmDg+2fPac0k/MxXjHj2GFZg+ccf0zcX2PFd3FyBiCVoNQYyzd43qEmAgFU1+bfiheOy4+qikx3s=@vger.kernel.org X-Gm-Message-State: AOJu0YwODeGpYKcLobk7k0Qys+tqvJJ1zplMYkwLMMPRAsKs5oi8hL5N Oz4za2k9JiiVNzHrYWfeLMraBUunJz/Srf+524H7+fa3LhqLOQ4hoVMa71qt/rsYkZxAAMdUBCV QF3dZ+lhU2Ip24VTA7g== X-Received: from wmbhb19.prod.google.com ([2002:a05:600c:8693:b0:493:b2c0:5a0d]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:6207:b0:493:e504:cbef with SMTP id 5b1f17b1804b1-495389731b5mr122208845e9.0.1784205292019; Thu, 16 Jul 2026 05:34:52 -0700 (PDT) Date: Thu, 16 Jul 2026 12:34:29 +0000 In-Reply-To: <20260716-pr-ratelimited-v2-0-31c27a4543d2@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260716-pr-ratelimited-v2-0-31c27a4543d2@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=22368; i=aliceryhl@google.com; h=from:subject:message-id; bh=gOZzMQXUm49K1zkiCV6cQcshoBw9zQOkaGum7c57ims=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBqWM/isbtV1txqkyn8m4qtLJRr/y/1AeamP8HiQ oUHUx0i16iJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCaljP4gAKCRAEWL7uWMY5 RuQaD/9OVFOzm4Fxc6T+3POcuIYaw5Slkg8BKD4h76L66XxgEcoQsz3y4xwufg4zD/GAywS/3Oy SsbuDuI6Rn+BB3DlI5AL3OscXzV2vAZHdw8wjORKPZSniunfvfJn4dwPDUpeMmffK1Z6o2aaCDq 8bqC8DOt8rg/hwyB06W2Dh/peXnwLMMXQmxtBvi3YkLfRxvbQ0P+RDOPXKSKgl9whi0OEFMPk2S XDE1O64bWqwqomOEpMkRXwYziru7hqCOgOXcp//6FVtnZKT/tD0fbgyTHFBQicWbul1IUgoJZ6w UBCCg45KPwi2ZiQQRBS2tl8YPVY3PB5jEV+vNCQi3Qz8qPj/8oeTp6kr1iYRm0cg/nNvt31kV9B Nx4eEUomDP0GPxg2IhBv4aac9FT0l+3BVXeMj/X0SkcjZVrd1gz9QZNHW1AgzzaQzbCP4LzoLRs 0P0ahBRMVNThB7NEBphFbHLKgVVkuPXx2lXaKFEJPBQxz3dR9gKQyRQ+bo5WPM2yYNAYM8Yn6bE y9YZvTPw5DKh1HVUesFMpMkG3TU69ORbFaZqMvwDy3cX6tdfIwhfeEaEi/s6TFQXFvJFMgrIdg8 JyAN1D6bguwa8kJh9tW+w+yUsfQXZP+gyKEdTbKS2J3kAldk8Bjdq3TylrtO6Z961vtvtc+IIHu wAu86943q73Ubsg== X-Mailer: b4 0.14.3 Message-ID: <20260716-pr-ratelimited-v2-5-31c27a4543d2@google.com> Subject: [PATCH v2 5/5] rust_binder: use pr_*_ratelimited! for printing From: Alice Ryhl To: Greg Kroah-Hartman , Carlos Llamas , Boqun Feng , Gary Guo Cc: "=?utf-8?q?Onur_=C3=96zkan?=" , Andreas Hindborg , Benno Lossin , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Daniel Almeida , Danilo Krummrich , Ingo Molnar , Lyude Paul , Miguel Ojeda , Peter Zijlstra , Trevor Gross , Waiman Long , Will Deacon , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, Alice Ryhl Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable To avoid DoS from printing too much, make printing in Binder rate limited. A big portion of these print statements have been updated to use binder_debug!, but some still remain to be converted. For now, just update them to use pr_*_ratelimted! until we get around to converting them to use binder_debug! too. While we're at it, fix the missing newlines at the end of some of those println statements. Acked-by: Carlos Llamas Signed-off-by: Alice Ryhl --- drivers/android/binder/allocation.rs | 4 +-- drivers/android/binder/context.rs | 6 ++--- drivers/android/binder/debug.rs | 4 +-- drivers/android/binder/freeze.rs | 2 +- drivers/android/binder/node.rs | 4 +-- drivers/android/binder/page_range.rs | 12 ++++----- drivers/android/binder/process.rs | 22 ++++++++-------- drivers/android/binder/thread.rs | 48 ++++++++++++++++++++-----------= ---- drivers/android/binder/transaction.rs | 4 +-- 9 files changed, 57 insertions(+), 49 deletions(-) diff --git a/drivers/android/binder/allocation.rs b/drivers/android/binder/= allocation.rs index 165cb797eb1e..8151ba3ea7f4 100644 --- a/drivers/android/binder/allocation.rs +++ b/drivers/android/binder/allocation.rs @@ -261,7 +261,7 @@ fn drop(&mut self) { let view =3D AllocationView::new(self, offsets.start); for i in offsets.step_by(size_of::()) { if view.cleanup_object(i).is_err() { - pr_warn!("Error cleaning up object at offset {}\n"= , i) + pr_warn_ratelimited!("Error cleaning up object at = offset {}\n", i) } } } @@ -286,7 +286,7 @@ fn drop(&mut self) { =20 if info.clear_on_free { if let Err(e) =3D self.fill_zero() { - pr_warn!("Failed to clear data on free: {:?}", e); + pr_warn_ratelimited!("Failed to clear data on free: {:= ?}\n", e); } } } diff --git a/drivers/android/binder/context.rs b/drivers/android/binder/con= text.rs index ddddb66b3557..431d6007a9b1 100644 --- a/drivers/android/binder/context.rs +++ b/drivers/android/binder/context.rs @@ -80,7 +80,7 @@ pub(crate) fn deregister(self: &Arc) { =20 pub(crate) fn register_process(self: &Arc, proc: Arc) -= > Result { if !Arc::ptr_eq(self, &proc.ctx) { - pr_err!("Context::register_process called on the wrong context= ."); + pr_err_ratelimited!("Context::register_process called on the w= rong context.\n"); return Err(EINVAL); } self.manager.lock().all_procs.push(proc, GFP_KERNEL)?; @@ -89,7 +89,7 @@ pub(crate) fn register_process(self: &Arc, proc: Ar= c) -> Result { =20 pub(crate) fn deregister_process(self: &Arc, proc: &Arc= ) { if !Arc::ptr_eq(self, &proc.ctx) { - pr_err!("Context::deregister_process called on the wrong conte= xt."); + pr_err_ratelimited!("Context::deregister_process called on the= wrong context.\n"); return; } let mut manager =3D self.manager.lock(); @@ -110,7 +110,7 @@ pub(crate) fn deregister_process(self: &Arc, proc= : &Arc) { pub(crate) fn set_manager_node(&self, node_ref: NodeRef) -> Result { let mut manager =3D self.manager.lock(); if manager.node.is_some() { - pr_warn!("BINDER_SET_CONTEXT_MGR already set"); + pr_warn_ratelimited!("BINDER_SET_CONTEXT_MGR already set\n"); return Err(EBUSY); } security::binder_set_context_mgr(&node_ref.node.owner.cred)?; diff --git a/drivers/android/binder/debug.rs b/drivers/android/binder/debug= .rs index 824b10c004c3..6d8dcddf4619 100644 --- a/drivers/android/binder/debug.rs +++ b/drivers/android/binder/debug.rs @@ -53,7 +53,7 @@ macro_rules! binder_debug { // Rule to explicitly specify a PID (used in kworkers). (pid=3D$pid:expr, $mask:ident, $($arg:tt)*) =3D> { if $crate::debug::debug_mask_enabled($crate::debug::DebugMask::$ma= sk) { - kernel::pr_info!( + kernel::pr_info_ratelimited!( "{}: {}\n", $pid, kernel::prelude::fmt!($($arg)*) @@ -65,7 +65,7 @@ macro_rules! binder_debug { ($mask:ident, $($arg:tt)*) =3D> { if $crate::debug::debug_mask_enabled($crate::debug::DebugMask::$ma= sk) { let thread =3D kernel::current!(); - kernel::pr_info!( + kernel::pr_info_ratelimited!( "{}:{} {}\n", thread.tgid(), thread.pid(), diff --git a/drivers/android/binder/freeze.rs b/drivers/android/binder/free= ze.rs index 66912b4cb527..7fbde3345ced 100644 --- a/drivers/android/binder/freeze.rs +++ b/drivers/android/binder/freeze.rs @@ -412,7 +412,7 @@ fn find_freeze_recipients(&self) -> Result, Arc)>, Al recipients .push_within_capacity(node_proc_pair) .map_err(|_| { - pr_err!( + pr_err_ratelimited!( "push_within_capacity failed even though we ch= ecked the capacity\n" ); AllocError diff --git a/drivers/android/binder/node.rs b/drivers/android/binder/node.rs index c73cdf82100f..d23f29e51631 100644 --- a/drivers/android/binder/node.rs +++ b/drivers/android/binder/node.rs @@ -401,7 +401,7 @@ pub(crate) fn update_refcount_locked( !is_dead && !state.has_count } else { if state.count < count { - pr_err!("Failure: refcount underflow!"); + pr_err_ratelimited!("Failure: refcount underflow!\n"); return None; } state.count -=3D count; @@ -689,7 +689,7 @@ pub(crate) fn remove_freeze_listener(&self, p: &Process= ) -> KVVec> .freeze_list .retain(|proc| !core::ptr::eq::(&**proc, p)); if len =3D=3D inner.freeze_list.len() { - pr_warn!( + pr_warn_ratelimited!( "Could not remove freeze listener for {}\n", p.pid_in_current_ns() ); diff --git a/drivers/android/binder/page_range.rs b/drivers/android/binder/= page_range.rs index 52ffbf3504e7..c1f4f635c2c0 100644 --- a/drivers/android/binder/page_range.rs +++ b/drivers/android/binder/page_range.rs @@ -212,7 +212,7 @@ unsafe fn set_page(me: *mut PageInfo, page: Page) { =20 // SAFETY: The pointer is valid for writing, so also valid for rea= ding. if unsafe { (*ptr).is_some() } { - pr_err!("set_page called when there is already a page"); + pr_err_ratelimited!("set_page called when there is already a p= age\n"); // SAFETY: We will initialize the page again below. unsafe { ptr::drop_in_place(ptr) }; } @@ -300,11 +300,11 @@ pub(crate) fn register_with_vma(&self, vma: &virt::Vm= aNew) -> Result { let num_pages =3D num_bytes >> PAGE_SHIFT; =20 if !ptr::eq::(&*self.mm, &**vma.mm()) { - pr_debug!("Failed to register with vma: invalid vma->vm_mm"); + pr_debug_ratelimited!("Failed to register with vma: invalid vm= a->vm_mm\n"); return Err(EINVAL); } if num_pages =3D=3D 0 { - pr_debug!("Failed to register with vma: size zero"); + pr_debug_ratelimited!("Failed to register with vma: size zero\= n"); return Err(EINVAL); } =20 @@ -325,7 +325,7 @@ pub(crate) fn register_with_vma(&self, vma: &virt::VmaN= ew) -> Result { =20 let mut inner =3D self.lock.lock(); if inner.size > 0 { - pr_debug!("Failed to register with vma: already registered"); + pr_debug_ratelimited!("Failed to register with vma: already re= gistered\n"); drop(inner); return Err(EBUSY); } @@ -380,7 +380,7 @@ pub(crate) fn use_range(&self, start: usize, end: usize= ) -> Result<()> { match unsafe { self.use_page_slow(i) } { Ok(()) =3D> {} Err(err) =3D> { - pr_warn!("Error in use_page_slow: {:?}", err); + pr_warn_ratelimited!("Error in use_page_slow: {:?}= \n", err); return Err(err); } } @@ -529,7 +529,7 @@ unsafe fn iterate(&self, mut offset: usize, mut size= : usize, mut cb: T) -> Re // duration of this call to `iterate`, so nobody will change t= he page. let page =3D unsafe { PageInfo::get_page(page_info) }; if page.is_none() { - pr_warn!("Page is null!"); + pr_warn_ratelimited!("Page is null!\n"); } let page =3D page.ok_or(EFAULT)?; cb(page, offset, available)?; diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/pro= cess.rs index eb2f08bec655..c405a7ef81db 100644 --- a/drivers/android/binder/process.rs +++ b/drivers/android/binder/process.rs @@ -313,7 +313,7 @@ pub(crate) fn death_delivered(&mut self, death: DArc) { if let Some(death) =3D ListArc::try_from_arc_or_drop(death) { self.delivered_deaths.push_back(death); } else { - pr_warn!("Notification added to `delivered_deaths` twice."); + pr_warn_ratelimited!("Notification added to `delivered_deaths`= twice.\n"); } } =20 @@ -683,7 +683,7 @@ fn get_current_thread(self: ArcBorrow<'_, Self>) -> Res= ult> { let id =3D { let current =3D kernel::current!(); if self.task !=3D current.group_leader() { - pr_err!("get_current_thread was called from the wrong proc= ess."); + pr_err_ratelimited!("get_current_thread was called from th= e wrong process.\n"); return Err(EINVAL); } current.pid() @@ -707,7 +707,7 @@ fn get_current_thread(self: ArcBorrow<'_, Self>) -> Res= ult> { Ok(ta) } rbtree::Entry::Occupied(_entry) =3D> { - pr_err!("Cannot create two threads with the same id."); + pr_err_ratelimited!("Cannot create two threads with the sa= me id.\n"); Err(EINVAL) } } @@ -843,7 +843,9 @@ pub(crate) fn insert_or_update_handle( match refs.by_handle.entry(res.as_u32()) { rbtree::Entry::Vacant(entry) =3D> break (res, entry), rbtree::Entry::Occupied(_) =3D> { - pr_err!("Detected mismatch between handle_is_prese= nt and by_handle"); + pr_err_ratelimited!( + "Detected mismatch between handle_is_present a= nd by_handle\n" + ); res.acquire(); kernel::warn_on!(true); return Err(EINVAL); @@ -1083,7 +1085,7 @@ pub(crate) fn buffer_alloc( ) { Ok(()) =3D> {} Err(err) =3D> { - pr_warn!("use_range failure {:?}", err); + pr_warn_ratelimited!("use_range failure {:?}\n", err); return Err(err.into()); } } @@ -1114,7 +1116,7 @@ pub(crate) fn buffer_raw_free(&self, ptr: usize) { let freed_range =3D match mapping.alloc.reservation_abort(offs= et) { Ok(freed_range) =3D> freed_range, Err(_) =3D> { - pr_warn!( + pr_warn_ratelimited!( "Pointer {:x} failed to free, base =3D {:x}\n", ptr, mapping.address @@ -1136,7 +1138,7 @@ pub(crate) fn buffer_make_freeable(&self, offset: usi= ze, mut data: Option, guard: &mut Guard<'_,= ProcessInner, SpinLockBack // It is an error to hit this branch, and it should not be rea= chable. We try to do // something reasonable when the failure path happens. Most li= kely, the thread in // question will sleep forever. - pr_err!("Same thread registered with `ready_threads` twice."); + pr_err_ratelimited!("Same thread registered with `ready_thread= s` twice.\n"); } Self { thread } } @@ -1816,7 +1818,7 @@ impl Drop for WithNodes<'_> { fn drop(&mut self) { core::mem::swap(&mut self.nodes, &mut self.inner.nodes); if self.nodes.iter().next().is_some() { - pr_err!("nodes array was modified while using lock_with_nodes\= n"); + pr_err_ratelimited!("nodes array was modified while using lock= _with_nodes\n"); } } } diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thre= ad.rs index bcdf0adfaaff..01b851e0b3df 100644 --- a/drivers/android/binder/thread.rs +++ b/drivers/android/binder/thread.rs @@ -160,8 +160,8 @@ fn validate_parent_fixup( let sg_entry =3D match self.sg_entries.get(sg_idx) { Some(sg_entry) =3D> sg_entry, None =3D> { - pr_err!( - "self.ancestors[{}] is {}, but self.sg_entries.len() i= s {}", + pr_err_ratelimited!( + "self.ancestors[{}] is {}, but self.sg_entries.len() i= s {}\n", ancestors_i, sg_idx, self.sg_entries.len() @@ -170,8 +170,8 @@ fn validate_parent_fixup( } }; if sg_entry.fixup_min_offset > parent_offset { - pr_warn!( - "validate_parent_fixup: fixup_min_offset=3D{}, parent_offs= et=3D{}", + pr_warn_ratelimited!( + "validate_parent_fixup: fixup_min_offset=3D{}, parent_offs= et=3D{}\n", sg_entry.fixup_min_offset, parent_offset ); @@ -179,8 +179,8 @@ fn validate_parent_fixup( } let new_min_offset =3D parent_offset.checked_add(length).ok_or(EIN= VAL)?; if new_min_offset > sg_entry.length { - pr_warn!( - "validate_parent_fixup: new_min_offset=3D{}, sg_entry.leng= th=3D{}", + pr_warn_ratelimited!( + "validate_parent_fixup: new_min_offset=3D{}, sg_entry.leng= th=3D{}\n", new_min_offset, sg_entry.length ); @@ -323,7 +323,7 @@ fn push_reply_work(&mut self, code: u32) { work.set_error_code(code); self.push_work(work); } else { - pr_warn!("Thread reply work is already in use."); + pr_warn_ratelimited!("Thread reply work is already in use.\n"); } } =20 @@ -332,7 +332,7 @@ fn push_return_work(&mut self, reply: u32) { work.set_error_code(reply); self.push_work(work); } else { - pr_warn!("Thread return work is already in use."); + pr_warn_ratelimited!("Thread return work is already in use.\n"= ); } } =20 @@ -776,8 +776,8 @@ fn translate_object( let parent_entry =3D match sg_state.sg_entries.get_mut= (info.parent_sg_index) { Some(parent_entry) =3D> parent_entry, None =3D> { - pr_err!( - "validate_parent_fixup returned index out = of bounds for sg.entries" + pr_err_ratelimited!( + "validate_parent_fixup returned index out = of bounds for sg.entries\n" ); return Err(EINVAL.into()); } @@ -823,8 +823,8 @@ fn translate_object( let parent_entry =3D match sg_state.sg_entries.get_mut(inf= o.parent_sg_index) { Some(parent_entry) =3D> parent_entry, None =3D> { - pr_err!( - "validate_parent_fixup returned index out of b= ounds for sg.entries" + pr_err_ratelimited!( + "validate_parent_fixup returned index out of b= ounds for sg.entries\n" ); return Err(EINVAL.into()); } @@ -857,7 +857,9 @@ fn translate_object( .read_all(&mut fda_bytes, GFP_KERNEL)?; =20 if fds_len !=3D fda_bytes.len() { - pr_err!("UserSlice::read_all returned wrong length in = BINDER_TYPE_FDA"); + pr_err_ratelimited!( + "UserSlice::read_all returned wrong length in BIND= ER_TYPE_FDA\n" + ); return Err(EINVAL.into()); } =20 @@ -972,7 +974,11 @@ pub(crate) fn copy_transaction_data( let ctx =3D match security::SecurityCtx::from_secid(secid) { Ok(ctx) =3D> ctx, Err(err) =3D> { - pr_warn!("Failed to get security ctx for id {}: {:?}",= secid, err); + pr_warn_ratelimited!( + "Failed to get security ctx for id {}: {:?}\n", + secid, + err + ); return Err(err.into()); } }; @@ -1195,7 +1201,7 @@ fn top_of_transaction_stack(&self) -> Result>> { let inner =3D self.inner.lock(); if let Some(cur) =3D &inner.current_transaction { if core::ptr::eq(self, cur.from.as_ref()) { - pr_warn!("got new transaction with bad transaction stack"); + pr_warn_ratelimited!("got new transaction with bad transac= tion stack\n"); return Err(EINVAL); } Ok(Some(cur.clone())) @@ -1521,7 +1527,7 @@ fn read(self: &Arc, req: &mut BinderWriteRead, = wait: bool) -> Result { let mut has_noop_placeholder =3D false; if req.read_consumed =3D=3D 0 { if let Err(err) =3D writer.write_code(BR_NOOP) { - pr_warn!("Failure when writing BR_NOOP at beginning of buf= fer."); + pr_warn_ratelimited!("Failure when writing BR_NOOP at begi= nning of buffer.\n"); return Err(err); } has_noop_placeholder =3D true; @@ -1544,7 +1550,7 @@ fn read(self: &Arc, req: &mut BinderWriteRead, = wait: bool) -> Result { Err(err) =3D> { // Propagate the error if we haven't written anything = else. if err !=3D EINTR && err !=3D EAGAIN { - pr_warn!("Failure in work getter: {:?}", err); + pr_warn_ratelimited!("Failure in work getter: {:?}= \n", err); } if initial_len =3D=3D writer.len() { return Err(err); @@ -1579,8 +1585,8 @@ pub(crate) fn write_read(self: &Arc, data: User= Slice, wait: bool) -> Resul ret =3D self.write(&mut req); crate::trace::trace_write_done(ret); if let Err(err) =3D ret { - pr_warn!( - "Write failure {:?} in pid:{}", + pr_warn_ratelimited!( + "Write failure {:?} in pid:{}\n", err, self.process.pid_in_current_ns() ); @@ -1596,8 +1602,8 @@ pub(crate) fn write_read(self: &Arc, data: User= Slice, wait: bool) -> Resul ret =3D self.read(&mut req, wait); crate::trace::trace_read_done(ret); if ret.is_err() && ret !=3D Err(EINTR) { - pr_warn!( - "Read failure {:?} in pid:{}", + pr_warn_ratelimited!( + "Read failure {:?} in pid:{}\n", ret, self.process.pid_in_current_ns() ); diff --git a/drivers/android/binder/transaction.rs b/drivers/android/binder= /transaction.rs index 19ad37b0b294..971679b9b620 100644 --- a/drivers/android/binder/transaction.rs +++ b/drivers/android/binder/transaction.rs @@ -148,7 +148,7 @@ pub(crate) fn new( )?; if info.is_oneway() { if from_parent.is_some() { - pr_warn!("Oneway transaction should not be in a transactio= n stack."); + pr_warn_ratelimited!("Oneway transaction should not be in = a transaction stack.\n"); return Err(EINVAL.into()); } alloc.set_info_oneway_node(node_ref.node.clone()); @@ -343,7 +343,7 @@ pub(crate) fn submit(self: DLArc, info: &mut Tran= sactionInfo) -> BinderRes return Ok(()); } } else { - pr_err!("Failed to submit oneway transaction to node."); + pr_err_ratelimited!("Failed to submit oneway transaction t= o node.\n"); } } =20 --=20 2.55.0.229.g6434b31f56-goog