diff --git a/drivers/android/binder.c b/drivers/android/binder.c index b0188e8ee00b..dc9606733889 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -560,6 +560,7 @@ static bool binder_has_work(struct binder_thread *thread, bool do_proc_work) binder_inner_proc_lock(thread->proc); has_work = binder_has_work_ilocked(thread, do_proc_work); + trace_android_vh_binder_has_special_work_ilocked(thread, do_proc_work, &has_work); binder_inner_proc_unlock(thread->proc); return has_work; @@ -4280,6 +4281,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); @@ -4607,6 +4609,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) { @@ -4662,14 +4666,20 @@ retry: binder_inner_proc_lock(proc); trace_android_vh_binder_select_worklist_ilocked(&list, thread, proc, wait_for_proc_work); + 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 */ @@ -4987,11 +4997,14 @@ 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 ((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))) || + force_spawn /* the user-space code fails to */ /*spawn a new thread if we leave this out */) { proc->requested_threads++; binder_inner_proc_unlock(proc); @@ -5780,6 +5793,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 14bb47fcf8b0..3b50cf94742b 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -164,6 +164,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_wait_for_work); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_proc_transaction_finish); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_proc_transaction_entry); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_select_worklist_ilocked); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_select_special_worklist); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sync_txn_recvd); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_cpufreq_transition); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_freq_qos_add_request); @@ -370,3 +371,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_kmalloc_large_alloced); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_netlink_poll); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ep_create_wakeup_source); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_timerfd_create); +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); diff --git a/include/trace/hooks/binder.h b/include/trace/hooks/binder.h index 216b5645db73..1a1d051fb079 100644 --- a/include/trace/hooks/binder.h +++ b/include/trace/hooks/binder.h @@ -74,6 +74,11 @@ DECLARE_HOOK(android_vh_binder_select_worklist_ilocked, TP_PROTO(struct list_head **list, struct binder_thread *thread, struct binder_proc *proc, int wait_for_proc_work), TP_ARGS(list, thread, proc, wait_for_proc_work)); +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_binder_alloc_new_buf_locked, TP_PROTO(size_t size, size_t *free_async_space, int is_async), TP_ARGS(size, free_async_space, is_async)); @@ -118,6 +123,23 @@ DECLARE_HOOK(android_vh_binder_free_buf, struct binder_buffer *buffer), TP_ARGS(proc, thread, buffer)); +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)); #endif /* _TRACE_HOOK_BINDER_H */ /* This part must be outside protection */ #include