ANDROID: binder: Add vendor hooks to implement the feature of

binder_proc->fg_todo list

1. The implementation logic of this feature
1) In trace_android_vh_binder_list_add_work, record the sequence of work, work->android_oem_data1 = atomic64_inc_return(&binder_work_seq).
2) In the binder_proc_transaction() function, for special synchronized
binders, if a thread is not found, t->work will be added to proc->fg_todo in trace_android_vh_binder_special_task().
3) binder_thread_read() -> trace_android_vh_binder_select_special_worklist()
will select work to execute from proc->fg_todo according to a specific
algorithm, such as selecting the thread->todo first, then selecting two
proc->fg_todo works, and then one proc->todo work, while taking into account the sequence of work (work->android_oem_data1).
proc->ANDROID_OEM_DATA(1) is used to generate proc->fg_todo list, and it
was committed in the id 8a3740893d9957783493364b118282daa71695cc by other colleagues.

2. trace_android_vh_binder_list_add_work: record the sequence of work.

3. trace_android_vh_binder_has_proc_work_ilocked: Check if there is work
in proc->fg_todo list, and if so, then binder_wakeup_proc_ilocked.

4. trace_android_vh_binder_check_special_work: release the work on
proc->fg_todo list, and print the binder work on fg_list.

Bug: 334746237
Bug: 395737475

Change-Id: I855618ee129fe1bb5925b169d24eb2301ad90664
Signed-off-by: Fuchun Liao <lfc@oppo.com>
This commit is contained in:
Fuchun Liao
2024-04-23 14:57:42 +08:00
committed by Treehugger Robot
parent 0ebf9a330d
commit f831b886d2
4 changed files with 40 additions and 5 deletions
+18 -2
View File
@@ -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;
+4
View File
@@ -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);
};
/**
+4
View File
@@ -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);
+14 -3
View File
@@ -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 <trace/define_trace.h>