From: Mohamad Alsadhan Date: Tue, 17 Mar 2026 14:49:43 +0000 (+0300) Subject: rust_binder: add ioctl/read/write done tracepoints X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=be3953bb2655fe4571a1b2cd1705bcc5a241a58e;p=thirdparty%2Flinux.git rust_binder: add ioctl/read/write done tracepoints Add Rust Binder tracepoints declarations for `ioctl_done`, `read_done` and `write_done`. Additionally, wire in the new tracepoints into the corresponding Binder call sites. Note that the new tracepoints report final errno-style return values, matching the existing C model for operation completion. Signed-off-by: Mohamad Alsadhan Link: https://patch.msgid.link/20260317-rust-binder-trace-v3-2-6fae4fbcf637@sdhn.cc Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/process.rs index 312e5c3f14cd..820cbd541435 100644 --- a/drivers/android/binder/process.rs +++ b/drivers/android/binder/process.rs @@ -1659,11 +1659,14 @@ impl Process { const _IOC_READ_WRITE: u32 = _IOC_READ | _IOC_WRITE; - match _IOC_DIR(cmd) { + let res = match _IOC_DIR(cmd) { _IOC_WRITE => Self::ioctl_write_only(this, file, cmd, &mut user_slice.reader()), _IOC_READ_WRITE => Self::ioctl_write_read(this, file, cmd, user_slice), _ => Err(EINVAL), - } + }; + + crate::trace::trace_ioctl_done(res); + res } pub(crate) fn mmap( diff --git a/drivers/android/binder/rust_binder_events.h b/drivers/android/binder/rust_binder_events.h index e3adfb93170d..4fda8576c01f 100644 --- a/drivers/android/binder/rust_binder_events.h +++ b/drivers/android/binder/rust_binder_events.h @@ -30,6 +30,27 @@ TRACE_EVENT(binder_ioctl, TP_printk("cmd=0x%x arg=0x%lx", __entry->cmd, __entry->arg) ); +DECLARE_EVENT_CLASS(binder_function_return_class, + TP_PROTO(int ret), + TP_ARGS(ret), + TP_STRUCT__entry( + __field(int, ret) + ), + TP_fast_assign( + __entry->ret = ret; + ), + TP_printk("ret=%d", __entry->ret) +); + +#define DEFINE_RBINDER_FUNCTION_RETURN_EVENT(name) \ +DEFINE_EVENT(binder_function_return_class, name, \ + TP_PROTO(int ret), \ + TP_ARGS(ret)) + +DEFINE_RBINDER_FUNCTION_RETURN_EVENT(binder_ioctl_done); +DEFINE_RBINDER_FUNCTION_RETURN_EVENT(binder_read_done); +DEFINE_RBINDER_FUNCTION_RETURN_EVENT(binder_write_done); + TRACE_EVENT(binder_transaction, TP_PROTO(bool reply, rust_binder_transaction t, struct task_struct *thread), TP_ARGS(reply, t, thread), diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thread.rs index 97a5e4acf64c..138c45cecfa0 100644 --- a/drivers/android/binder/thread.rs +++ b/drivers/android/binder/thread.rs @@ -1507,6 +1507,7 @@ impl Thread { let mut ret = Ok(()); if req.write_size > 0 { ret = self.write(&mut req); + crate::trace::trace_write_done(ret); if let Err(err) = ret { pr_warn!( "Write failure {:?} in pid:{}", @@ -1523,6 +1524,7 @@ impl Thread { // Go through the work queue. if req.read_size > 0 { ret = self.read(&mut req, wait); + crate::trace::trace_read_done(ret); if ret.is_err() && ret != Err(EINTR) { pr_warn!( "Read failure {:?} in pid:{}", diff --git a/drivers/android/binder/trace.rs b/drivers/android/binder/trace.rs index d54b18ab71a8..3b0458e2738c 100644 --- a/drivers/android/binder/trace.rs +++ b/drivers/android/binder/trace.rs @@ -5,12 +5,16 @@ use crate::transaction::Transaction; use kernel::bindings::{rust_binder_transaction, task_struct}; -use kernel::ffi::{c_uint, c_ulong}; +use kernel::error::Result; +use kernel::ffi::{c_int, c_uint, c_ulong}; use kernel::task::Task; use kernel::tracepoint::declare_trace; declare_trace! { unsafe fn binder_ioctl(cmd: c_uint, arg: c_ulong); + unsafe fn binder_ioctl_done(ret: c_int); + unsafe fn binder_read_done(ret: c_int); + unsafe fn binder_write_done(ret: c_int); unsafe fn binder_transaction(reply: bool, t: rust_binder_transaction, thread: *mut task_struct); } @@ -19,12 +23,36 @@ fn raw_transaction(t: &Transaction) -> rust_binder_transaction { t as *const Transaction as rust_binder_transaction } +#[inline] +fn to_errno(ret: Result) -> i32 { + match ret { + Ok(()) => 0, + Err(err) => err.to_errno(), + } +} + #[inline] pub(crate) fn trace_ioctl(cmd: u32, arg: usize) { // SAFETY: Always safe to call. unsafe { binder_ioctl(cmd, arg as c_ulong) } } +#[inline] +pub(crate) fn trace_ioctl_done(ret: Result) { + // SAFETY: Always safe to call. + unsafe { binder_ioctl_done(to_errno(ret)) } +} +#[inline] +pub(crate) fn trace_read_done(ret: Result) { + // SAFETY: Always safe to call. + unsafe { binder_read_done(to_errno(ret)) } +} +#[inline] +pub(crate) fn trace_write_done(ret: Result) { + // SAFETY: Always safe to call. + unsafe { binder_write_done(to_errno(ret)) } +} + #[inline] pub(crate) fn trace_transaction(reply: bool, t: &Transaction, thread: Option<&Task>) { let thread = match thread {