* [PATCH v2 1/3] rust_binder: remove "rust_" prefix from tracepoints
2026-03-08 1:24 [PATCH v2 0/3] rust_binder: add and wire Binder tracepoints Mohamad Alsadhan
@ 2026-03-08 1:24 ` Mohamad Alsadhan
2026-03-16 14:10 ` Alice Ryhl
2026-03-08 1:24 ` [PATCH v2 2/3] rust_binder: add Rust binder tracepoints Mohamad Alsadhan
2026-03-08 1:24 ` [PATCH v2 3/3] rust_binder: add in the new tracepoint calls Mohamad Alsadhan
2 siblings, 1 reply; 6+ messages in thread
From: Mohamad Alsadhan @ 2026-03-08 1:24 UTC (permalink / raw)
To: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
Christian Brauner, Carlos Llamas, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich
Cc: Alice Ryhl, linux-kernel, rust-for-linux, Mohamad Alsadhan
Remove the "rust_" prefix as the name is part of the uapi, and
userspace expects tracepoints to have the old names.
Link: https://github.com/Rust-for-Linux/linux/issues/1226
Suggested-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Mohamad Alsadhan <mo@sdhn.cc>
---
drivers/android/binder/rust_binder_events.h | 4 ++--
drivers/android/binder/trace.rs | 8 ++++----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/android/binder/rust_binder_events.h b/drivers/android/binder/rust_binder_events.h
index 8ad785c6b..e3adfb931 100644
--- a/drivers/android/binder/rust_binder_events.h
+++ b/drivers/android/binder/rust_binder_events.h
@@ -15,7 +15,7 @@
#include <linux/tracepoint.h>
-TRACE_EVENT(rust_binder_ioctl,
+TRACE_EVENT(binder_ioctl,
TP_PROTO(unsigned int cmd, unsigned long arg),
TP_ARGS(cmd, arg),
@@ -30,7 +30,7 @@ TRACE_EVENT(rust_binder_ioctl,
TP_printk("cmd=0x%x arg=0x%lx", __entry->cmd, __entry->arg)
);
-TRACE_EVENT(rust_binder_transaction,
+TRACE_EVENT(binder_transaction,
TP_PROTO(bool reply, rust_binder_transaction t, struct task_struct *thread),
TP_ARGS(reply, t, thread),
TP_STRUCT__entry(
diff --git a/drivers/android/binder/trace.rs b/drivers/android/binder/trace.rs
index 9839901c7..d54b18ab7 100644
--- a/drivers/android/binder/trace.rs
+++ b/drivers/android/binder/trace.rs
@@ -10,8 +10,8 @@
use kernel::tracepoint::declare_trace;
declare_trace! {
- unsafe fn rust_binder_ioctl(cmd: c_uint, arg: c_ulong);
- unsafe fn rust_binder_transaction(reply: bool, t: rust_binder_transaction, thread: *mut task_struct);
+ unsafe fn binder_ioctl(cmd: c_uint, arg: c_ulong);
+ unsafe fn binder_transaction(reply: bool, t: rust_binder_transaction, thread: *mut task_struct);
}
#[inline]
@@ -22,7 +22,7 @@ fn raw_transaction(t: &Transaction) -> rust_binder_transaction {
#[inline]
pub(crate) fn trace_ioctl(cmd: u32, arg: usize) {
// SAFETY: Always safe to call.
- unsafe { rust_binder_ioctl(cmd, arg as c_ulong) }
+ unsafe { binder_ioctl(cmd, arg as c_ulong) }
}
#[inline]
@@ -33,5 +33,5 @@ pub(crate) fn trace_transaction(reply: bool, t: &Transaction, thread: Option<&Ta
};
// SAFETY: The raw transaction is valid for the duration of this call. The thread pointer is
// valid or null.
- unsafe { rust_binder_transaction(reply, raw_transaction(t), thread) }
+ unsafe { binder_transaction(reply, raw_transaction(t), thread) }
}
--
2.52.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v2 2/3] rust_binder: add Rust binder tracepoints
2026-03-08 1:24 [PATCH v2 0/3] rust_binder: add and wire Binder tracepoints Mohamad Alsadhan
2026-03-08 1:24 ` [PATCH v2 1/3] rust_binder: remove "rust_" prefix from tracepoints Mohamad Alsadhan
@ 2026-03-08 1:24 ` Mohamad Alsadhan
2026-03-08 1:24 ` [PATCH v2 3/3] rust_binder: add in the new tracepoint calls Mohamad Alsadhan
2 siblings, 0 replies; 6+ messages in thread
From: Mohamad Alsadhan @ 2026-03-08 1:24 UTC (permalink / raw)
To: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
Christian Brauner, Carlos Llamas, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich
Cc: Alice Ryhl, linux-kernel, rust-for-linux, Mohamad Alsadhan
New tracepoints: `{ioctl,read,write}_done`, `wait_for_work`,
`transaction_received`, `transaction_fd_{send,recv}`,
`{alloc,free}_lru_{start,end}`, `alloc_page_{start,end}`,
`unmap_{user,kernel}_{start,end}`, `command` and `return`.
Link: https://github.com/Rust-for-Linux/linux/issues/1226
Suggested-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Mohamad Alsadhan <mo@sdhn.cc>
---
drivers/android/binder/rust_binder.h | 5 +
drivers/android/binder/rust_binder_events.h | 172 ++++++++++++++++++++++++++++
drivers/android/binder/trace.rs | 109 +++++++++++++++++-
3 files changed, 284 insertions(+), 2 deletions(-)
diff --git a/drivers/android/binder/rust_binder.h b/drivers/android/binder/rust_binder.h
index d2284726c..3936b9d0b 100644
--- a/drivers/android/binder/rust_binder.h
+++ b/drivers/android/binder/rust_binder.h
@@ -99,4 +99,9 @@ static inline size_t rust_binder_node_debug_id(rust_binder_node t)
return *(size_t *) (t + RUST_BINDER_LAYOUT.n.debug_id);
}
+static inline binder_uintptr_t rust_binder_node_ptr(rust_binder_node t)
+{
+ return *(binder_uintptr_t *) (t + RUST_BINDER_LAYOUT.n.ptr);
+}
+
#endif
diff --git a/drivers/android/binder/rust_binder_events.h b/drivers/android/binder/rust_binder_events.h
index e3adfb931..6725453f5 100644
--- a/drivers/android/binder/rust_binder_events.h
+++ b/drivers/android/binder/rust_binder_events.h
@@ -30,6 +30,45 @@ 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_wait_for_work,
+ TP_PROTO(bool proc_work, bool transaction_stack, bool thread_todo),
+ TP_ARGS(proc_work, transaction_stack, thread_todo),
+ TP_STRUCT__entry(
+ __field(bool, proc_work)
+ __field(bool, transaction_stack)
+ __field(bool, thread_todo)
+ ),
+ TP_fast_assign(
+ __entry->proc_work = proc_work;
+ __entry->transaction_stack = transaction_stack;
+ __entry->thread_todo = thread_todo;
+ ),
+ TP_printk("proc_work=%d transaction_stack=%d thread_todo=%d",
+ __entry->proc_work, __entry->transaction_stack,
+ __entry->thread_todo)
+);
+
TRACE_EVENT(binder_transaction,
TP_PROTO(bool reply, rust_binder_transaction t, struct task_struct *thread),
TP_ARGS(reply, t, thread),
@@ -60,6 +99,139 @@ TRACE_EVENT(binder_transaction,
__entry->reply, __entry->flags, __entry->code)
);
+TRACE_EVENT(binder_transaction_received,
+ TP_PROTO(rust_binder_transaction t),
+ TP_ARGS(t),
+ TP_STRUCT__entry(
+ __field(int, debug_id)
+ ),
+ TP_fast_assign(
+ __entry->debug_id = rust_binder_transaction_debug_id(t);
+ ),
+ TP_printk("transaction=%d", __entry->debug_id)
+);
+
+TRACE_EVENT(binder_transaction_fd_send,
+ TP_PROTO(int t_debug_id, int fd, size_t offset),
+ TP_ARGS(t_debug_id, fd, offset),
+ TP_STRUCT__entry(
+ __field(int, debug_id)
+ __field(int, fd)
+ __field(size_t, offset)
+ ),
+ TP_fast_assign(
+ __entry->debug_id = t_debug_id;
+ __entry->fd = fd;
+ __entry->offset = offset;
+ ),
+ TP_printk("transaction=%d src_fd=%d offset=%zu",
+ __entry->debug_id, __entry->fd, __entry->offset)
+);
+
+TRACE_EVENT(binder_transaction_fd_recv,
+ TP_PROTO(int t_debug_id, int fd, size_t offset),
+ TP_ARGS(t_debug_id, fd, offset),
+ TP_STRUCT__entry(
+ __field(int, debug_id)
+ __field(int, fd)
+ __field(size_t, offset)
+ ),
+ TP_fast_assign(
+ __entry->debug_id = t_debug_id;
+ __entry->fd = fd;
+ __entry->offset = offset;
+ ),
+ TP_printk("transaction=%d dest_fd=%d offset=%zu",
+ __entry->debug_id, __entry->fd, __entry->offset)
+);
+
+DECLARE_EVENT_CLASS(binder_lru_page_class,
+ TP_PROTO(int pid, size_t page_index),
+ TP_ARGS(pid, page_index),
+ TP_STRUCT__entry(
+ __field(int, proc)
+ __field(size_t, page_index)
+ ),
+ TP_fast_assign(
+ __entry->proc = pid;
+ __entry->page_index = page_index;
+ ),
+ TP_printk("proc=%d page_index=%zu",
+ __entry->proc, __entry->page_index)
+);
+
+DEFINE_EVENT(binder_lru_page_class, binder_alloc_lru_start,
+ TP_PROTO(int pid, size_t page_index),
+ TP_ARGS(pid, page_index));
+
+DEFINE_EVENT(binder_lru_page_class, binder_alloc_lru_end,
+ TP_PROTO(int pid, size_t page_index),
+ TP_ARGS(pid, page_index));
+
+DEFINE_EVENT(binder_lru_page_class, binder_free_lru_start,
+ TP_PROTO(int pid, size_t page_index),
+ TP_ARGS(pid, page_index));
+
+DEFINE_EVENT(binder_lru_page_class, binder_free_lru_end,
+ TP_PROTO(int pid, size_t page_index),
+ TP_ARGS(pid, page_index));
+
+DEFINE_EVENT(binder_lru_page_class, binder_alloc_page_start,
+ TP_PROTO(int pid, size_t page_index),
+ TP_ARGS(pid, page_index));
+
+DEFINE_EVENT(binder_lru_page_class, binder_alloc_page_end,
+ TP_PROTO(int pid, size_t page_index),
+ TP_ARGS(pid, page_index));
+
+DEFINE_EVENT(binder_lru_page_class, binder_unmap_user_start,
+ TP_PROTO(int pid, size_t page_index),
+ TP_ARGS(pid, page_index));
+
+DEFINE_EVENT(binder_lru_page_class, binder_unmap_user_end,
+ TP_PROTO(int pid, size_t page_index),
+ TP_ARGS(pid, page_index));
+
+DEFINE_EVENT(binder_lru_page_class, binder_unmap_kernel_start,
+ TP_PROTO(int pid, size_t page_index),
+ TP_ARGS(pid, page_index));
+
+DEFINE_EVENT(binder_lru_page_class, binder_unmap_kernel_end,
+ TP_PROTO(int pid, size_t page_index),
+ TP_ARGS(pid, page_index));
+
+TRACE_EVENT(binder_command,
+ TP_PROTO(uint32_t cmd),
+ TP_ARGS(cmd),
+ TP_STRUCT__entry(
+ __field(uint32_t, cmd)
+ ),
+ TP_fast_assign(
+ __entry->cmd = cmd;
+ ),
+ TP_printk("cmd=0x%x %s",
+ __entry->cmd,
+ _IOC_NR(__entry->cmd) < ARRAY_SIZE(binder_command_strings) ?
+ binder_command_strings[_IOC_NR(__entry->cmd)] :
+ "unknown")
+);
+
+TRACE_EVENT(binder_return,
+ TP_PROTO(uint32_t cmd),
+ TP_ARGS(cmd),
+ TP_STRUCT__entry(
+ __field(uint32_t, cmd)
+ ),
+ TP_fast_assign(
+ __entry->cmd = cmd;
+ ),
+ TP_printk("cmd=0x%x %s",
+ __entry->cmd,
+ _IOC_NR(__entry->cmd) < ARRAY_SIZE(binder_return_strings) ?
+ binder_return_strings[_IOC_NR(__entry->cmd)] :
+ "unknown")
+);
+
#endif /* _RUST_BINDER_TRACE_H */
/* This part must be outside protection */
diff --git a/drivers/android/binder/trace.rs b/drivers/android/binder/trace.rs
index d54b18ab7..8bfe7f882 100644
--- a/drivers/android/binder/trace.rs
+++ b/drivers/android/binder/trace.rs
@@ -5,13 +5,33 @@
use crate::transaction::Transaction;
use kernel::bindings::{rust_binder_transaction, task_struct};
-use kernel::ffi::{c_uint, c_ulong};
-use kernel::task::Task;
+use kernel::error::Result;
+use kernel::ffi::{c_int, c_uint, c_ulong};
+use kernel::task::{Pid, 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_wait_for_work(proc_work: bool, transaction_stack: bool, thread_todo: bool);
unsafe fn binder_transaction(reply: bool, t: rust_binder_transaction, thread: *mut task_struct);
+ unsafe fn binder_transaction_received(t: rust_binder_transaction);
+ unsafe fn binder_transaction_fd_send(t_debug_id: c_int, fd: c_int, offset: usize);
+ unsafe fn binder_transaction_fd_recv(t_debug_id: c_int, fd: c_int, offset: usize);
+ unsafe fn binder_alloc_lru_start(pid: c_int, page_index: usize);
+ unsafe fn binder_alloc_lru_end(pid: c_int, page_index: usize);
+ unsafe fn binder_free_lru_start(pid: c_int, page_index: usize);
+ unsafe fn binder_free_lru_end(pid: c_int, page_index: usize);
+ unsafe fn binder_alloc_page_start(pid: c_int, page_index: usize);
+ unsafe fn binder_alloc_page_end(pid: c_int, page_index: usize);
+ unsafe fn binder_unmap_user_start(pid: c_int, page_index: usize);
+ unsafe fn binder_unmap_user_end(pid: c_int, page_index: usize);
+ unsafe fn binder_unmap_kernel_start(pid: c_int, page_index: usize);
+ unsafe fn binder_unmap_kernel_end(pid: c_int, page_index: usize);
+ unsafe fn binder_command(cmd: u32);
+ unsafe fn binder_return(ret: u32);
}
#[inline]
@@ -19,12 +39,42 @@ 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_wait_for_work(proc_work: bool, transaction_stack: bool, thread_todo: bool) {
+ // SAFETY: Always safe to call.
+ unsafe { binder_wait_for_work(proc_work, transaction_stack, thread_todo) }
+}
+
#[inline]
pub(crate) fn trace_transaction(reply: bool, t: &Transaction, thread: Option<&Task>) {
let thread = match thread {
@@ -35,3 +85,58 @@ pub(crate) fn trace_transaction(reply: bool, t: &Transaction, thread: Option<&Ta
// valid or null.
unsafe { binder_transaction(reply, raw_transaction(t), thread) }
}
+
+#[inline]
+pub(crate) fn trace_transaction_received(t: &Transaction) {
+ // SAFETY: The raw transaction is valid for the duration of this call.
+ unsafe { binder_transaction_received(raw_transaction(t)) }
+}
+
+#[inline]
+pub(crate) fn trace_transaction_fd_send(t_debug_id: usize, fd: u32, offset: usize) {
+ // SAFETY: This function is always safe to call.
+ unsafe { binder_transaction_fd_send(t_debug_id as c_int, fd as c_int, offset) }
+}
+#[inline]
+pub(crate) fn trace_transaction_fd_recv(t_debug_id: usize, fd: u32, offset: usize) {
+ // SAFETY: This function is always safe to call.
+ unsafe { binder_transaction_fd_recv(t_debug_id as c_int, fd as c_int, offset) }
+}
+
+macro_rules! define_wrapper_lru_page_class {
+ ($($name:ident),* $(,)?) => {
+ $(
+ kernel::macros::paste! {
+ #[inline]
+ pub(crate) fn [<trace_ $name>](pid: Pid, page_index: usize) {
+ // SAFETY: Always safe to call.
+ unsafe { [<binder_ $name>](pid as c_int, page_index) }
+ }
+ }
+ )*
+ };
+}
+
+define_wrapper_lru_page_class!(
+ alloc_lru_start,
+ alloc_lru_end,
+ free_lru_start,
+ free_lru_end,
+ alloc_page_start,
+ alloc_page_end,
+ unmap_user_start,
+ unmap_user_end,
+ unmap_kernel_start,
+ unmap_kernel_end,
+);
+
+#[inline]
+pub(crate) fn trace_command(cmd: u32) {
+ // SAFETY: This function is always safe to call.
+ unsafe { binder_command(cmd) }
+}
+#[inline]
+pub(crate) fn trace_return(ret: u32) {
+ // SAFETY: This function is always safe to call.
+ unsafe { binder_return(ret) }
+}
--
2.52.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v2 3/3] rust_binder: add in the new tracepoint calls
2026-03-08 1:24 [PATCH v2 0/3] rust_binder: add and wire Binder tracepoints Mohamad Alsadhan
2026-03-08 1:24 ` [PATCH v2 1/3] rust_binder: remove "rust_" prefix from tracepoints Mohamad Alsadhan
2026-03-08 1:24 ` [PATCH v2 2/3] rust_binder: add Rust binder tracepoints Mohamad Alsadhan
@ 2026-03-08 1:24 ` Mohamad Alsadhan
2026-03-16 14:12 ` Alice Ryhl
2 siblings, 1 reply; 6+ messages in thread
From: Mohamad Alsadhan @ 2026-03-08 1:24 UTC (permalink / raw)
To: Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
Christian Brauner, Carlos Llamas, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Danilo Krummrich
Cc: Alice Ryhl, linux-kernel, rust-for-linux, Mohamad Alsadhan
Wire the new Rust Binder tracepoints into live execution paths.
Hook trace calls into:
- ioctl entry/exit (`binder_ioctl`, `binder_ioctl_done`)
- command parsing and return writes (`binder_command`,
`binder_return`)
- read/write completion (`binder_read_done`, `binder_write_done`)
- wait (`binder_wait_for_work`)
- transaction (`binder_transaction_received`)
- fd translation (`binder_transaction_fd_{send,recv}`)
- buffer/page lifecycle (`binder_alloc_*`, `binder_free_*`,
`binder_unmap_*`)
Signed-off-by: Mohamad Alsadhan <mo@sdhn.cc>
---
drivers/android/binder/allocation.rs | 1 +
drivers/android/binder/page_range.rs | 17 +++++++++++++++++
drivers/android/binder/process.rs | 7 +++++--
drivers/android/binder/rust_binder_main.rs | 1 +
drivers/android/binder/thread.rs | 15 +++++++++++++--
drivers/android/binder/transaction.rs | 2 ++
6 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/drivers/android/binder/allocation.rs b/drivers/android/binder/allocation.rs
index 7f65a9c3a..8c0f94463 100644
--- a/drivers/android/binder/allocation.rs
+++ b/drivers/android/binder/allocation.rs
@@ -208,6 +208,7 @@ pub(crate) fn translate_fds(&mut self) -> Result<TranslatedFds> {
let res = FileDescriptorReservation::get_unused_fd_flags(bindings::O_CLOEXEC)?;
let fd = res.reserved_fd();
self.write::<u32>(file_info.buffer_offset, &fd)?;
+ crate::trace::trace_transaction_fd_recv(self.debug_id, fd, file_info.buffer_offset);
reservations.push(
Reservation {
diff --git a/drivers/android/binder/page_range.rs b/drivers/android/binder/page_range.rs
index fdd97112e..43fe23907 100644
--- a/drivers/android/binder/page_range.rs
+++ b/drivers/android/binder/page_range.rs
@@ -327,6 +327,8 @@ pub(crate) fn use_range(&self, start: usize, end: usize) -> Result<()> {
// SAFETY: The pointer is valid, and we hold the lock so reading from the page is okay.
if let Some(page) = unsafe { PageInfo::get_page(page_info) } {
+ crate::trace::trace_alloc_lru_start(self.pid, i);
+
// Since we're going to use the page, we should remove it from the lru list so that
// the shrinker will not free it.
//
@@ -335,9 +337,12 @@ pub(crate) fn use_range(&self, start: usize, end: usize) -> Result<()> {
// The shrinker can't free the page between the check and this call to
// `list_lru_del` because we hold the lock.
unsafe { PageInfo::list_lru_del(page_info, page.nid(), self.shrinker) };
+
+ crate::trace::trace_alloc_lru_end(self.pid, i);
} else {
// We have to allocate a new page. Use the slow path.
drop(inner);
+ crate::trace::trace_alloc_page_start(self.pid, i);
// SAFETY: `i < end <= inner.size` so `i` is in bounds.
match unsafe { self.use_page_slow(i) } {
Ok(()) => {}
@@ -346,6 +351,7 @@ pub(crate) fn use_range(&self, start: usize, end: usize) -> Result<()> {
return Err(err);
}
}
+ crate::trace::trace_alloc_page_end(self.pid, i);
inner = self.lock.lock();
}
}
@@ -448,8 +454,12 @@ pub(crate) fn stop_using_range(&self, start: usize, end: usize) {
// SAFETY: Okay for reading since we have the lock.
if let Some(page) = unsafe { PageInfo::get_page(page_info) } {
+ crate::trace::trace_free_lru_start(self.pid, i);
+
// SAFETY: The pointer is valid, and it's the right shrinker.
unsafe { PageInfo::list_lru_add(page_info, page.nid(), self.shrinker) };
+
+ crate::trace::trace_free_lru_end(self.pid, i);
}
}
}
@@ -667,6 +677,7 @@ fn drop(self: Pin<&mut Self>) {
let mmap_read;
let mm_mutex;
let vma_addr;
+ let pid;
{
// CAST: The `list_head` field is first in `PageInfo`.
@@ -700,7 +711,9 @@ fn drop(self: Pin<&mut Self>) {
// SAFETY: Both pointers are in bounds of the same allocation.
page_index = unsafe { info.offset_from(inner.pages) } as usize;
+ pid = range.pid;
+ crate::trace::trace_unmap_kernel_start(pid, page_index);
// SAFETY: We hold the spinlock, so we can take the page.
//
// This sets the page pointer to zero before we unmap it from the vma. However, we call
@@ -709,6 +722,8 @@ fn drop(self: Pin<&mut Self>) {
page = unsafe { PageInfo::take_page(info) };
vma_addr = inner.vma_addr;
+ crate::trace::trace_unmap_kernel_end(pid, page_index);
+
// From this point on, we don't access this PageInfo or ShrinkablePageRange again, because
// they can be freed at any point after we unlock `lru_lock`. This is with the exception of
// `mm_mutex` which is kept alive by holding the lock.
@@ -719,7 +734,9 @@ fn drop(self: Pin<&mut Self>) {
if let Some(vma) = mmap_read.vma_lookup(vma_addr) {
let user_page_addr = vma_addr + (page_index << PAGE_SHIFT);
+ crate::trace::trace_unmap_user_start(pid, page_index);
vma.zap_page_range_single(user_page_addr, PAGE_SIZE);
+ crate::trace::trace_unmap_user_end(pid, page_index);
}
drop(mmap_read);
diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/process.rs
index 41de55931..4d7b165e7 100644
--- a/drivers/android/binder/process.rs
+++ b/drivers/android/binder/process.rs
@@ -1656,11 +1656,14 @@ pub(crate) fn ioctl(this: ArcBorrow<'_, Process>, file: &File, cmd: u32, arg: us
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_main.rs b/drivers/android/binder/rust_binder_main.rs
index aa5f2a75a..1028e0a8a 100644
--- a/drivers/android/binder/rust_binder_main.rs
+++ b/drivers/android/binder/rust_binder_main.rs
@@ -116,6 +116,7 @@ fn new(writer: UserSliceWriter, thread: &'a Thread) -> Self {
/// Write a return code back to user space.
/// Should be a `BR_` constant from [`defs`] e.g. [`defs::BR_TRANSACTION_COMPLETE`].
fn write_code(&mut self, code: u32) -> Result {
+ crate::trace::trace_return(code);
stats::GLOBAL_STATS.inc_br(code);
self.thread.process.stats.inc_br(code);
self.writer.write(&code)
diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thread.rs
index 0b62d24b2..ef7fba700 100644
--- a/drivers/android/binder/thread.rs
+++ b/drivers/android/binder/thread.rs
@@ -706,6 +706,7 @@ fn translate_object(
core::mem::offset_of!(uapi::binder_fd_object, __bindgen_anon_1.fd);
let field_offset = offset + FD_FIELD_OFFSET;
+ crate::trace::trace_transaction_fd_send(view.alloc.debug_id, fd, field_offset);
view.alloc.info_add_fd(file, field_offset, false)?;
}
@@ -1323,6 +1324,7 @@ fn write(self: &Arc<Self>, req: &mut BinderWriteRead) -> Result {
while reader.len() >= size_of::<u32>() && self.inner.lock().return_work.is_unused() {
let before = reader.len();
let cmd = reader.read::<u32>()?;
+ crate::trace::trace_command(cmd);
GLOBAL_STATS.inc_bc(cmd);
self.process.stats.inc_bc(cmd);
match cmd {
@@ -1412,11 +1414,18 @@ fn read(self: &Arc<Self>, req: &mut BinderWriteRead, wait: bool) -> Result {
UserSlice::new(UserPtr::from_addr(read_start as _), read_len as _).writer(),
self,
);
- let (in_pool, use_proc_queue) = {
+ let (in_pool, has_transaction, thread_todo, use_proc_queue) = {
let inner = self.inner.lock();
- (inner.is_looper(), inner.should_use_process_work_queue())
+ (
+ inner.is_looper(),
+ inner.current_transaction.is_some(),
+ !inner.work_list.is_empty(),
+ inner.should_use_process_work_queue(),
+ )
};
+ crate::trace::trace_wait_for_work(use_proc_queue, has_transaction, thread_todo);
+
let getter = if use_proc_queue {
Self::get_work
} else {
@@ -1482,6 +1491,7 @@ pub(crate) fn write_read(self: &Arc<Self>, data: UserSlice, wait: bool) -> Resul
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:{}",
@@ -1498,6 +1508,7 @@ pub(crate) fn write_read(self: &Arc<Self>, data: UserSlice, wait: bool) -> Resul
// 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/transaction.rs b/drivers/android/binder/transaction.rs
index 75e6f5fba..c43846bb7 100644
--- a/drivers/android/binder/transaction.rs
+++ b/drivers/android/binder/transaction.rs
@@ -430,6 +430,8 @@ fn do_work(
self.drop_outstanding_txn();
+ crate::trace::trace_transaction_received(&self);
+
// When this is not a reply and not a oneway transaction, update `current_transaction`. If
// it's a reply, `current_transaction` has already been updated appropriately.
if self.target_node.is_some() && tr_sec.transaction_data.flags & TF_ONE_WAY == 0 {
--
2.52.0
^ permalink raw reply related [flat|nested] 6+ messages in thread