Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <mo@sdhn.cc>
Link: https://patch.msgid.link/20260317-rust-binder-trace-v3-2-6fae4fbcf637@sdhn.cc
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Mohamad Alsadhan and committed by
Greg Kroah-Hartman
be3953bb e3007a92

+57 -3
+5 -2
drivers/android/binder/process.rs
··· 1659 1659 1660 1660 const _IOC_READ_WRITE: u32 = _IOC_READ | _IOC_WRITE; 1661 1661 1662 - match _IOC_DIR(cmd) { 1662 + let res = match _IOC_DIR(cmd) { 1663 1663 _IOC_WRITE => Self::ioctl_write_only(this, file, cmd, &mut user_slice.reader()), 1664 1664 _IOC_READ_WRITE => Self::ioctl_write_read(this, file, cmd, user_slice), 1665 1665 _ => Err(EINVAL), 1666 - } 1666 + }; 1667 + 1668 + crate::trace::trace_ioctl_done(res); 1669 + res 1667 1670 } 1668 1671 1669 1672 pub(crate) fn mmap(
+21
drivers/android/binder/rust_binder_events.h
··· 30 30 TP_printk("cmd=0x%x arg=0x%lx", __entry->cmd, __entry->arg) 31 31 ); 32 32 33 + DECLARE_EVENT_CLASS(binder_function_return_class, 34 + TP_PROTO(int ret), 35 + TP_ARGS(ret), 36 + TP_STRUCT__entry( 37 + __field(int, ret) 38 + ), 39 + TP_fast_assign( 40 + __entry->ret = ret; 41 + ), 42 + TP_printk("ret=%d", __entry->ret) 43 + ); 44 + 45 + #define DEFINE_RBINDER_FUNCTION_RETURN_EVENT(name) \ 46 + DEFINE_EVENT(binder_function_return_class, name, \ 47 + TP_PROTO(int ret), \ 48 + TP_ARGS(ret)) 49 + 50 + DEFINE_RBINDER_FUNCTION_RETURN_EVENT(binder_ioctl_done); 51 + DEFINE_RBINDER_FUNCTION_RETURN_EVENT(binder_read_done); 52 + DEFINE_RBINDER_FUNCTION_RETURN_EVENT(binder_write_done); 53 + 33 54 TRACE_EVENT(binder_transaction, 34 55 TP_PROTO(bool reply, rust_binder_transaction t, struct task_struct *thread), 35 56 TP_ARGS(reply, t, thread),
+2
drivers/android/binder/thread.rs
··· 1507 1507 let mut ret = Ok(()); 1508 1508 if req.write_size > 0 { 1509 1509 ret = self.write(&mut req); 1510 + crate::trace::trace_write_done(ret); 1510 1511 if let Err(err) = ret { 1511 1512 pr_warn!( 1512 1513 "Write failure {:?} in pid:{}", ··· 1524 1523 // Go through the work queue. 1525 1524 if req.read_size > 0 { 1526 1525 ret = self.read(&mut req, wait); 1526 + crate::trace::trace_read_done(ret); 1527 1527 if ret.is_err() && ret != Err(EINTR) { 1528 1528 pr_warn!( 1529 1529 "Read failure {:?} in pid:{}",
+29 -1
drivers/android/binder/trace.rs
··· 5 5 use crate::transaction::Transaction; 6 6 7 7 use kernel::bindings::{rust_binder_transaction, task_struct}; 8 - use kernel::ffi::{c_uint, c_ulong}; 8 + use kernel::error::Result; 9 + use kernel::ffi::{c_int, c_uint, c_ulong}; 9 10 use kernel::task::Task; 10 11 use kernel::tracepoint::declare_trace; 11 12 12 13 declare_trace! { 13 14 unsafe fn binder_ioctl(cmd: c_uint, arg: c_ulong); 15 + unsafe fn binder_ioctl_done(ret: c_int); 16 + unsafe fn binder_read_done(ret: c_int); 17 + unsafe fn binder_write_done(ret: c_int); 14 18 unsafe fn binder_transaction(reply: bool, t: rust_binder_transaction, thread: *mut task_struct); 15 19 } 16 20 ··· 24 20 } 25 21 26 22 #[inline] 23 + fn to_errno(ret: Result) -> i32 { 24 + match ret { 25 + Ok(()) => 0, 26 + Err(err) => err.to_errno(), 27 + } 28 + } 29 + 30 + #[inline] 27 31 pub(crate) fn trace_ioctl(cmd: u32, arg: usize) { 28 32 // SAFETY: Always safe to call. 29 33 unsafe { binder_ioctl(cmd, arg as c_ulong) } 34 + } 35 + 36 + #[inline] 37 + pub(crate) fn trace_ioctl_done(ret: Result) { 38 + // SAFETY: Always safe to call. 39 + unsafe { binder_ioctl_done(to_errno(ret)) } 40 + } 41 + #[inline] 42 + pub(crate) fn trace_read_done(ret: Result) { 43 + // SAFETY: Always safe to call. 44 + unsafe { binder_read_done(to_errno(ret)) } 45 + } 46 + #[inline] 47 + pub(crate) fn trace_write_done(ret: Result) { 48 + // SAFETY: Always safe to call. 49 + unsafe { binder_write_done(to_errno(ret)) } 30 50 } 31 51 32 52 #[inline]