From nobody Fri Jul 24 23:30:19 2026 Received: from mail-ej1-f69.google.com (mail-ej1-f69.google.com [209.85.218.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 A10C8368D4D for ; Wed, 22 Jul 2026 10:12:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.69 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784715145; cv=none; b=FUsH2ZiJIh85n/fQMNxV95uiXNkXaRDXGjPzRXConGt5jPgCsWR6gZcwEyb6DgpqjruK1WVhCG+tT5T+jKNJdKHm0jIpWRveM+9vUpX8leLi4CyGvYd3sY66brxAxD2iyIzD/F8tIiNkkmuC/TjLQQ9QIK72mON4P37afSTMKnc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784715145; c=relaxed/simple; bh=+tuwon26i7NMHDgudyG/uZWyjNbEDWOkDlgtBA6Yz7Q=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=sGTK52ilcLBHvmHyZ2b+0bDgiR2dRPLZU7W1TU5BzPEJwWEP2q63rriVeF6DYC6rJSF6z0SKnAfYQppDF2yEt+42W1PsZ+oOX2OpbwmaZcN0TZ1f/VputsZw758kOFKVhY2ASkGRZgtHQedGlt6AslC9RO55Ked3IPK+QyUrrmw= 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=REL+VI0S; arc=none smtp.client-ip=209.85.218.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="REL+VI0S" Received: by mail-ej1-f69.google.com with SMTP id a640c23a62f3a-c15deb3377eso1060696866b.3 for ; Wed, 22 Jul 2026 03:12:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1784715140; x=1785319940; 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=Y2BvQ11kXLIbDEiQSMA80OPUJbvs5+anKj476L5SRjQ=; b=REL+VI0SXXn6OSCU66ZIu+uMnsqydZMRySEQzu9Y2dE5e+9XNh0visoEo9PE8ofx5f 1Qy/69C77ytoVFbtsDw6kwiRsAMCZKkFHTJCoe+3aoOCvHAU+8VP8izeaBJZyzQU9ST5 xgJsd31kxzPFzNbRB3rq2VgUDQpNBZdidHswZNeGAUrdulmqajH13njMwlmxcTeGc8lR QDhCsYRKuGzq16bzfGePuuze77jNLKcrhjkJIxfjEHB91Nc8ZOqoHC/TRxlyDlkN4D14 XzjnTAoaK1nOGvEbKCU5AkxKPEBDNDblLh4RiBMZKwCyv7w2xbLpYO7YmXpylshLwUhc hgVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784715140; x=1785319940; 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=Y2BvQ11kXLIbDEiQSMA80OPUJbvs5+anKj476L5SRjQ=; b=JtUJoINcGSIwFy/is1YpjWvdx+qWCayAOD40Ei2BQCX+8P75FUBXhw0XOIN8COG80+ X7IQmKzY+w3IbncLamSx5rITdPK6IxMVanJ00wWf2IxvzPRmwLA+v8WxLI0VuJyPS+9Y 6o65GRwxRaGyS2dYdqPFaOKxC5ZKdCGLCxNf19BTITOvgYylj47dkcV7o8X1kPxT3SD0 b78SSwCTLjrObnAZit+zkeOgoTFU/0+eYWtpinmdjZRUNN0v8meN8ucik0qiPQ3YaV5/ J6v7J8cRDsm7zVg/XJYkvbV+DcAQMIhsCiNWfOhiFfTILPn2jK97kcRqRq4IOWSYYW0Y 0HjQ== X-Forwarded-Encrypted: i=1; AHgh+RpoFujE8nnhLRUROQwZX6hmsdqfOlE/VGfqugUfA1Cg8gVQXuMHgWncp2oTzTDnfsaJQzO8RiJOiCUrY40=@vger.kernel.org X-Gm-Message-State: AOJu0Yx+XUDKB2dvz/DDZkJ+OW/h0Xt+LYpnsiwa1Uaqap4SFisQeENG jYLgjgTwcikWQJ44SxjgxLTWZcDzA4nY60wEW4jhoNZ7hEa20cjQclpxMaZ1L9t1pOI8VGJgZRO P0gmkxqCQyNkyxJQihw== X-Received: from ejbcb18.prod.google.com ([2002:a17:906:a452:b0:c12:83ae:cb65]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a17:907:3d04:b0:c16:1ba4:f29 with SMTP id a640c23a62f3a-c16b48355a1mr952622466b.44.1784715140066; Wed, 22 Jul 2026 03:12:20 -0700 (PDT) Date: Wed, 22 Jul 2026 10:12:09 +0000 In-Reply-To: <20260722-pr-ratelimited-v3-0-57faa37fdfbd@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260722-pr-ratelimited-v3-0-57faa37fdfbd@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=11681; i=aliceryhl@google.com; h=from:subject:message-id; bh=+tuwon26i7NMHDgudyG/uZWyjNbEDWOkDlgtBA6Yz7Q=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBqYJeAU4/lgMt5ABrgp3XguJBH5wlL5etP3yxVx 38s9PVoJTuJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCamCXgAAKCRAEWL7uWMY5 RnEsD/wOKSV0CXn+iLIpCwCnAMp63a0ZvAbuwtNsa1lH1BF6ZnjKyNQ5aqDY0d//i30XhKBVZVH oeS2oFGMGJbrWqaF/52UErXFAbGhoknMsV17K2iSCnIQzM1/FZ2CkQJkmaCOM5WjulZl8NFqM8Q z3fpLTRa6yFJQKmEyX/WMq7a5pDblbqbK4UjbgpBx0Eo9nZL4B1Q9do0vO8ioeXAATz5/VazMw5 ofmaH2cRwB6qYj534iSFkE30VUxqZYbHqKgc91Pjcr0zAVZP1x/+ortZZf2BwNPgbNb+ZuyXPSe dATUHaprX0btt7LpbtZWTi0wP5pxxcHP273MB9eBvvrzV6KSYhn+BftvP5tWTMsYbxG7heB6W7g LGfFECg06a/EpFujLIdOwkjH5X1LDsmeavDKXAJ18Y2DiYFhAMXM3lgTYS2zRj4Gpe/Q/Dsktxa Y+IjVU+O+egY9edGwqyVjjpUdj4KssX5nrJus49y3fSpCRlyteJ/qj2nJdqealnwn/dKeA0hUF1 ROHfh0P9uzJnMNwho5ajJAVUx/lDZnykXk0ytsE4PzQ3ILVTONtiSi/lXzUcXnRF1gLmCnSYwp1 SwH7AqbrF2E/WSRUTyJ74y+jivBAS+oltIN9TtAYBhaa9UT6Qk8J9aFjLgimlC62m8/237gDNhP 8LOQudkXKG2zsSg== X-Mailer: b4 0.14.3 Message-ID: <20260722-pr-ratelimited-v3-1-57faa37fdfbd@google.com> Subject: [PATCH v3 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 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 a3edb1fa7954..814ca2b12f16 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15156,6 +15156,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.229.g6434b31f56-goog From nobody Fri Jul 24 23:30:19 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 BD1A13E3C74 for ; Wed, 22 Jul 2026 10:12:23 +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=1784715145; cv=none; b=RvVT2+ORYH4wVsBSS1qcu0ozqMJ91DhtYFVkTQeC9M6//J1wt+KVQYrpAWjp9D44J/XzYKZKC8P0gPKtfpVAt+/hq1JksJSd88hBcPrP2Xp6sqBh5oZgT5s2QFe7Y47N+hJysXD8N/MjbAjAy8sanLs5ggIEhpWkcZJ1P7gKRMA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784715145; c=relaxed/simple; bh=VJEn9k0cad7bQSpM4TtNmV26i5N7k4ratpVcrf9ivaI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=GNROE5WvUt/xr/qkQSmwTJNDKqkHsWmbcAEn18o6Kt2EMCx/hjQinYQwLlJMyJKQC8mbKQOxA7giiwYdYiB5sQ1+OzL+W484f0Syw3aLJ8Nhd/QgF0QreqfqGCRgrlvluGc+qjKbvogvbFG9kOlq+/NHf2oT2UHhO1lvkFQdigY= 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=l+qBKgxq; 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="l+qBKgxq" Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-4955b2f56a4so22142305e9.0 for ; Wed, 22 Jul 2026 03:12:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1784715142; x=1785319942; 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=l+qBKgxqbMsqAd2aJ1uI3jMqUc8hT7qdPt3wD9B9wyqKhiOutqjPXHNn8DJkhOfWpT e7TbRBWzh8hmHbd1lUOU5HmYDBIGBpRIb1VZbnh99R/MrRz0ZPp3ACj89XgbHH985nKx FdPJGF64nCUhxbUZ51pZM3JDlzbgW9U1JaCPOSfIGKfSWbgppuCy5PvDqlwbr034mio8 Ox5BWehsb32V3Jm6TTtkU9FHtpgOGIksomVzGrUA1qUiZGzmqKXe+laGuJkTEdYNxtId nv3gnQfxsDPdER99h3XgtSFtv+ZXPS2Rel1d4oCSut/y0wbCaVicyU3Ybhur9cFui4GU AFAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784715142; x=1785319942; 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=XDcH1Bh6s0r9wlybJS4kfhuj52VzGOmo4RDOkyA0YaEqLfr0kNV7ekiJNljylqoM1m ozcvDvyM1PS7+w3T/lUJ3cpMDHaRUxke7WZsS3re6DmCrSFpMSM4Y3lPlvr8u2kkRqWz 9c7hhHtUCaJsWUZvH0QljU4MRKGZa0rsWwQGJZqHwpWoxWF34yE4UbcXU1x6Fi4/xOzM ELHk919Uru8M3Jk6MO1ul8jk7+iHINE2siiGWY2nzfcFPpW/8KJ1WGm+H4/ZAGugyHQo JV1K/6VBdVyUJ0Skd4raUVuv+WNOxt2CopMhzaLtPS9VoamXLgsFYbY5hg0C/DaSqFzs kWlg== X-Forwarded-Encrypted: i=1; AHgh+RrdcJ9zO7QHdM8SqkqgC6N6QbHvZxt2VZJ671uw9O6zbo/89EOp/KgdsB5gqyDAeB3Z5tgcu9kTlAHo+oU=@vger.kernel.org X-Gm-Message-State: AOJu0YwlITyOwaMXjHSz7rII+F3rz+RAJbM+1+q1HTCROMfcg7l8HSuA qW4xJKPFr7/KET34oVAEx5/sFJ0XVc44/czKzFF7QL/y/qIinPT8dlxM+kqZiuXPEmcirLE3uvG dTRTip54rbCHzjTf9jg== X-Received: from wmg10.prod.google.com ([2002:a05:600c:22ca:b0:493:c531:facd]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4746:b0:495:4d07:4fcb with SMTP id 5b1f17b1804b1-4954d0784c6mr229986875e9.36.1784715141388; Wed, 22 Jul 2026 03:12:21 -0700 (PDT) Date: Wed, 22 Jul 2026 10:12:10 +0000 In-Reply-To: <20260722-pr-ratelimited-v3-0-57faa37fdfbd@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260722-pr-ratelimited-v3-0-57faa37fdfbd@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/ZANAwAKAQRYvu5YxjlGAcsmYgBqYJeAX6DVR/E74RaBE/8XJiaMvco9GQEYH8S5Z U0SZu9jqhWJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCamCXgAAKCRAEWL7uWMY5 Rq82D/oCHfytgelXyIx257zT84fG2/eTfdDWd4it5XMDtY0dMiYjFLlFBHipSRlmIK2u8uvCvim ZAkcQ62b4I49SxJ4vzjNuxN5IVT4HHjnROuNm47BzT3/I4N2s/FOXHSA6v7CuIHRDL3BhGm83++ mjAojGoYq3Pwzwxrmcrp/yLLEWK1mRcHIN3Ni/qejAGIlvO0KjGJVbHQxuk24V7sIeCnNXheFMS Oy7TSyxMw7sFlT5c77fIO/2hvyZX96XpBNn5mGqLFExyd4p8wDGEe0L+OpjuslL/4/Ho/n6G+ph waeCspNbiA4ElMdRIXBZOVNYA5RJIM5pa+qh6rxGoqeWAxYUhLVtys6hbHGeHWnQ3FK1XYQ39g9 dfZ6mVhl9cxtHbL9RqyZDrlQNdqW3QBaCQK1/ghbp1DZu8zcwNyR2hojcwRESJhAMUW+lqEsW3X iir9aErhwO5Dp/d1swbEREU3bmpnnrfamue/HBj3IvfOqAqhsI8IlZ9LEAINCKjyTBZNBP44QDz j55iXSsrdO6sncnUmAjIwYydHcvRAQ8TSvzvOXxlp2jHGVOyusczR2UJ/9GyO33kOTWril6tuP9 N4cszZxvLwcPWMJlZUvxTEvYuqZjipVAMNLmmxxWngckKemiu9NcTDRwbUIMTlzQ4qNDnYVr420 t6ayYwNOUHFK+Jw== X-Mailer: b4 0.14.3 Message-ID: <20260722-pr-ratelimited-v3-2-57faa37fdfbd@google.com> Subject: [PATCH v3 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 Fri Jul 24 23:30:19 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 79D9A4746AE for ; Wed, 22 Jul 2026 10:12:25 +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=1784715148; cv=none; b=Eywi5bXFPrJKrc1AdtqPVkM40tpH0vVVzMu6YScHpcUSZ4tlpnKMaFVtr1V4swUSpTYGaE+falYo1rxmKyFI32Ox/8EEqEbu6nrgpKLG+jTCAmuV6/neUMSdOLSQJVTukieYqJLDI3gHoJO7yZLRW2mhVXrNdgcNTGLny1iQg0s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784715148; c=relaxed/simple; bh=3i3GDjIlwvozhnGmllgMo5tK2nwxQB1v2sugL7c30P4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=IhJBkZ9nFHzib1OWhS3EKqtqKB7bqKarFxoiIq9Cfqi/vphASPjO3bLpV49+kxbRnt3nW6FhJPoVBH+dE452TXW0ocneQR4E8qTk359Mmt1MMYADakL0JuuHyomDN4RUpXATrvu29mXd8JP6DRmiPZmI8iWt3hYpOl3HpOx6iPw= 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=iHsY3UWC; 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="iHsY3UWC" Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-473ac08a6a4so8128785f8f.0 for ; Wed, 22 Jul 2026 03:12:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1784715144; x=1785319944; 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=iHsY3UWCN6SuFQNaWUPfJexmzhDFhSHez+64WpSqEAacqaopjAoc7rSQAR7fH5JYZV HJPmtyGFDXRfsqzpU+GxOkXpJCH9lPW7Zii3fLMxdbJbLVLFt/NMleLWE6VwWftpyPce jGVnoNg7/jrjVUzlz6fBWGqsGXxLW47PAfIo/DuWAXId0VvVfUW6vyPz6YYJPapVjHda 1L8COQXzqvRmqcTS+mDjDaZ0LCF9zOPFCYI3QTDAJUDuR3U6LWHAt2OAPqJ29zNdkSXd +kqCO/TAEJ+S2u43b9dRQCp0I9SlRbxfPORaQYAlCO8DY8rpTDXParFHJZKtqrXMVCYN ZNbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784715144; x=1785319944; 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=PC/t3/7CUdCLZYKOCgo1XrOEnehTNdPxmNJ1rQrlEHR5j7uxEAtCKaFfdh3sJhH6N9 PNvnSXFXfYLkqBDGBEWxN3xxb2+NnnLX5Nt4/61MR1VFhglMTlhbzl+pNybIec9ChBtC OYwERwc26Wm2CwXTe8q1sOAIrmVJlOBw9sXnE3AY2XOSNto0i6V+zWITPxCVX1CCz6kJ ENYKsRIJN1Bj8hVIeD1qVK34Y30emkyUdfviu6yBKySbsQO5UrXYOfN1k2ufcyK/BVtV dcZ9iEMOpir7O8xA0IyD+UEA6mVc5QyoTYETOLbyYQghzq0t/6Ar/8k/Lgzc3jgNfDp5 MiMg== X-Forwarded-Encrypted: i=1; AHgh+RoRZTEIdHsgjx701or5Px8QFGy8rWOW0Jxei5vBEIPUMsXitNVUSVk2Ulp+GZdbzfdBBMXSve38SpQqF9c=@vger.kernel.org X-Gm-Message-State: AOJu0Yw3VrxqtLHIqOURzJGydKHW2AMcGMOmMUa3v6na73jlISiYsGrT 2FzaQ6l6itNj4Gl+h/8IW4sAbO2Qdib4L8K7zHA4qNrLSQowrTqIJ3BpD1L45m2M7XaDTeQl1zs Zt4OjJ18+OHJlujve9Q== X-Received: from wmbha11.prod.google.com ([2002:a05:600c:860b:b0:493:b301:e269]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:190b:b0:493:c77c:108a with SMTP id 5b1f17b1804b1-4954aa1a10amr240255935e9.36.1784715143275; Wed, 22 Jul 2026 03:12:23 -0700 (PDT) Date: Wed, 22 Jul 2026 10:12:11 +0000 In-Reply-To: <20260722-pr-ratelimited-v3-0-57faa37fdfbd@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260722-pr-ratelimited-v3-0-57faa37fdfbd@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/ZANAwAKAQRYvu5YxjlGAcsmYgBqYJeAQWMR55n30JeNseWxvHvsvNWsTDmSCdNU/ j/Ab3QM64eJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCamCXgAAKCRAEWL7uWMY5 RhTuEACnwc9is6TBh96Rvo3qwhDVoygAzJGXd2QKHu3jgso3wgsRAGxxx3cyFl6Ig4yI6BAyllE yaTwqvFnm++S9p+h43S9yGqbzx9cJvV0KFQ5O9iaXKAoGUsCSw5J3PPdUe8HHPiG9Hi9i+Si7Kd iZNRgtoIl/rTsjlmnOmWytY6+oOrcJpb9VxNjxsZNew/JIiVUMVbT8rDJr/fVVszpPT6kLXyPtj HYzKYf6aozCoY53JvdW/PzzpRHbL+En0SgzwjthwqanwzfshwK21lqtOKYHou4I5+r/66DYqWpc uBsHhlaSwTtwLQSzT88k5L1E0TJT6wQfc6ylQZlHr36g12u4a/V4uJYazWO+4Wq+9EOJnp7sO8q zB6l1z/aX1RoDIRHwgEIL87kBpzRMpIhV/ahnqfsTTGn1DSC0vbj/fP7heYtobNl6Unbb1xFuVd W26l9J12Z2hstwMF/E1W9P7byWy5TyIc8C2eJQtdQ3b+9LWAJA4ChBYRdqt0noDNRaqO0nBfE5v Vbc896Dcj2BbC5JUiCvdHf77bzCQ3RYeJ7cnXJq8usXxgX4X1JoaFQxpk+5N8caKOVoAqnZXUPs LByx0+GMnT3vpleTiSuYszxrtTRVkl7ikKPV24w/So4XmBaqWKo8+7Y5jmB64INwobFO3RChAUk NI0d9aHktB9pjYg== X-Mailer: b4 0.14.3 Message-ID: <20260722-pr-ratelimited-v3-3-57faa37fdfbd@google.com> Subject: [PATCH v3 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 Fri Jul 24 23:30:19 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 1FBD430BF4F for ; Wed, 22 Jul 2026 10:12:26 +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=1784715149; cv=none; b=HyQBOqdWfxL7kLneDJXPADYbE+7kTUm65B40iCRjOxzhSCb79MLMtHP0+QaF/ed9FzkTOjTs5d+2YwANTtO4k3ocwH6/HOjnGROtJTCHfzKI247X5bbLaqHhfYTu8iDQtezJGOt49KpFnmwETMnsLP1HKa9Ql4GN/tRwvlstaKg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784715149; c=relaxed/simple; bh=u8+XbXW/iqU3Zl/tDYSpWCpJulWxkMNYKzxdzveTm3c=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=RFwwtpiAVoVdV7KCQRuNhulZVBCpQRZewC4l/HnXrDGfu01+Z8sIrtFBN+HikdmyhA7p47oOPkLDVBv+JVR2J38JvHmk1Xn/cdFbBnejRFwFGjc58jfIO3N3ISFelIz1UMkZuZZxCRjhckNOXbmsRBRJHseXzhEiGxLyR+UV1CY= 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=Cbos2NP2; 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="Cbos2NP2" Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-47f83a59e5aso1100995f8f.0 for ; Wed, 22 Jul 2026 03:12:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1784715145; x=1785319945; 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=OPrehYfXohkL1JQRHKrXSg8FGuetOVxo37j+PsWbvzY=; b=Cbos2NP2lgc7mv4usVvt7bJIBRdE6EZU2w7FeBkAM421K6eHYUdkapENl+/i+CDD8g ZsCuLhIBtnBblCFJHgYqcjpFK/CI5Xd6R9YEVLxFmuUsfpHqvaUWSoGoHg96JssA6tGl Q2y4C7Brk/Y27JMfiNALoJ/ngVjwaa7YKNsImS0VFb4L1FNnBBplVUgcRW1mm+laKE1V qcW8SqTiIn7KKClnROItk7EtilNvNdVC3yULfNDp6QfQjOzE7aIhkeNMK1EvO0Phzee2 0eOc4myVSzS8D+Iq0ZEOn1McH9HMXR03Z4LCap4OSXMtfhQytGJ3a5pF0gnSkI/9HLJY h2tg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784715145; x=1785319945; 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=OPrehYfXohkL1JQRHKrXSg8FGuetOVxo37j+PsWbvzY=; b=IlZhZBJF+tCT03OV+VD1YAn5b0fMlcHE+2UST2MphKw2LqBsrg82hz8Zg4I+GBGqQm i8mUVb0dO+4LyKZXE7hmAgi4dv58w++z4cmVH62HHVDG4vdtupp8dtbd2rw3nUUP9unC 7pK/2vST1SZvuuJ/ifKzyb1Wt6r6r63mw5uxr31e6VPGDgmbYNBuyWr0Pis2bfCM2zMA Kg7KxFt9JpNTPW8wdq7rI7lt8TLd/xSHN/r2GLUueyOUoYcyoB/PL4Jn0Y16NUfkPddI WrPVHBHXaVCaAMM1RrHfQrlNG1pcmI3Lls2wwQF2+Wq4pmZdMSKyyDZzQ+ewIIbjELNJ hfDg== X-Forwarded-Encrypted: i=1; AHgh+RpDOWcDDehiA2E54eFdWsCLb13VDI4efLrdFCAVFxY4FQygkv4+aOT544p7JyfvQPocLsls+iPMO8iJ0rc=@vger.kernel.org X-Gm-Message-State: AOJu0Yw01/B6tZVBYncIC+Cqqq+mhWAl0b8eo8I0CR0uExvo4X8amfpY 7Bv9YC25slouobxoy0Zd7dukarqNsfR3qHFZKja/sam5mjSL1yAifYrXJdtTuIuTuZ7XYecIU4r KpPBdK0rtFpJY0drOGw== X-Received: from wrtw5.prod.google.com ([2002:a5d:6085:0:b0:45e:edca:cb12]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:22c4:b0:47f:81a9:3f36 with SMTP id ffacd0b85a97d-47f81a93fb8mr6950952f8f.18.1784715144748; Wed, 22 Jul 2026 03:12:24 -0700 (PDT) Date: Wed, 22 Jul 2026 10:12:12 +0000 In-Reply-To: <20260722-pr-ratelimited-v3-0-57faa37fdfbd@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260722-pr-ratelimited-v3-0-57faa37fdfbd@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=u8+XbXW/iqU3Zl/tDYSpWCpJulWxkMNYKzxdzveTm3c=; b=kA0DAAoBBFi+7ljGOUYByyZiAGpgl4GgZJD1g2npFcsrYldSO6FBD9gIOEhhSSuuqEl/bX5ZP IkCMwQAAQoAHRYhBIOSopRNZAcK8Ui9sgRYvu5YxjlGBQJqYJeBAAoJEARYvu5YxjlG3DoP/03S HadXx/3SMtc/ZZyF/BUUGh40/F06jGYSTTJUMYGh7a0VnLMuXaY75bX0uJvL5sBMz3unF6pXY/B XFAiPkugB0O7KMY9Niz4T+bsMFsLcsJ+GOpD6JoEl+SFTZaFR1fx/dHGCq3CYxbXTyc3BtpQ8L0 8BhNAHhJtG3dA2qDrDdVEKHespVqe7dosE+RKvRKCWdsEVosHVKd4YrG5QXDStaSGiQv/uJ/hde /acpQNVcecWIacNxTegKhFIX7ocnHllkNLTS8MZjaXNQNDNVAmEvl7qITF4BowTeMKaevn9sru8 pJPO688n5B4wuoO7SILRbkeOxHV5jvZTjFw0tzQpwF0u1bQSVH1Kf5X/u0NqfdoVrilsOrELfGV 8YjE/Oookom5J2UGVbNSQymG15zuLIPasKVkW6fu1WEZ3Spkcen1vLKZXV6Zo0oXTHw+HXbjGkB f6KHHSAWpgCO1+OYKFhV3gUVTqI1kU5FfzghNUoEIHzN2beFjUhtykt9sS7wMYBE7T80OArjieg DxjXa8xguXPw0mSN8Wu6jRldX4qc3len5jaRPRAtaf3tbGW8t6xrh4GWar6TvjK7aGN/5ROx6nz 48C/acc2vbzYLUwCZHkyIyYU9R5H0LnDr3UU8l6BztKI9QPOpRn+qsUIzRClY/n4qicwwoEAHdj m45T+ X-Mailer: b4 0.14.3 Message-ID: <20260722-pr-ratelimited-v3-4-57faa37fdfbd@google.com> Subject: [PATCH v3 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 a51821dde0ad..44ad4c2e8786 100644 --- a/drivers/android/binder/thread.rs +++ b/drivers/android/binder/thread.rs @@ -25,7 +25,7 @@ use crate::{ allocation::{Allocation, AllocationView, BinderObject, BinderObjectRef= , NewAllocation}, defs::*, - error::BinderResult, + error::{BinderError, BinderResult}, process::{GetWorkOrRegister, Process}, ptr_align, stats::GLOBAL_STATS, @@ -1022,17 +1022,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; @@ -1283,6 +1273,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 { @@ -1290,13 +1283,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 {}-= {}", @@ -1309,7 +1310,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 @@ -1317,15 +1321,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 @@ -1407,12 +1402,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 13dfb5c5c955..9c9e11d08c7e 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 Fri Jul 24 23:30:19 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 99780472530 for ; Wed, 22 Jul 2026 10:12:28 +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=1784715151; cv=none; b=Lhoob5EUuuPu0supjBrlCvYqrYDQ6+tby8j5CL1TctceF2jmgdxOFeA1e+iWE+cpDOcota6syu4iMsfdDMjUlw5OaCMmtT1MCfRXOSk/+F1LRBA5OOVr/RjURbUxa/3/vLaJalyXRkmlzoLpKX4EdnjhiZzYm0bt5CW7HbTGthk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784715151; c=relaxed/simple; bh=tyPNG+NSueEA+Oks56CO6sShs3fTtKVO6nXbyfQyQ5w=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=kvkLrv9tP+bRMb8xlfL/lzJFEyMjZhHwg5ukUcEziKlL3+1rEjE2sHuyP13Z7ZGBACLOCSlkJ8kPeWzpCisJ6Hl+Q+uGvVzVaMp2FtLvvPdamCfLs5UIHvMd4EzXRALNdUW+vW9fZwXNOc99QcDe+fHXvWEVmtrS9poHQyyD9tE= 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=SlhCs19e; 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="SlhCs19e" Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-492488f8583so163837015e9.2 for ; Wed, 22 Jul 2026 03:12:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1784715147; x=1785319947; 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=4ZXFE5FvE87Hu2/6dxHQDjFsr3IG7iYihBHixTeYHvU=; b=SlhCs19esZfZEHnzPDm4RwoZon2I74QobDykzhzzDlxGWK/1S+M8dTNHoaalikrwHz 7m/PcFw7pd8XAhMUZsSXc+SVCOnDWFxtrMylbpFh3T9eyZaSVNe5Qxc6PSkjPr//lBr7 oCvi3GWt3GcSqzTqbO7yCchlyKQ3k5OmKV3/1SZ8Fc2JeXF4B41y05S6Kag/QqVzqV3F CNuxAddD5QIfoQxsZtigJILp6bi1jdPeLLEHoPiUZtSKncC6pr5mPxP/gmwELzy/5TEv 1k1mCE7DIWgkfHmZtviKGnTd0KH4w/uBoAz0ws4/RsaFG2qvGPlhUMWo14lWd9WBsMMw MyMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784715147; x=1785319947; 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=4ZXFE5FvE87Hu2/6dxHQDjFsr3IG7iYihBHixTeYHvU=; b=cYvmsmHi+rOqkl+fhetIYJneH8XfPId5lhOg0l7iIvTAQcPLlpaKuzLBo9dlK3UFsq DWwex7fR9aKOuXANEzfo7zNTkvX18l1YP9gDXx7mqVoJGmB4jKVwtf4UWtKgyu/A0W+I aynBqUeFQ0mAvoluXh6puCrY1fTnvjSA+PkyhwT2RXn6/753TQpLFhoXO1lzjaykiYmp gotk8aZpQ4OevYhXcdw03uSMOWnUHIMjwa8joG7GkISC/Hy06TH13QE5AaNaBIolQDm/ vm0YGkejr7w4RiMBTwf7ICiPyeUpJw7RLDd+4HCYopDTR1c9VYmIyFcmOfcvepMpN7jx u/MQ== X-Forwarded-Encrypted: i=1; AHgh+RpgfGQ33JOW4SGQULXASFNWGvm3Vai+ZWryYwyS/8Jk0k5rJYD1rANs1GIujJQ7bzME8rB65DLttfh8dpA=@vger.kernel.org X-Gm-Message-State: AOJu0YyNKzfkhEhS0VAoBRAvNPLFmLzFBS1Gx5FH020jBpHKaHrxyha0 OEw8X1ezynmhPEQNmeyUlz0cgVcJg9MynGI0uIkKeZGJmjhDsoan0oHfPUVJfcQKv/sW2ECrqAw f06tkIN1vkKphrdl2Yw== X-Received: from wmtf6.prod.google.com ([2002:a05:600c:8b46:b0:495:3c12:fb52]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:6d82:b0:490:b8c0:d470 with SMTP id 5b1f17b1804b1-4954a405ea3mr177754695e9.19.1784715146228; Wed, 22 Jul 2026 03:12:26 -0700 (PDT) Date: Wed, 22 Jul 2026 10:12:13 +0000 In-Reply-To: <20260722-pr-ratelimited-v3-0-57faa37fdfbd@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260722-pr-ratelimited-v3-0-57faa37fdfbd@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=22432; i=aliceryhl@google.com; h=from:subject:message-id; bh=tyPNG+NSueEA+Oks56CO6sShs3fTtKVO6nXbyfQyQ5w=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBqYJeB2/V/kHNdYPccYnnwJlQscNy4oGevtbpyy 9/ZW2Vb9vKJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCamCXgQAKCRAEWL7uWMY5 RlDLEACz4W/5eh/86jC8icUZTzNnVE8g1DM0pHGYysc+6IR+2yV/X6nYK/dZe/gk2afoDwb/PVh LnzTPL9hJlw1Gp9l68ZDauxrxzXBsyQXMOtdGZlkkzeWXcSNp8fsSHr/uxTCjji6woPCGWv+yTR gn2fBZr0OGvO0CU5dh2shjNsJlBjJYfVNc9R/fezphz7fPXl6gg9VP6J/TV10SvH4hZbeOrweEA LWnYsDLgunl4ORZLKCOi11ST6Yo/ViYiH9QQqVUgIG/C2OXHQfZkWVqdMDuzry6+GmT7hK9XA7w X+M2lD1i+zkecn6mmiaLRRtsyuVIXCMKi6u9mNgwbI9yrWzTvijKTxI8mSXC8/tKqecTLpxXkuo BKK92oj+N4qwNGgYey9DhqgVyHwDtCWufmMGpiCqUE08r6Ynyz01ICuan3Ibw9dOW4s6tKU+pCu md+kH+KHp7QdzYOv5aReJ+688fq+CL7wWYE9PvZvpLAoSwz6jmSH46S8Z8oz+kIySWGdinfsjNI Zw/A4Kj8bLLtNT6X+EXaewze/eD7LyFgybly4suml9TBqGJy941WFqlp7XAESINk8sdy15SS2zP B0PsyaCaad3wMRF+euInG8mXuuVEj//fS7BJQOgtOLwLPYkUp45fFY8DNaZGCpGWwZA4gpF/f5x rXhCHIkD//1UEfw== X-Mailer: b4 0.14.3 Message-ID: <20260722-pr-ratelimited-v3-5-57faa37fdfbd@google.com> Subject: [PATCH v3 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 b74ef32b0d94..d6d093dc2cd0 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 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 44ad4c2e8786..e5d11b47ad2f 100644 --- a/drivers/android/binder/thread.rs +++ b/drivers/android/binder/thread.rs @@ -159,8 +159,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() @@ -169,8 +169,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 ); @@ -178,8 +178,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 ); @@ -328,7 +328,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 } } @@ -339,7 +339,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 @@ -791,8 +791,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()); } @@ -838,8 +838,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()); } @@ -872,7 +872,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 @@ -987,7 +989,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()); } }; @@ -1211,7 +1217,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())) @@ -1539,7 +1545,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; @@ -1562,7 +1568,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); @@ -1597,8 +1603,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() ); @@ -1614,8 +1620,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 9c9e11d08c7e..2682c2e0695a 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