Re: [PATCH v2 1/7] rust_binder: Add dynamic debug logging mask
From: Gary Guo
Date: Fri Jul 10 2026 - 13:13:22 EST
On Fri Jul 10, 2026 at 3:32 PM BST, Jahnavi MN via B4 Relay wrote:
> From: Jahnavi MN <jahnavimn@xxxxxxxxxx>
>
> Implement a dynamic debug logging mask (`debug_mask`) for the
> `rust_binder` module to allow dynamic runtime configuration of log
> levels. This enables parity with the legacy C driver's debug mask.
>
> Since the Rust `module!` macro in the current kernel build does not yet
> support declaring module parameters directly in Rust, we define the
> `debug_mask` variable in a C companion file to expose it to the kernel
> runtime and import it using FFI with volatile reads.
>
> To verify the setup, instrument process lifecycle events (open, flush,
> and release) in `process.rs` under the new `BINDER_DEBUG_OPEN_CLOSE`
> logging mask. These entry-point events are chosen for initial validation
> because they represent the start of the Binder lifecycle and occur
> at low frequency, allowing simple runtime verification of the dynamic
> toggle without log noise.
>
> Signed-off-by: Jahnavi MN <jahnavimn@xxxxxxxxxx>
> ---
> drivers/android/binder/debug.rs | 80 ++++++++++++++++++++++++++++++
> drivers/android/binder/process.rs | 7 ++-
> drivers/android/binder/rust_binder_main.rs | 2 +
> drivers/android/binder/rust_binderfs.c | 3 ++
> rust/kernel/task.rs | 7 +++
> 5 files changed, 98 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/android/binder/debug.rs b/drivers/android/binder/debug.rs
> new file mode 100644
> index 000000000000..da48bce3df54
> --- /dev/null
> +++ b/drivers/android/binder/debug.rs
> @@ -0,0 +1,80 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (C) 2026 Google LLC.
> +
> +//! Binder debugging helpers.
> +
> +#![allow(dead_code)]
> +
> +kernel::impl_flags!(
> + /// Represents multiple debug mask flags.
> + #[derive(Debug, Clone, Default, Copy, PartialEq, Eq)]
> + pub struct DebugMasks(u32);
> +
> + /// Represents a single debug mask category.
> + #[derive(Debug, Clone, Copy, PartialEq, Eq)]
> + pub enum DebugMask {
> + UserError = 1 << 0,
> + FailedTransaction = 1 << 1,
> + DeadTransaction = 1 << 2,
> + OpenClose = 1 << 3,
> + DeadBinder = 1 << 4,
> + DeathNotification = 1 << 5,
> + ReadWrite = 1 << 6,
> + UserRefs = 1 << 7,
> + Threads = 1 << 8,
> + Transaction = 1 << 9,
> + TransactionComplete = 1 << 10,
> + FreeBuffer = 1 << 11,
> + InternalRefs = 1 << 12,
> + PriorityCap = 1 << 13,
> + Spinlocks = 1 << 14,
> + }
> +);
> +
> +extern "C" {
> + // Declared as static mut because the value is mutated dynamically by C sysfs.
> + static mut rust_binder_debug_mask: u32;
> +}
This should be `Atomic<u32>` so the read_volatile below is avoided.
> +
> +/// Checks if the given debug logging category is enabled in the mask.
> +pub(crate) fn debug_mask_enabled(mask: DebugMask) -> bool {
> + // SAFETY: `rust_binder_debug_mask` is defined in C and can be mutated at any time.
> + // We read it via volatile to ensure we fetch the current value from memory.
> + let current_mask = unsafe { core::ptr::read_volatile(&raw const rust_binder_debug_mask) };
> + (current_mask & (mask as u32)) != 0
> +}
> +
> +/// Prints a debug log if the specified mask category is enabled.
> +#[macro_export]
> +macro_rules! binder_debug {
> + // 1. Internal helper rule to do the raw print.
This 1, 2, 3 numbering is very strange.
> + (raw, $($arg:tt)*) => {
> + kernel::pr_info!($($arg)*);
> + };
Why is this needed instead of just calling `pr_info!`?
Best,
Gary
> +
> + // 2. Rule to explicitly specify a PID (used in kworkers).
> + (pid=$pid:expr, $mask:ident, $($arg:tt)*) => {
> + if $crate::debug::debug_mask_enabled($crate::debug::DebugMask::$mask) {
> + $crate::binder_debug!(
> + raw,
> + "{}: {}\n",
> + $pid,
> + kernel::prelude::fmt!($($arg)*)
> + );
> + }
> + };
> +
> + // 3. Default rule (automatically prepends "PID:TID" of the current calling thread).
> + ($mask:ident, $($arg:tt)*) => {
> + if $crate::debug::debug_mask_enabled($crate::debug::DebugMask::$mask) {
> + let thread = kernel::current!();
> + $crate::binder_debug!(
> + raw,
> + "{}:{} {}\n",
> + thread.tgid(),
> + thread.pid(),
> + kernel::prelude::fmt!($($arg)*)
> + );
> + }
> + };
> +}