From 02ea01fd0f09f7ea81b1087582da0dabeebb265c Mon Sep 17 00:00:00 2001 From: zhengding chen Date: Wed, 28 Apr 2021 19:24:57 +0800 Subject: [PATCH] ANDROID: vendor_hooks: Add hooks for binder proc transaction When servicemanager process added service proxy from other process register the service, we want to know the matching relation between handle in the process and service name. When binder transaction happened, We want to know what process calls what method on what service. Patch 3482670 was uploaded in this patchset to avoid conflict. Bug: 186604985 Bug: 395737475 Signed-off-by: zhengding chen Change-Id: I813d1cde10294d8665f899f7fef0d444ec1f1f5e Signed-off-by: shenshen mao Signed-off-by: xiaosa liang --- drivers/android/binder.c | 31 ++++++++++++++++++++++++++----- drivers/android/vendor_hooks.c | 7 +++++++ include/trace/hooks/binder.h | 33 ++++++++++++++++++++++++++++++--- 3 files changed, 63 insertions(+), 8 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 84086a181d2a..b00ebe1660a0 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -553,10 +553,12 @@ static void binder_inc_node_tmpref_ilocked(struct binder_node *node); static bool binder_has_work_ilocked(struct binder_thread *thread, bool do_proc_work) { - return thread->process_todo || + bool has_work = thread->process_todo || thread->looper_need_return || (do_proc_work && - !binder_worklist_empty_ilocked(&thread->proc->todo)); + !binder_worklist_empty_ilocked(&thread->proc->todo)); + trace_android_vh_binder_has_special_work_ilocked(thread, do_proc_work, &has_work); + return has_work; } static bool binder_has_work(struct binder_thread *thread, bool do_proc_work) @@ -3061,6 +3063,10 @@ static int binder_proc_transaction(struct binder_transaction *t, if (!thread && !pending_async) thread = binder_select_thread_ilocked(proc); + trace_android_vh_binder_proc_transaction(current, proc->tsk, + thread ? thread->task : NULL, node->debug_id, t, + pending_async); + if (thread) { binder_transaction_priority(thread, t, node); binder_enqueue_thread_work_ilocked(thread, &t->work); @@ -4519,6 +4525,7 @@ static int binder_thread_write(struct binder_proc *proc, thread->looper |= BINDER_LOOPER_STATE_ENTERED; break; case BC_EXIT_LOOPER: + trace_android_vh_binder_looper_exited(thread, proc); binder_debug(BINDER_DEBUG_THREADS, "%d:%d BC_EXIT_LOOPER\n", proc->pid, thread->pid); @@ -4884,6 +4891,8 @@ static int binder_thread_read(struct binder_proc *proc, void __user *end = buffer + size; int ret = 0; + bool nothing_to_do = false; + bool force_spawn = false; int wait_for_proc_work; if (*consumed == 0) { @@ -4937,12 +4946,20 @@ retry: size_t trsize = sizeof(*trd); binder_inner_proc_lock(proc); + trace_android_vh_binder_select_special_worklist(&list, thread, + proc, wait_for_proc_work, ¬hing_to_do); + if (list) + goto skip; + else if (nothing_to_do) + goto no_work; + if (!binder_worklist_empty_ilocked(&thread->todo)) list = &thread->todo; else if (!binder_worklist_empty_ilocked(&proc->todo) && wait_for_proc_work) list = &proc->todo; else { +no_work: binder_inner_proc_unlock(proc); /* no data added */ @@ -4950,11 +4967,12 @@ retry: goto retry; break; } - +skip: if (end - ptr < sizeof(tr) + 4) { binder_inner_proc_unlock(proc); break; } + trace_android_vh_binder_thread_read(&list, proc, thread); w = binder_dequeue_work_head_ilocked(list); if (binder_worklist_empty_ilocked(&thread->todo)) thread->process_todo = false; @@ -5302,11 +5320,13 @@ done: *consumed = ptr - buffer; binder_inner_proc_lock(proc); - if (proc->requested_threads == 0 && + trace_android_vh_binder_spawn_new_thread(thread, proc, &force_spawn); + + if (force_spawn || (proc->requested_threads == 0 && list_empty(&thread->proc->waiting_threads) && proc->requested_threads_started < proc->max_threads && (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | - BINDER_LOOPER_STATE_ENTERED)) /* the user-space code fails to */ + BINDER_LOOPER_STATE_ENTERED)))/* the user-space code fails to */ /*spawn a new thread if we leave this out */) { proc->requested_threads++; binder_inner_proc_unlock(proc); @@ -6152,6 +6172,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) goto err; } ret = 0; + trace_android_vh_binder_ioctl_end(current, cmd, arg, thread, proc, &ret); err: if (thread) thread->looper_need_return = false; diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 0c6cb4b1beb7..cd2b2f4b32d1 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -158,6 +158,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpuidle_psci_exit); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_cpufreq_transition); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_gic_v3_set_affinity); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_proc_transaction_finish); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_select_special_worklist); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sync_txn_recvd); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_freq_qos_add_request); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_freq_qos_update_request); @@ -369,6 +370,12 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_list_add_work); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_has_proc_work_ilocked); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_check_special_work); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_free_proc); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_ioctl_end); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_looper_exited); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_spawn_new_thread); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_has_special_work_ilocked); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_preset); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_reply); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_trans); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_proc_transaction); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_thread_read); diff --git a/include/trace/hooks/binder.h b/include/trace/hooks/binder.h index 7795a80afd28..c5b8409df24d 100644 --- a/include/trace/hooks/binder.h +++ b/include/trace/hooks/binder.h @@ -36,6 +36,10 @@ DECLARE_HOOK(android_vh_binder_proc_transaction_finish, TP_PROTO(struct binder_proc *proc, struct binder_transaction *t, struct task_struct *binder_th_task, bool pending_async, bool sync), TP_ARGS(proc, t, binder_th_task, pending_async, sync)); +DECLARE_HOOK(android_vh_binder_select_special_worklist, + TP_PROTO(struct list_head **list, struct binder_thread *thread, struct binder_proc *proc, + int wait_for_proc_work, bool *nothing_to_do), + TP_ARGS(list, thread, proc, wait_for_proc_work, nothing_to_do)); DECLARE_HOOK(android_vh_alloc_oem_binder_struct, TP_PROTO(struct binder_transaction_data *tr, struct binder_transaction *t, struct binder_proc *proc), @@ -56,8 +60,23 @@ DECLARE_HOOK(android_vh_binder_buffer_release, TP_PROTO(struct binder_proc *proc, struct binder_thread *thread, struct binder_buffer *buffer, bool has_transaction), TP_ARGS(proc, thread, buffer, has_transaction)); -struct binder_proc; -struct binder_thread; +DECLARE_HOOK(android_vh_binder_ioctl_end, + TP_PROTO(struct task_struct *caller_task, + unsigned int cmd, + unsigned long arg, + struct binder_thread *thread, + struct binder_proc *proc, + int *ret), + TP_ARGS(caller_task, cmd, arg, thread, proc, ret)); +DECLARE_HOOK(android_vh_binder_looper_exited, + TP_PROTO(struct binder_thread *thread, struct binder_proc *proc), + TP_ARGS(thread, proc)); +DECLARE_HOOK(android_vh_binder_spawn_new_thread, + TP_PROTO(struct binder_thread *thread, struct binder_proc *proc, bool *force_spawn), + TP_ARGS(thread, proc, force_spawn)); +DECLARE_HOOK(android_vh_binder_has_special_work_ilocked, + TP_PROTO(struct binder_thread *thread, bool do_proc_work, bool *has_work), + TP_ARGS(thread, do_proc_work, has_work)); DECLARE_HOOK(android_vh_binder_list_add_work, TP_PROTO(struct binder_work *work, struct list_head *target_list), TP_ARGS(work, target_list)); @@ -73,7 +92,6 @@ DECLARE_HOOK(android_vh_binder_free_proc, DECLARE_HOOK(android_vh_binder_preset, TP_PROTO(struct hlist_head *hhead, struct mutex *lock, struct binder_proc *proc), TP_ARGS(hhead, lock, proc)); -struct binder_transaction_data; DECLARE_HOOK(android_vh_binder_reply, TP_PROTO(struct binder_proc *target_proc, struct binder_proc *proc, struct binder_thread *thread, struct binder_transaction_data *tr), @@ -82,6 +100,15 @@ DECLARE_HOOK(android_vh_binder_trans, TP_PROTO(struct binder_proc *target_proc, struct binder_proc *proc, struct binder_thread *thread, struct binder_transaction_data *tr), TP_ARGS(target_proc, proc, thread, tr)); +DECLARE_HOOK(android_vh_binder_proc_transaction, + TP_PROTO(struct task_struct *caller_task, struct task_struct *binder_proc_task, + struct task_struct *binder_th_task, int node_debug_id, + struct binder_transaction *t, bool pending_async), + TP_ARGS(caller_task, binder_proc_task, binder_th_task, node_debug_id, t, pending_async)); +DECLARE_HOOK(android_vh_binder_thread_read, + TP_PROTO(struct list_head **list, struct binder_proc *proc, + struct binder_thread *thread), + TP_ARGS(list, proc, thread)); #endif /* _TRACE_HOOK_BINDER_H */ /* This part must be outside protection */ #include