diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 0fb7611aae70..84086a181d2a 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -442,6 +442,7 @@ binder_enqueue_work_ilocked(struct binder_work *work, { BUG_ON(target_list == NULL); BUG_ON(work->entry.next && !list_empty(&work->entry)); + trace_android_vh_binder_list_add_work(work, target_list); list_add_tail(&work->entry, target_list); } @@ -5474,6 +5475,7 @@ static void binder_free_proc(struct binder_proc *proc) put_cred(proc->cred); binder_stats_deleted(BINDER_STAT_PROC); dbitmap_free(&proc->dmap); + trace_android_vh_binder_free_proc(proc); kfree(proc); } @@ -5608,6 +5610,7 @@ static int binder_ioctl_write_read(struct file *filp, unsigned long arg, struct binder_proc *proc = filp->private_data; void __user *ubuf = (void __user *)arg; struct binder_write_read bwr; + bool has_special_work = false; if (copy_from_user(&bwr, ubuf, sizeof(bwr))) { ret = -EFAULT; @@ -5639,7 +5642,9 @@ static int binder_ioctl_write_read(struct file *filp, unsigned long arg, filp->f_flags & O_NONBLOCK); trace_binder_read_done(ret); binder_inner_proc_lock(proc); - if (!binder_worklist_empty_ilocked(&proc->todo)) + trace_android_vh_binder_has_proc_work_ilocked( + thread, true, &has_special_work); + if (!binder_worklist_empty_ilocked(&proc->todo) || has_special_work) binder_wakeup_proc_ilocked(proc); binder_inner_proc_unlock(proc); if (ret < 0) { @@ -6269,6 +6274,7 @@ static int binder_open(struct inode *nodp, struct file *filp) INIT_LIST_HEAD(&proc->waiting_threads); filp->private_data = proc; + trace_android_vh_binder_preset(&binder_procs, &binder_procs_lock, proc); mutex_lock(&binder_procs_lock); hlist_for_each_entry(itr, &binder_procs, proc_node) { if (itr->pid == proc->pid) { @@ -6278,7 +6284,6 @@ static int binder_open(struct inode *nodp, struct file *filp) } hlist_add_head(&proc->proc_node, &binder_procs); mutex_unlock(&binder_procs_lock); - trace_android_vh_binder_preset(&binder_procs, &binder_procs_lock); if (binder_debugfs_dir_entry_proc && !existing_pid) { char strbuf[11]; @@ -6439,6 +6444,7 @@ static void binder_deferred_release(struct binder_proc *proc) struct binder_context *context = proc->context; struct rb_node *n; int threads, nodes, incoming_refs, outgoing_refs, active_transactions; + struct list_head *special_list = NULL; mutex_lock(&binder_procs_lock); hlist_del(&proc->proc_node); @@ -6511,6 +6517,9 @@ static void binder_deferred_release(struct binder_proc *proc) binder_proc_unlock(proc); binder_release_work(proc, &proc->todo); + trace_android_vh_binder_check_special_work(proc, &special_list); + if (special_list) + binder_release_work(proc, special_list); binder_release_work(proc, &proc->delivered_death); binder_release_work(proc, &proc->delivered_freeze); @@ -6745,6 +6754,7 @@ static void print_binder_proc(struct seq_file *m, size_t start_pos = m->count; size_t header_pos; struct binder_node *last_node = NULL; + struct list_head *special_list = NULL; seq_printf(m, "proc %d\n", proc->pid); seq_printf(m, "context %s\n", proc->context->name); @@ -6796,6 +6806,12 @@ static void print_binder_proc(struct seq_file *m, list_for_each_entry(w, &proc->todo, entry) print_binder_work_ilocked(m, proc, " ", " pending transaction", w); + trace_android_vh_binder_check_special_work(proc, &special_list); + if (special_list) { + list_for_each_entry(w, special_list, entry) + print_binder_work_ilocked(m, proc, " ", + " special pending transaction", w); + } list_for_each_entry(w, &proc->delivered_death, entry) { seq_puts(m, " has delivered dead binder\n"); break; diff --git a/drivers/android/binder_internal.h b/drivers/android/binder_internal.h index 21b6c0230c90..65720b3b35a3 100644 --- a/drivers/android/binder_internal.h +++ b/drivers/android/binder_internal.h @@ -165,6 +165,8 @@ struct binder_work { BINDER_WORK_FROZEN_BINDER, BINDER_WORK_CLEAR_FREEZE_NOTIFICATION, } type; + + ANDROID_OEM_DATA(1); }; struct binder_error { @@ -481,6 +483,7 @@ struct binder_proc { spinlock_t outer_lock; struct dentry *binderfs_entry; bool oneway_spam_detection_enabled; + ANDROID_OEM_DATA(1); }; /** @@ -602,6 +605,7 @@ struct binder_transaction { */ spinlock_t lock; ANDROID_VENDOR_DATA(1); + ANDROID_OEM_DATA(1); }; /** diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 05d85a991b10..0c6cb4b1beb7 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -365,6 +365,10 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_dma_heap_buffer_alloc_start); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_dma_heap_buffer_alloc_end); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_zs_shrinker_adjust); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_zs_shrinker_bypass); +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_preset); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_reply); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_trans); diff --git a/include/trace/hooks/binder.h b/include/trace/hooks/binder.h index 11795f6e6407..7795a80afd28 100644 --- a/include/trace/hooks/binder.h +++ b/include/trace/hooks/binder.h @@ -58,9 +58,21 @@ DECLARE_HOOK(android_vh_binder_buffer_release, TP_ARGS(proc, thread, buffer, has_transaction)); struct binder_proc; struct binder_thread; +DECLARE_HOOK(android_vh_binder_list_add_work, + TP_PROTO(struct binder_work *work, struct list_head *target_list), + TP_ARGS(work, target_list)); +DECLARE_HOOK(android_vh_binder_has_proc_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_check_special_work, + TP_PROTO(struct binder_proc *proc, struct list_head **special_list), + TP_ARGS(proc, special_list)); +DECLARE_HOOK(android_vh_binder_free_proc, + TP_PROTO(struct binder_proc *proc), + TP_ARGS(proc)); DECLARE_HOOK(android_vh_binder_preset, - TP_PROTO(struct hlist_head *hhead, struct mutex *lock), - TP_ARGS(hhead, lock)); + 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, @@ -70,7 +82,6 @@ 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)); - #endif /* _TRACE_HOOK_BINDER_H */ /* This part must be outside protection */ #include