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