From 24bb8fc82e6084e93e22edc2011ddb088f5a60b2 Mon Sep 17 00:00:00 2001 From: songfeng Date: Thu, 4 Jan 2024 18:17:32 +0800 Subject: [PATCH] ANDROID: vendor_hooks: add hooks in driver/android/binder.c Add hooks to support oem's binder feature of improving certain scenarios sched priority by moving these scenarios' work to a fixed binder thread. Add the following new vendor hooks to drivers/android/binder.c: 1 trace_android_vh_binder_spawn_new_thread in our os, some binder_transaction will be marked as vip flag, it can be named vip transaction, the binder_work within the vip transaction can be named vip work. here will force a thread (named vip thread) to be spawned and skip the normal conditions to spawn a thread. vip thread will just select vip transaction to process. 2 trace_android_vh_binder_ioctl_end in our os, in binder_proc, about binder threads,special thread (called vip thread) will work for special binder_transaction (called vip transaction). here will expand one ioctl cmd for binder driver, it will set the max count about special thread (called vip thread) in binder_proc, and if it has vip thread in the binder_proc. 3 trace_android_vh_binder_looper_exited while BC_REGISTER_LOOPER cmd, will set special thread as vip thread. the flag saved in binder_thread:looper here will unset the vip flag saved in binder_thread, while BC_EXIT_LOOPER cmd, if the thread is vip thread(reference above about vip thread) 4 trace_android_vh_binder_has_special_work_ilocked for special binder thread(called vip thread), it will deal with special binder_work (called vip work) within special transaction (call vip transaction), here, if the thread is vip thread, it will check the vip work if exist or not. 5 trace_android_vh_binder_select_special_worklist for special binder thread(called vip thread), it will select the worklist for special binder_work(called vip work) within special binder_transaction(called vip transaction) here, it will make sure the selected worklist, the head of it is vip work within vip transaction Bug: 318782978 Change-Id: I8e544d9be2644a6144a9cfbd477e087d46b0073f Signed-off-by: songfeng --- drivers/android/binder.c | 18 ++++++++++++++++-- drivers/android/vendor_hooks.c | 5 +++++ include/trace/hooks/binder.h | 22 ++++++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) 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