From nobody Fri Oct 2 09:26:43 2026 Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) (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 B14CA3A962E for ; Mon, 3 Aug 2026 07:30:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.69 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785742215; cv=none; b=hDXmwLrRsLF1ohZ+oHrspKvFSBJ+l7Ms4sAZ8Q5HlWjacKL7+whxGUAFnelOIeF+n9bMylLrnV8DtDwIjV4wJpT8fHV4JF2N3zEa2g1PucTyiC6O9n/LhgbQdXxrL2JiH428O6HpCUQTZGt3Yr+6oYUgmIIj9/tib/qnuFmeeSM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785742215; c=relaxed/simple; bh=6OUtJxUyEDdDWF9enVUC+jQgSwejH/Ezn97FdauMTkM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=E3V6ERx/8rGMwahiPKzmMoAjsHSEmZRBW0uQ/BGOsMdsWPXJkxeg+WAXx5PrPaygNa1YMq6knRSaxDQ9h96cZrcm5xNxSiOkE/ZVprMXmWweOpyYTy3QnyuVJIKQvwLg5etMTfPtEeDQZ8O+mW7RdGcBsJy3t0cRgRc25cPhmog= 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=HjjWNQly; arc=none smtp.client-ip=209.85.128.69 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="HjjWNQly" Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-495495ad5ddso7496115e9.3 for ; Mon, 03 Aug 2026 00:30:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1785742208; x=1786347008; 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=O9W9h7wEPytZk5LBhtU84b9W9YgvfWvTGpSYytbAHAc=; b=HjjWNQly4qqcNpAVJ3TyMAYl0F+/0I5fs7oLMyd0t4yZTDkF3s+vtEC9pR9tiOzjxX otHdUMCaPA55pcckVP3l4qec/LVYfSMmWQhlcNXq3r7i03mDfYVTNoyqfGZVWimviJuW fpBaKSEHK9maPRFLcAAbE8/bOCkXrej1JOYkutg9dq5zNjFfq9sJaovuoIl/WO66RVdN +PVKXV+vPnkZ972BnZecQNbdUvl3/rkcw0wT+NeYdgahFVEHo8135A4e6UyQYpEDltse JK7LlBk2fioO/z6wy+/3rOHPEXWZR1lGtxOTbtfaQHVluDElpfLGq6XtQlmxOcxRHo5k Gf4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785742208; x=1786347008; 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=O9W9h7wEPytZk5LBhtU84b9W9YgvfWvTGpSYytbAHAc=; b=KXGR8YBYK3N2+Wn+UW0ppZAANJhWXi5ESQhzqLVxGfx+VP4o1FZms36pVy+XkdGgCO y0B0ernuUgQc7FVLKPPDftz1aZNSi3m8R7+1wxeDpXpK1dXBZL20CkvO56amGlEA8ySc ZTl/TcO46s22fov/ajgYbT9lGk4/FWTxnzL6O8y6kjYzjuYjXo5nvlqud3SA1ImWsymZ Hic61kWDPgHKQRSFtihItfXm2IisimvIjTQQy+fEOZOGVt6qresJxdSeob3RMMrtHk0L shBMWKPcE7tJfVnFGR+rk4ElhhTl0QLsNYbuAXBBeIkZDzD/Nmags71IE71Sna9NImSv 5xVQ== X-Forwarded-Encrypted: i=1; AHgh+RoKhZnZ075FpXeZynyfP8FxlXFqjlo2b7rkmJ6NsNTgPjJxWu5X1JBr36t0VPZObIEsorXXUW3G87mSKms=@vger.kernel.org X-Gm-Message-State: AOJu0YySHF+0bKapD5YLL+L+7ehSDrsJPvmaSy6je7Zb+ZXDJi6+yW1y bW7BUl/0CTUIEbtfrW08Sjgg8/UbGBbponFTbttxLb24aWuX/2u4MJ5aj8HV1S4FMrjT2glwhZM 1fdW0RHuXIzl6+wo5nA== X-Received: from wmlz23.prod.google.com ([2002:a05:600c:2217:b0:495:6d55:63ba]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1553:b0:498:ee7:e40a with SMTP id 5b1f17b1804b1-4980ee7e62amr162987955e9.16.1785742203558; Mon, 03 Aug 2026 00:30:03 -0700 (PDT) Date: Mon, 03 Aug 2026 07:29:52 +0000 In-Reply-To: <20260803-pr-ratelimited-v5-0-a77d456de974@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260803-pr-ratelimited-v5-0-a77d456de974@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=11724; i=aliceryhl@google.com; h=from:subject:message-id; bh=6OUtJxUyEDdDWF9enVUC+jQgSwejH/Ezn97FdauMTkM=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBqcEN41oMlro3w60O+akneTmGXlxWbwAEoYT54v EB+cJ+AcceJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCanBDeAAKCRAEWL7uWMY5 RqtDD/9kaJK0aWWNQxtSRgytOW+VJlAzDk9ts6DD06NQlgjz2obtDGAuIu87Ms5kda9054CkZVE SaC5cnsx4XHzfQ9TwBBDQO5IKmmx0oNAYs1I/x5XcaaQlvAz/3nztDKNd33XcD/1lVmMCGGMRit B89f0+DO9iNB0wXORywUZlQPbzJYy2Tbwn4Vql14D9IUP5eHMcXzFKp4Pxq0g+QTVwGBeK4sDKZ ltDqU3KBByfw2uakPBQUdwhBWq7WjtC7lqdZmXCiFD2qZAWuR2tcLtMyOYdnNEV1ZprcLMYy1H+ 7xOJU2eoBj6lsdxUMoQJetxAwmmjJddMTXTtqw5A7JRmiD4qAbfPsMpePcj+e7cSAwjdmMiFarg cVfha2qB1YJH4v8QD78J3GAX/rMUFt+j2hzlHH6UQ+dCwkX9mAugfiH7Sg7+dxYeCaIujQ/7M0N Mm2y/roxSCi9XQb2LZ8S4DvXBQmxMiKQbR/gG2zowehLR0E9cVKOsaOvjaq0GLIVnfRBtr2/Rhd P8ryJjp6KwnljhhrywBXIztWGt5oAUtjmDDU8JFdYZDOU5ILOI7+QQ3gNdwFyhUZNiKdGX6Ca5K bb8pK2dvTSPKrwwMdkvQE/VyaJO7xtKCbm9lG1+soSiHvJfsLFUuFkGQ2H+pNr19ASCl0KvtBq3 iCLA5RPb5mKOtkg== X-Mailer: b4 0.14.3 Message-ID: <20260803-pr-ratelimited-v5-1-a77d456de974@google.com> Subject: [PATCH v5 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. The new module is listed under LOCKING PRIMITIVES in the MAINTAINERS file. 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 Acked-by: Miguel Ojeda Signed-off-by: Alice Ryhl --- MAINTAINERS | 1 + rust/kernel/sync.rs | 135 +---------------------------------------= -- rust/kernel/sync/lockdep.rs | 139 ++++++++++++++++++++++++++++++++++++++++= ++++ 3 files changed, 142 insertions(+), 133 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 1e27c49ffe48..5c945f981fee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15161,6 +15161,7 @@ F: rust/helpers/mutex.c F: rust/helpers/spinlock.c F: rust/kernel/sync/lock.rs F: rust/kernel/sync/lock/ +F: rust/kernel/sync/lockdep.rs F: rust/kernel/sync/locked_by.rs X: kernel/locking/locktorture.c =20 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.508.g3f0d502094-goog From nobody Fri Oct 2 09:26:43 2026 Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) (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 3D20D3AA518 for ; Mon, 3 Aug 2026 07:30:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.70 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785742211; cv=none; b=CrHlvK9SVbZRcjLh4Ef00Dua5SKM3KjeMLbU/Wh3WPLryj1vtw2QSvBpmLcdRl5Wz/Qb5Q9d5dLQHEUy6SdEhwExqvYE1CJJSanx9EBRaDgeuEqjjOgFrN40lgJDyyXE6xTVqVkjCJ3kTqZuzADVey0+5LbRJKsuWMjWc2gauUA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785742211; c=relaxed/simple; bh=/YSWTZGXJkQntouN56tM4ixvsFNBxXhnHTqTdRkBQRo=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=o3H9ZeL+Ac3hsKBubcSn9iBGRp3tzfuoXifui89fjuxQ5H4w4tK8EcxnAkcCKYiBTFnvOo12gp0LYlcE49tRajwYBwxLxtQP+IrN9KHdBWQy/zkkXLD4xTTe1QUB9AUEyTwPb0/0IC2g5mqRKmh7gU8RX7H34+Z0nINxnDgb50A= 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=PGmglckf; arc=none smtp.client-ip=209.85.128.70 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="PGmglckf" Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-4955ecd8a10so15197935e9.3 for ; Mon, 03 Aug 2026 00:30:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1785742206; x=1786347006; 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=bkaEES2jtN2KJns/0+l19TJj6puYgWk/U6tLYEyDvi0=; b=PGmglckfxttpAPWRyGumHrwmpeSeXnZeFjRVkeHnXPG2kDQb8zI2awOrv1if/vKsFP I5I3g6yCwEJ0dvHNwWutdZmisHLio5ACpkm/bdGVnb0csADTOXjG8QHsLZaDBiK5bjN+ wZk0qT3fvIPel6AJn6LE8Lxp3XX7LqpNzA+jsdDm0Q08sFIJsQK3nwt+p+JVx9aaR91i IYelkx5xE1Bkf5gRq+jq9WhWHYX2FBswDPqODGTR+Vw8VZR7RS5L8YuVoj+/vArx6ju4 WdUM1wY+uuxy3aPPY8899JuZ0IOBvKGv0y4lxl6IoqhiT8131S+iJAMewalVSqQOnF/d FWtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785742206; x=1786347006; 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=bkaEES2jtN2KJns/0+l19TJj6puYgWk/U6tLYEyDvi0=; b=cWCOm7qegBtUQbanRjzgzeQVdL1S7smzwzP4x1e3//YnELGBYGQJaPVFqdCry+HYN5 XBeLckaR8hASyYxX0GzVgWuHuTuxTNSjUpAI1H0Ef1/4MKhhZy87/51rwg//6xP+96Jr dzz1q6LmX7VGjlLm8c+hOnIZREo+04Y2JYD3HJQ/awU7melJA9k296rZCXFtCw5VIsR/ HRqwX68GPM5OipJewbiJsosfe6mFOcm/9ogoj0j85y5dYhA2kj3dYPSXx/osW9Pa3qB8 5XV3bqWF3WNz3EDYy8B8mG2Rkr9dkkEAitFdfg+2a3OrGDmZNtywW3KVL7RqB64iTjS0 U1QA== X-Forwarded-Encrypted: i=1; AHgh+RosN3hgTkQf78nv6t3sYtRFLSWYqfvB+CfOJ+9/ZzvO6v6+io/TxbnwLFV8Q315yScklf4YVNk82kfA9eU=@vger.kernel.org X-Gm-Message-State: AOJu0YyRYmDe7VQOkAcjF5qr27H6iXM1MfFNVbR/ru1gvJ+ppaO4I2jW KakFuvoJrWMXdnk9G7e4z4nlEwMSzpOpFUtorobJqYb+Ujf6YaCaCy7WUP9eF6nqrIXxY7Fd1jp M7l5SyGSnoQ+i7MXb2g== X-Received: from wmqa8.prod.google.com ([2002:a05:600c:3488:b0:493:b6e1:bb31]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600d:8492:b0:496:c1f3:e8fb with SMTP id 5b1f17b1804b1-4980c64acc6mr139337445e9.8.1785742206114; Mon, 03 Aug 2026 00:30:06 -0700 (PDT) Date: Mon, 03 Aug 2026 07:29:53 +0000 In-Reply-To: <20260803-pr-ratelimited-v5-0-a77d456de974@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260803-pr-ratelimited-v5-0-a77d456de974@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=5116; i=aliceryhl@google.com; h=from:subject:message-id; bh=/YSWTZGXJkQntouN56tM4ixvsFNBxXhnHTqTdRkBQRo=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBqcEN4Ve4blYo1pZZEDpCXE1zwMBVY9riO9gCIX MBdPlkzJDeJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCanBDeAAKCRAEWL7uWMY5 RoKnD/9U0B3iya3glyqJsSO325Q0tbvKYl8k4XowSGvRnGGZqZ0HjfCiQjNxObD5s49DP0Q1Qeh DMILqykvsmmlwuu5SLEBOJy/abin4f2jqiXI8sMvf5CpERZJDnSbqD+OtJwL3l5zb5R2/Nsjg27 lrCuqtDc8R84YiYZfp7Wz+HU98G/o6SrO8MPWQkvBXtEy+Aj+N/iufIROvGzY41GL2meqPE/3HW 5N3bm62EAEZN7j2FbQRqdjvCp+V6i5NlnzY6jB4ZecicUXH06RQr2iCr3LUAwXqzWxk7ISN7li1 6Txd3zf+93KkoXI1CfdwcpiD+CfkrNle5gjgrIA1/RQDtSCend7n/OGrSaxBnVSGpvsN7bfiUjm jMPrjzIkRAoyV89V4lUcgn1ts3r1QYS1zxC1Zk6IYGt218SC92xZGP1OkVAF4xckIDU/ycdczVP fwTFG6fUd+f0CMKxQS8tRxJzb+Dkn2nSm51oeIPeg6Ja+lBnImZCOufohxlGQ51wdOT0jngj8UI PM2BN2XzbNJuLrpCJ+r6isy7pWnPQxeIghbhJZQmotzmE2sRhu6ZNWtqszakEjKhPbuxj5t88QI Wsueu/q+85pz2YM2+diArB7969eBIExDp54yfbAN8FhfPlGjkNOQEL+LJoO6lEUCk578ex9z8+J paur039SITrl1YA== X-Mailer: b4 0.14.3 Message-ID: <20260803-pr-ratelimited-v5-2-a77d456de974@google.com> Subject: [PATCH v5 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 Acked-by: Miguel Ojeda 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 812f8e5a08d5..bb35e64957cd 100644 --- a/rust/bindings/lib.rs +++ b/rust/bindings/lib.rs @@ -81,3 +81,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.508.g3f0d502094-goog From nobody Fri Oct 2 09:26:43 2026 Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) (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 B0E6C30C60D for ; Mon, 3 Aug 2026 07:30:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.70 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785742214; cv=none; b=PP8/zF0m05fAJDg4LVEV3YJcoGHmLgB5ah6Sifq9YuQASLX/LERZ1/gQOVYjTQqzGeqjt5c5wFSdXwdKsrR2UYuV+EKXrBgGRscGtnICvbvHh4pJERWmQOvNZbMP/BYFJYVEhembZZJvBvlos7TO/GgQWyXdkgfX8xcNEbZ1n44= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785742214; c=relaxed/simple; bh=wsBlPPFoPxaCiPxaYA/jzfhWKDKs0lL+T/BXOyyCY2Y=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=hR490jSNjOb+M8CjQ5vCUytR0GDwO6y9pD9nrxeWEW6hqj5xpeLKVQHHd3dWUxrdCrUMfhxQI58krlIP4ZY0RqUYQxAW/xAVvMPcJiFOPhdG2rAnEEuk7c60J7YF4v7kTpAwrNQAFMxGG1e46yyS4E6x5VfgQ71Cim046CK6ARM= 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=waHBsN44; arc=none smtp.client-ip=209.85.221.70 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="waHBsN44" Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-47f8580ed9eso3121524f8f.0 for ; Mon, 03 Aug 2026 00:30:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1785742208; x=1786347008; 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=TQvPB6jYC+U9y7/R1Rdle/evzG9UICK1eR/7QT1ydDg=; b=waHBsN44Y+y570YN8SqVi7ZLgYjvdHJ6ZuMA2zqCRXRaJLKzxiPY3oBbDwxCCCUUPs rp4qnp6syF+ZPv4cTu3C+D6hLbPgOQuRVtYAQTA1BuTl/B+boA58pez28unry3Bi1zlW 1sHdy/W4lxKJNYYXISTfcSL6QfTQJwNN0KShk8QqVTS+8DzjFjGh1r/3W2gfHJaViAlp 3FJG4NtVMDdpLpaX4HVoBMhRt6YHLvjRwjjfI7AgELe2Zr6VjXNWcsd4Oj7FBLKEna+s KXu0ift1+4fvwzOy2V4cVThb5pzWULP4aXJO2KxF2uokgCdmzRJgxhEHtWScgUJAmtwJ Sw9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785742208; x=1786347008; 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=TQvPB6jYC+U9y7/R1Rdle/evzG9UICK1eR/7QT1ydDg=; b=Rsdoe113GxWVmrT5wUK+GraH9+oq83fSQbv3Wi4AovQONyi4+7nz/vx3KlnmWJHAUJ X4WJAsrvPMSvqJ7pg8Zq3rXki+c5EmjwOnpv3lcvgWxVw26ZQ9E7c3f8xCbGV98isSk/ dp+BLP6fetem9mT1cJXH87s6h7iXmoZyL4rmekcSoACTjOv2UMA/UBDln5nRVGUAxmPA HYqlrovWpHqHtHB8Owrp3wA+LWkH7mREqelxO4MMkHKOsz2GYjNerdKHQo/TN/wJk6k9 bA4Q9ax0v9LcuhVGrq0YRIzZZq5JDamu3iPRuID2Ala4yXfHr9HhLfD/85Dwr2ReAPLS ZVjQ== X-Forwarded-Encrypted: i=1; AHgh+RpYVIpUNvpB79ZhJBxArRbzruG57y6UcmxufkraC+Njlq0/E5NAIdgr+DxtCVRe5ajVqbT+DQYd2FREAJU=@vger.kernel.org X-Gm-Message-State: AOJu0Yw04OxuO46YNoSopT4mRr4dT8LQd9njfLCauqNsGWWCkzBbtimO xBDmpYCZnxMsbSOJXOnYWdH315DyZy03/CM4k3t+6uK3xOMR4lbh3iQZMM8+HC5MdF0VdvdFvmG 2rkRUlCxtoR7fHvs0+w== X-Received: from wruz5.prod.google.com ([2002:a5d:6405:0:b0:47a:f6a1:70d2]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a5d:640d:0:b0:47f:9568:ebf0 with SMTP id ffacd0b85a97d-47fd72a904emr17895903f8f.23.1785742207772; Mon, 03 Aug 2026 00:30:07 -0700 (PDT) Date: Mon, 03 Aug 2026 07:29:54 +0000 In-Reply-To: <20260803-pr-ratelimited-v5-0-a77d456de974@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260803-pr-ratelimited-v5-0-a77d456de974@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=10826; i=aliceryhl@google.com; h=from:subject:message-id; bh=wsBlPPFoPxaCiPxaYA/jzfhWKDKs0lL+T/BXOyyCY2Y=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBqcEN4PJJXzvvRdmhB1u/dQ1F2sX27IAKExNTuY 1ZucVUyniuJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCanBDeAAKCRAEWL7uWMY5 RoGHD/9U26Z4XszYOQyjNAxBMiZGN43z/4tn4mx/mwECyvNVbLYMtiXr1AyeBK9un3CJm36Jy9p qirHf4a6Rd2qf1JTGx3gCOeEjvAQklhgh0DW+slvaNHn5b5gDgBQB3O40G9XcO2ZzBkcj60Tuwu oqiQS3HtDvbEt3d38aXhCG8FCN6mhgbWfw4/Imhx3JgilWaczsCQy9mm9VEfkzFxTAyRWeGY1Kd bIJDjdvHJtZXEV1/tituyNnYXNfwkYQvhgWTO+fGGlZ0MpVPIfovDx3y80ch2D+CthywSVbTvLn L233mii3ap9pR8MeGV9oSxe3P8vBU3Xh6Spdk9/NzWBRFekxuHXKa+MvtaDJGoNr7t20hUZI9Sz xR45D/70pVO2a9SnmeZEpu+xpvlMyQAi5ZOCfAoWcThqfWeaS8fvrEeRVtKds/mpTIlX1gbNb/l /RTkCKaq0JiO5jjGdXuE3MExNNG9x0OowywHg/FEXSAswlhUKcMp9UH4ae9/5vM8JSqjypprWvL tQs3xnHSJsN8WnStHBrKw+i217TpXsZvX+16u63yOC5Nf8M4tr0/jrIBPS3G+Gj75lrwUxiiv2+ y67qImQoHXGJBOTCRk9i0Rc4Ua5ONBB6g0w8aRw1pdvorJCn8OAprYojjAKOjlx1XuvKgU7wAtJ ohtsau45Ceu8F2A== X-Mailer: b4 0.14.3 Message-ID: <20260803-pr-ratelimited-v5-3-a77d456de974@google.com> Subject: [PATCH v5 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. The new files will fall under the catch-all RUST maintainers entry. Tested-by: Alvin Sun Reviewed-by: Carlos Llamas Link: https://github.com/Rust-for-Linux/linux/issues/122 Acked-by: Miguel Ojeda 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 | 216 ++++++++++++++++++++++++++++++++++= ++++ rust/kernel/sync/lock/spinlock.rs | 1 - 6 files changed, 240 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..5f0deae819dd --- /dev/null +++ b/rust/kernel/ratelimit.rs @@ -0,0 +1,216 @@ +// 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. + #[inline] + 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.508.g3f0d502094-goog From nobody Fri Oct 2 09:26:43 2026 Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) (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 67D453A785C for ; Mon, 3 Aug 2026 07:30:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785742217; cv=none; b=dO3ob1K3lUnsDxoMF8IMwFIZybrOIczxrIVRbLpnglzQDiRENLqu94SY+OsK2Fl9VFgusR8MVo655YHzQWouNfHDMuP+iRSRATvoDajS1xEXHL7DzDLIs2cwm6XB9M81ySFjBtYB6os3+6x6ZRtfcsVfLE0AIv8otAB8yoB9zTU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785742217; c=relaxed/simple; bh=kR3igSBMNuHw5DyXS0ecHl3gAcxwBpKtHQmxuHd74C8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=mA00NI/n6ifTKuRsyjfv5j9l8XMXv0xbGlKdLiT6XQrV/Y5hK+tqqKxRpId7LAFBoqAatqqjfe8t8A4DIK8LKL3dqeTW8Ph2RLovAI8rlihm6TAgBttArsdZMJTsGKIRAjULsxV3Ds4smwA0rVS6L742pv/rOrETmXlw6UFr0s0= 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=biub70tV; arc=none smtp.client-ip=209.85.128.72 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="biub70tV" Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-496b6f97676so20386765e9.2 for ; Mon, 03 Aug 2026 00:30:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1785742210; x=1786347010; 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=ATqpTG9YB6fyY1MztwiHEaptgvNM5wT6TJQAgysBebM=; b=biub70tVb6Bwk4ZON7XxRcty7a58HMCjAoKjbO04VwU9jr06cbA2CKZIPgzj2DuQmO Im/g0fz6RL9opKgcfb+GdJ/5W5llNXG0i1XrG7SHNYV2gu91erpn9XdUSUA+SxK8iLIh lJBvNdpwe7KRlxGjKjZr/P48Hs9XOuRRP12tACKjM6PG1MFyspVH0FY0+eGP5e3FtkzO 8YDl8Wpv1cw0TX9mB9hlWVJKVLCkSz0WsSUsz0BAh+AW9ERinpypTGImXJOjRV6pDdzF 5XCfXxFY/x4iS8xCi5evE+oOlIr9/hOnQ6rmqZ39j8GXGF4f4mJrYp7/sz1owlk631L8 Y66A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785742210; x=1786347010; 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=ATqpTG9YB6fyY1MztwiHEaptgvNM5wT6TJQAgysBebM=; b=QYMUBt4VUClZyyyVUtEMmig7Hf8ZlST5lCn2eFqWqjl6mM1ZRZdKNie0A3M0qOLQzH rNjm2HedPerzJTKyS1FfLtR/J37xqYplUf6baI0GTRl9GUr65UMbgta/wMihgdTims5X Lem+O5bF9JMQB00z6kcdIlDSkmCP7rMj+0DZ+wUi3Tx9YEZD8XGef2TU/y7ERBE3SqXp D3AWJ7g+DDI9M9xfW3BnLpMuOfn2JnCUw9d+Hy6/elsUZ0YakLe5sBWWOo/ojSZQKRHQ KbQeQnQkNTesjK835Om7EM9TaLZrOookBSN1bkH/ZBqm8KrSQ+WJwWDL2hHSykb9emPE Q/8g== X-Forwarded-Encrypted: i=1; AHgh+Rq6aQlu6oamz2X1hn1+2VHupfzf0Cq/RTT18JTQO/xxinwWDOOYg5YELxYijezrJRUQ0EANJhZqjh9tbsc=@vger.kernel.org X-Gm-Message-State: AOJu0YyStxoA5lCgDcmB/NCb/u2KA53/xnM8ZAURMSlt4j54jvvALZN8 jFKBjVJB2gDDMG1WfIFLY5rumWGpdFagdRcsoxhCiJSVa1IOpOz7NilkgrTM4M2qc3bhxCQGojV u4Bfr/bKDVXzttrnU/g== X-Received: from wmbfp13.prod.google.com ([2002:a05:600c:698d:b0:490:b058:c623]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:6990:b0:495:4d00:2fc0 with SMTP id 5b1f17b1804b1-4980c673907mr201254305e9.12.1785742209796; Mon, 03 Aug 2026 00:30:09 -0700 (PDT) Date: Mon, 03 Aug 2026 07:29:55 +0000 In-Reply-To: <20260803-pr-ratelimited-v5-0-a77d456de974@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260803-pr-ratelimited-v5-0-a77d456de974@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=8830; i=aliceryhl@google.com; h=from:subject:message-id; bh=kR3igSBMNuHw5DyXS0ecHl3gAcxwBpKtHQmxuHd74C8=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBqcEN4USNgBKMPS/gQxSmcvb68AG7oIC/QpzoEd GPcd5J6t8iJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCanBDeAAKCRAEWL7uWMY5 RnDQD/0X+OLrvYqM1gR4NCPrZ8ULyFKn30S8aZqZlU41NH1O+SMjYtdCvIuyG69u/qtehQispd0 r13yxBFVUHLXuaP8JRl7qEasuxwHR0EofD8hnmR1v+wI/oy8OHNUen+L6FETiEKw6QDMp9k48Vn aAnEDa8VL44OMGfgcrrvXZLZEyRERE6GLcrE8uNdymXwoJmsMWePw/dEn7VB93+Ev8wOd6L4sGV KJReaAffs/tlvXUC+JeFjGIuGR75UnKNtBVEZHvLQGBaI0/M6MHeaX4TnKUlMunujCVapzbHSfP Qotvnyr6fhnR/lRFEVbqf7BGnXSZSLuhLEdaJU/WoFyheu3KEuYEeCkCb6WSyDo8/l5R4ofZqZd JcAZO8cKRrtM1wpUBEUHrPtHDYK9SEKGVmCIKpUgJ4JNyM/XEzQ6hriSdSoU2EmstuEZ2VadmMH U6KYXjgVZIeb7LkrSV5sfsM3tAQWk4+tVAkNBBFXT8DuBWYm8ynGAypWzq1uhtdFJdcKdzfYJ/H vx5s/rMm8j9d3kWWrHN46Ghqzo69O6riM+2nigMlmFr9kSMiruTQSuBL19ov8kWrhT865QShosy T0ANZBlkBwaCmGxEYwFMfvgli0R3F2RrYEdWP6NjNQcm0EGoLr5TuezzROo2YFgxzhOYHP4e/Rs nORHAjAphiY2yZQ== X-Mailer: b4 0.14.3 Message-ID: <20260803-pr-ratelimited-v5-4-a77d456de974@google.com> Subject: [PATCH v5 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. Acked-by: Carlos Llamas Signed-off-by: Alice Ryhl --- drivers/android/binder/error.rs | 4 -- drivers/android/binder/thread.rs | 71 +++++++++++++++----------------= ---- drivers/android/binder/transaction.rs | 20 ++-------- rust/kernel/error.rs | 2 +- 4 files changed, 34 insertions(+), 63 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 18a14aa8a835..bdc43864f5bd 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, @@ -1034,17 +1034,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; @@ -1295,6 +1285,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 { @@ -1302,29 +1295,8 @@ 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()); - } - - binder_debug!( - FailedTransaction, - "transaction {} to {}:{} failed {:?}, code {} size= {}-{}", - if info.is_reply { - "reply" - } else if info.is_oneway() { - "async" - } else { - "call" - }, - info.to_pid, - info.to_tid, - err, - info.code, - info.data_size, - info.offsets_size - ); + self.inner.lock().extended_error =3D + ExtendedError::new(info.debug_id as u32, err.reply= , source.to_errno()); } } } @@ -1334,8 +1306,31 @@ fn transaction(self: &Arc, cmd: u32, reader: &= mut UserSliceReader) -> Resu // 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 {}-= {}", + if info.is_reply { + "reply" + } else if info.is_oneway() { + "async" + } else { + "call" + }, + info.to_pid, + info.to_tid, + BinderError { + reply: info.reply, + source: Error::try_from_errno(info.errno), + }, + info.code, + info.data_size, + info.offsets_size + ); + } } =20 Ok(()) @@ -1419,12 +1414,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 245f1556b5db..81df588d96ad 100644 --- a/drivers/android/binder/transaction.rs +++ b/drivers/android/binder/transaction.rs @@ -166,21 +166,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."); @@ -221,13 +213,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.contains(TransactionFlag::ClearBuf) { 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.508.g3f0d502094-goog From nobody Fri Oct 2 09:26:43 2026 Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) (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 1956E3A874F for ; Mon, 3 Aug 2026 07:30:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.71 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785742218; cv=none; b=Zfe7nG1NNkrrpauj6wRAb1lT1JodOrf/rogq2c6lexA5ytxrI2RL1vGb0rmi1bXxzSun8wL8V2VF7YNnp06Rwtame4VM55YRQ4YpHo6tJozwuVTZvEgP4xT12ZVEfXZnNZ9gvUn23O6hyDLCZ3j9fhS0T25fPSp0XcGsxPPGqXY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785742218; c=relaxed/simple; bh=jZtA4btUnK/WE6VCz/a9wAHo5F9tvlXIrAO6APJvdm8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=EwvKTNg7cZ2X6BWCPTbRvCC9dSaagPk6lc8U0uQkEoY1uCa6iiwYhhZPpOLCwy9aPVZoGyuauRQ82W2eXEEr6nCZ8FWhVAxYEtkqIEfSTQA9g5Ze24X+EeoWgQFa/+UOal65Atyl4Teso+I3R7/SAtc8+fB+QBJ7v26XaqjHMFI= 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=G9cc37LT; arc=none smtp.client-ip=209.85.221.71 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="G9cc37LT" Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-47fd3c114bdso2122977f8f.2 for ; Mon, 03 Aug 2026 00:30:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1785742212; x=1786347012; 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=EfNnoZZ44LCF1XN6afiqGdcJEcUhvO5gU6dm9Kyebuk=; b=G9cc37LT2v3jczsGTJbyfRcdn87f0f76nwnf2VYYNZgtgVElhMByWlFefD/GjqtUXo uwkulwvjaAItwAtlxKlJDu7NO3fG+6vL8w01/CwyI3BJ8wOu/RCQ8PwoR4PGsOY1Vxe6 L8lMD6QXBAtBwJvWC8Vd2S0yT9+Al75G0dOktr/wAjPlciKSM8F6j2SQskEdWtsYLHoM T3BCUsVgZ6hpuKiCX5RE8EQpFa2oMLOl2QojkOyDqfxM2BBhVzbR9XEZh39trCUeUK5t KEucaEZ4cSzv2LBNT0xD2juEPE81zSjUB/SMXccs2bT3Xia91YL61rIXH/BKBH3G9Fkt qJHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785742212; x=1786347012; 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=EfNnoZZ44LCF1XN6afiqGdcJEcUhvO5gU6dm9Kyebuk=; b=UkKn+IuR2jEtutOqSz1JwQR8cB+iwYxvgtB3QqgRDqBIiozUo7t3bpT6jsUsXrL8r+ ERsDWvSBLhDeFz5tuybEUvrx3Y7N+8JTWTmYeGXSFKIfXXc/0dnE1Va8PC0PU2Jy5Cw8 k9nJsyc72zlHOy08Rr3eNykt0mZ261BRIJlqQYBYWbVs9poWhnV1QLxrL9hRb90N665q aqamJ+OAXS9dv4Bf65ITRlpmwQ+JiqU6qKXf85KrnVr1U23dSxrd7nxj0jS1Ofi4TmBY sp8LblwajDFtEpRo/Pc9s/MXT9iJS2uXdplNk5brumyreUqzNYAwzit3esJ6bRkI3aoT 8b8w== X-Forwarded-Encrypted: i=1; AHgh+RoSmh1jTJEjsgkz6R8FmhF9krdC/f8Hy0ucddxgMSmZllLjix35BMB0COfBeTkHWDsXsiz8xkuCk98bzVE=@vger.kernel.org X-Gm-Message-State: AOJu0Yzd5jLUjrW94ScdprDSBRyw/fTJUZa3uEFDVZcTj3jUnMlreJc5 8PPu+C2qrYnzqaDlQYSEbVjNEbfNVRvwRskGaRk67x4JXSq+FH0J2Ifi5SuTdYPER8pknPcU1cm Z6Jtu8iI+h66zDb7lDw== X-Received: from wmdd23.prod.google.com ([2002:a05:600c:a217:b0:493:b84e:17fe]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:34c6:b0:493:a966:d5b5 with SMTP id 5b1f17b1804b1-4980c66b50emr209869865e9.2.1785742211277; Mon, 03 Aug 2026 00:30:11 -0700 (PDT) Date: Mon, 03 Aug 2026 07:29:56 +0000 In-Reply-To: <20260803-pr-ratelimited-v5-0-a77d456de974@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260803-pr-ratelimited-v5-0-a77d456de974@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=22433; i=aliceryhl@google.com; h=from:subject:message-id; bh=jZtA4btUnK/WE6VCz/a9wAHo5F9tvlXIrAO6APJvdm8=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBqcEN4uFPQxjOrQB9S3+fWwjcunkXa5Ftt8U/2l nyxz2hgQqiJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCanBDeAAKCRAEWL7uWMY5 Rn3fD/9dlB6hagjGd+WWYoyka8p4MUDKvfO79f+M1Pe0CoFEWIdkySx5GD1bPaRh5+LRqL0TdI5 Dc9Wk+rhdJLIVHm63N6DZ9LDFN28AlRscGyTEs6ejlb9pm8NG0qZ1XJTFFZw+t8vozWFAYMxU16 6EnEu8SDzdg8N82cYP1GQRafpjBYWUv79H2nkyA+huGH53FMsHreLY48vS+yOGm4diIudOzFd8L 3OlCYc0TuTauKqhjFvkDlkULRUNsE8Nx3vBY2SxTkDcA/qITPCOcdXYXrKf6huBm1O7Qt2XPgKa J/WpsIXMWSEVwnJX5InuO6uKPKBesuj6qLEmuDLHFpEYshcMEU5NWE0yvgmUsN99ZNbxKBLuwZz TjWSUnGzAb4FZ84XITJS6l3wcExsWAjGVUs1aU1++XtDeOMSYS3tDS+mcvLjCmhPDGzYcizrBLm Jxdtc0QIxNRkWleWapQjclHfmL6t149pffnLksJ8LlO2MpOdKmB5eIoatXUoodaCU+7nazu2Lrw Xy3D+3KViO2abeD6rUANFh5XGm+CsFk0Jd/F4nfv+5oFJGxxVzbYnj9XuD1Jv3JHOYc72aPbS79 oJhQrTRWypTW1TPRVDWN9fFXIWx6G4CeP0S5lKfV/imqbRaQHBtOHVt8ww43/UPsO/IvqLkG3c+ zko0ob0RvMdV2NQ== X-Mailer: b4 0.14.3 Message-ID: <20260803-pr-ratelimited-v5-5-a77d456de974@google.com> Subject: [PATCH v5 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 0a82af14cda3..69b36951dbbe 100644 --- a/drivers/android/binder/node.rs +++ b/drivers/android/binder/node.rs @@ -405,7 +405,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; @@ -693,7 +693,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 1778628d8acd..87628e7a3306 100644 --- a/drivers/android/binder/process.rs +++ b/drivers/android/binder/process.rs @@ -324,7 +324,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 @@ -701,7 +701,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() @@ -725,7 +725,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) } } @@ -861,7 +861,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); @@ -1101,7 +1103,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()); } } @@ -1132,7 +1134,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 @@ -1154,7 +1156,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 } } @@ -1857,7 +1859,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 bdc43864f5bd..5b0c29cf8320 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 ); @@ -339,7 +339,7 @@ fn push_reply_work(&mut self, code: u32) -> PushWorkRes= { 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"); PushWorkRes::Ok } } @@ -350,7 +350,7 @@ fn push_return_work(&mut self, reply: u32) { // Not notifying: Reply to current thread. let _ =3D 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 @@ -803,8 +803,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()); } @@ -850,8 +850,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()); } @@ -884,7 +884,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 @@ -999,7 +1001,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()); } }; @@ -1223,7 +1229,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())) @@ -1551,7 +1557,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; @@ -1574,7 +1580,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); @@ -1609,8 +1615,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() ); @@ -1626,8 +1632,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 81df588d96ad..227e98ed1393 100644 --- a/drivers/android/binder/transaction.rs +++ b/drivers/android/binder/transaction.rs @@ -175,7 +175,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()); @@ -370,7 +370,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.508.g3f0d502094-goog