aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/android
diff options
context:
space:
mode:
authorMartijn Coenen <maco@android.com>2017-11-15 03:21:35 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-11-28 10:33:03 -0500
commit148ade2c4d4f46b3ecc1ddad1c762371e8708e35 (patch)
tree0fbd781537b7128cdb6a7a8c42f65e29cd422fd9 /drivers/android
parent39b759cad5da88ee8ac55e186a00da4692b44e17 (diff)
ANDROID: binder: Add thread->process_todo flag.
This flag determines whether the thread should currently process the work in the thread->todo worklist. The prime usecase for this is improving the performance of synchronous transactions: all synchronous transactions post a BR_TRANSACTION_COMPLETE to the calling thread, but there's no reason to return that command to userspace right away - userspace anyway needs to wait for the reply. Likewise, a synchronous transaction that contains a binder object can cause a BC_ACQUIRE/BC_INCREFS to be returned to userspace; since the caller must anyway hold a strong/weak ref for the duration of the call, postponing these commands until the reply comes in is not a problem. Note that this flag is not used to determine whether a thread can handle process work; a thread should never pick up process work when thread work is still pending. Before patch: ------------------------------------------------------------------ Benchmark Time CPU Iterations ------------------------------------------------------------------ BM_sendVec_binderize/4 45959 ns 20288 ns 34351 BM_sendVec_binderize/8 45603 ns 20080 ns 34909 BM_sendVec_binderize/16 45528 ns 20113 ns 34863 BM_sendVec_binderize/32 45551 ns 20122 ns 34881 BM_sendVec_binderize/64 45701 ns 20183 ns 34864 BM_sendVec_binderize/128 45824 ns 20250 ns 34576 BM_sendVec_binderize/256 45695 ns 20171 ns 34759 BM_sendVec_binderize/512 45743 ns 20211 ns 34489 BM_sendVec_binderize/1024 46169 ns 20430 ns 34081 After patch: ------------------------------------------------------------------ Benchmark Time CPU Iterations ------------------------------------------------------------------ BM_sendVec_binderize/4 42939 ns 17262 ns 40653 BM_sendVec_binderize/8 42823 ns 17243 ns 40671 BM_sendVec_binderize/16 42898 ns 17243 ns 40594 BM_sendVec_binderize/32 42838 ns 17267 ns 40527 BM_sendVec_binderize/64 42854 ns 17249 ns 40379 BM_sendVec_binderize/128 42881 ns 17288 ns 40427 BM_sendVec_binderize/256 42917 ns 17297 ns 40429 BM_sendVec_binderize/512 43184 ns 17395 ns 40411 BM_sendVec_binderize/1024 43119 ns 17357 ns 40432 Signed-off-by: Martijn Coenen <maco@android.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/android')
-rw-r--r--drivers/android/binder.c151
1 files changed, 107 insertions, 44 deletions
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index a73596a4f804..e9d22dd85a19 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -577,6 +577,8 @@ enum {
577 * (protected by @proc->inner_lock) 577 * (protected by @proc->inner_lock)
578 * @todo: list of work to do for this thread 578 * @todo: list of work to do for this thread
579 * (protected by @proc->inner_lock) 579 * (protected by @proc->inner_lock)
580 * @process_todo: whether work in @todo should be processed
581 * (protected by @proc->inner_lock)
580 * @return_error: transaction errors reported by this thread 582 * @return_error: transaction errors reported by this thread
581 * (only accessed by this thread) 583 * (only accessed by this thread)
582 * @reply_error: transaction errors reported by target thread 584 * @reply_error: transaction errors reported by target thread
@@ -602,6 +604,7 @@ struct binder_thread {
602 bool looper_need_return; /* can be written by other thread */ 604 bool looper_need_return; /* can be written by other thread */
603 struct binder_transaction *transaction_stack; 605 struct binder_transaction *transaction_stack;
604 struct list_head todo; 606 struct list_head todo;
607 bool process_todo;
605 struct binder_error return_error; 608 struct binder_error return_error;
606 struct binder_error reply_error; 609 struct binder_error reply_error;
607 wait_queue_head_t wait; 610 wait_queue_head_t wait;
@@ -787,6 +790,16 @@ static bool binder_worklist_empty(struct binder_proc *proc,
787 return ret; 790 return ret;
788} 791}
789 792
793/**
794 * binder_enqueue_work_ilocked() - Add an item to the work list
795 * @work: struct binder_work to add to list
796 * @target_list: list to add work to
797 *
798 * Adds the work to the specified list. Asserts that work
799 * is not already on a list.
800 *
801 * Requires the proc->inner_lock to be held.
802 */
790static void 803static void
791binder_enqueue_work_ilocked(struct binder_work *work, 804binder_enqueue_work_ilocked(struct binder_work *work,
792 struct list_head *target_list) 805 struct list_head *target_list)
@@ -797,22 +810,56 @@ binder_enqueue_work_ilocked(struct binder_work *work,
797} 810}
798 811
799/** 812/**
800 * binder_enqueue_work() - Add an item to the work list 813 * binder_enqueue_deferred_thread_work_ilocked() - Add deferred thread work
801 * @proc: binder_proc associated with list 814 * @thread: thread to queue work to
802 * @work: struct binder_work to add to list 815 * @work: struct binder_work to add to list
803 * @target_list: list to add work to
804 * 816 *
805 * Adds the work to the specified list. Asserts that work 817 * Adds the work to the todo list of the thread. Doesn't set the process_todo
806 * is not already on a list. 818 * flag, which means that (if it wasn't already set) the thread will go to
819 * sleep without handling this work when it calls read.
820 *
821 * Requires the proc->inner_lock to be held.
807 */ 822 */
808static void 823static void
809binder_enqueue_work(struct binder_proc *proc, 824binder_enqueue_deferred_thread_work_ilocked(struct binder_thread *thread,
810 struct binder_work *work, 825 struct binder_work *work)
811 struct list_head *target_list)
812{ 826{
813 binder_inner_proc_lock(proc); 827 binder_enqueue_work_ilocked(work, &thread->todo);
814 binder_enqueue_work_ilocked(work, target_list); 828}
815 binder_inner_proc_unlock(proc); 829
830/**
831 * binder_enqueue_thread_work_ilocked() - Add an item to the thread work list
832 * @thread: thread to queue work to
833 * @work: struct binder_work to add to list
834 *
835 * Adds the work to the todo list of the thread, and enables processing
836 * of the todo queue.
837 *
838 * Requires the proc->inner_lock to be held.
839 */
840static void
841binder_enqueue_thread_work_ilocked(struct binder_thread *thread,
842 struct binder_work *work)
843{
844 binder_enqueue_work_ilocked(work, &thread->todo);
845 thread->process_todo = true;
846}
847
848/**
849 * binder_enqueue_thread_work() - Add an item to the thread work list
850 * @thread: thread to queue work to
851 * @work: struct binder_work to add to list
852 *
853 * Adds the work to the todo list of the thread, and enables processing
854 * of the todo queue.
855 */
856static void
857binder_enqueue_thread_work(struct binder_thread *thread,
858 struct binder_work *work)
859{
860 binder_inner_proc_lock(thread->proc);
861 binder_enqueue_thread_work_ilocked(thread, work);
862 binder_inner_proc_unlock(thread->proc);
816} 863}
817 864
818static void 865static void
@@ -927,7 +974,7 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd)
927static bool binder_has_work_ilocked(struct binder_thread *thread, 974static bool binder_has_work_ilocked(struct binder_thread *thread,
928 bool do_proc_work) 975 bool do_proc_work)
929{ 976{
930 return !binder_worklist_empty_ilocked(&thread->todo) || 977 return thread->process_todo ||
931 thread->looper_need_return || 978 thread->looper_need_return ||
932 (do_proc_work && 979 (do_proc_work &&
933 !binder_worklist_empty_ilocked(&thread->proc->todo)); 980 !binder_worklist_empty_ilocked(&thread->proc->todo));
@@ -1215,6 +1262,17 @@ static int binder_inc_node_nilocked(struct binder_node *node, int strong,
1215 node->local_strong_refs++; 1262 node->local_strong_refs++;
1216 if (!node->has_strong_ref && target_list) { 1263 if (!node->has_strong_ref && target_list) {
1217 binder_dequeue_work_ilocked(&node->work); 1264 binder_dequeue_work_ilocked(&node->work);
1265 /*
1266 * Note: this function is the only place where we queue
1267 * directly to a thread->todo without using the
1268 * corresponding binder_enqueue_thread_work() helper
1269 * functions; in this case it's ok to not set the
1270 * process_todo flag, since we know this node work will
1271 * always be followed by other work that starts queue
1272 * processing: in case of synchronous transactions, a
1273 * BR_REPLY or BR_ERROR; in case of oneway
1274 * transactions, a BR_TRANSACTION_COMPLETE.
1275 */
1218 binder_enqueue_work_ilocked(&node->work, target_list); 1276 binder_enqueue_work_ilocked(&node->work, target_list);
1219 } 1277 }
1220 } else { 1278 } else {
@@ -1226,6 +1284,9 @@ static int binder_inc_node_nilocked(struct binder_node *node, int strong,
1226 node->debug_id); 1284 node->debug_id);
1227 return -EINVAL; 1285 return -EINVAL;
1228 } 1286 }
1287 /*
1288 * See comment above
1289 */
1229 binder_enqueue_work_ilocked(&node->work, target_list); 1290 binder_enqueue_work_ilocked(&node->work, target_list);
1230 } 1291 }
1231 } 1292 }
@@ -1915,9 +1976,9 @@ static void binder_send_failed_reply(struct binder_transaction *t,
1915 binder_pop_transaction_ilocked(target_thread, t); 1976 binder_pop_transaction_ilocked(target_thread, t);
1916 if (target_thread->reply_error.cmd == BR_OK) { 1977 if (target_thread->reply_error.cmd == BR_OK) {
1917 target_thread->reply_error.cmd = error_code; 1978 target_thread->reply_error.cmd = error_code;
1918 binder_enqueue_work_ilocked( 1979 binder_enqueue_thread_work_ilocked(
1919 &target_thread->reply_error.work, 1980 target_thread,
1920 &target_thread->todo); 1981 &target_thread->reply_error.work);
1921 wake_up_interruptible(&target_thread->wait); 1982 wake_up_interruptible(&target_thread->wait);
1922 } else { 1983 } else {
1923 WARN(1, "Unexpected reply error: %u\n", 1984 WARN(1, "Unexpected reply error: %u\n",
@@ -2536,18 +2597,16 @@ static bool binder_proc_transaction(struct binder_transaction *t,
2536 struct binder_proc *proc, 2597 struct binder_proc *proc,
2537 struct binder_thread *thread) 2598 struct binder_thread *thread)
2538{ 2599{
2539 struct list_head *target_list = NULL;
2540 struct binder_node *node = t->buffer->target_node; 2600 struct binder_node *node = t->buffer->target_node;
2541 bool oneway = !!(t->flags & TF_ONE_WAY); 2601 bool oneway = !!(t->flags & TF_ONE_WAY);
2542 bool wakeup = true; 2602 bool pending_async = false;
2543 2603
2544 BUG_ON(!node); 2604 BUG_ON(!node);
2545 binder_node_lock(node); 2605 binder_node_lock(node);
2546 if (oneway) { 2606 if (oneway) {
2547 BUG_ON(thread); 2607 BUG_ON(thread);
2548 if (node->has_async_transaction) { 2608 if (node->has_async_transaction) {
2549 target_list = &node->async_todo; 2609 pending_async = true;
2550 wakeup = false;
2551 } else { 2610 } else {
2552 node->has_async_transaction = 1; 2611 node->has_async_transaction = 1;
2553 } 2612 }
@@ -2561,19 +2620,17 @@ static bool binder_proc_transaction(struct binder_transaction *t,
2561 return false; 2620 return false;
2562 } 2621 }
2563 2622
2564 if (!thread && !target_list) 2623 if (!thread && !pending_async)
2565 thread = binder_select_thread_ilocked(proc); 2624 thread = binder_select_thread_ilocked(proc);
2566 2625
2567 if (thread) 2626 if (thread)
2568 target_list = &thread->todo; 2627 binder_enqueue_thread_work_ilocked(thread, &t->work);
2569 else if (!target_list) 2628 else if (!pending_async)
2570 target_list = &proc->todo; 2629 binder_enqueue_work_ilocked(&t->work, &proc->todo);
2571 else 2630 else
2572 BUG_ON(target_list != &node->async_todo); 2631 binder_enqueue_work_ilocked(&t->work, &node->async_todo);
2573
2574 binder_enqueue_work_ilocked(&t->work, target_list);
2575 2632
2576 if (wakeup) 2633 if (!pending_async)
2577 binder_wakeup_thread_ilocked(proc, thread, !oneway /* sync */); 2634 binder_wakeup_thread_ilocked(proc, thread, !oneway /* sync */);
2578 2635
2579 binder_inner_proc_unlock(proc); 2636 binder_inner_proc_unlock(proc);
@@ -3068,10 +3125,10 @@ static void binder_transaction(struct binder_proc *proc,
3068 } 3125 }
3069 } 3126 }
3070 tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; 3127 tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
3071 binder_enqueue_work(proc, tcomplete, &thread->todo);
3072 t->work.type = BINDER_WORK_TRANSACTION; 3128 t->work.type = BINDER_WORK_TRANSACTION;
3073 3129
3074 if (reply) { 3130 if (reply) {
3131 binder_enqueue_thread_work(thread, tcomplete);
3075 binder_inner_proc_lock(target_proc); 3132 binder_inner_proc_lock(target_proc);
3076 if (target_thread->is_dead) { 3133 if (target_thread->is_dead) {
3077 binder_inner_proc_unlock(target_proc); 3134 binder_inner_proc_unlock(target_proc);
@@ -3079,13 +3136,21 @@ static void binder_transaction(struct binder_proc *proc,
3079 } 3136 }
3080 BUG_ON(t->buffer->async_transaction != 0); 3137 BUG_ON(t->buffer->async_transaction != 0);
3081 binder_pop_transaction_ilocked(target_thread, in_reply_to); 3138 binder_pop_transaction_ilocked(target_thread, in_reply_to);
3082 binder_enqueue_work_ilocked(&t->work, &target_thread->todo); 3139 binder_enqueue_thread_work_ilocked(target_thread, &t->work);
3083 binder_inner_proc_unlock(target_proc); 3140 binder_inner_proc_unlock(target_proc);
3084 wake_up_interruptible_sync(&target_thread->wait); 3141 wake_up_interruptible_sync(&target_thread->wait);
3085 binder_free_transaction(in_reply_to); 3142 binder_free_transaction(in_reply_to);
3086 } else if (!(t->flags & TF_ONE_WAY)) { 3143 } else if (!(t->flags & TF_ONE_WAY)) {
3087 BUG_ON(t->buffer->async_transaction != 0); 3144 BUG_ON(t->buffer->async_transaction != 0);
3088 binder_inner_proc_lock(proc); 3145 binder_inner_proc_lock(proc);
3146 /*
3147 * Defer the TRANSACTION_COMPLETE, so we don't return to
3148 * userspace immediately; this allows the target process to
3149 * immediately start processing this transaction, reducing
3150 * latency. We will then return the TRANSACTION_COMPLETE when
3151 * the target replies (or there is an error).
3152 */
3153 binder_enqueue_deferred_thread_work_ilocked(thread, tcomplete);
3089 t->need_reply = 1; 3154 t->need_reply = 1;
3090 t->from_parent = thread->transaction_stack; 3155 t->from_parent = thread->transaction_stack;
3091 thread->transaction_stack = t; 3156 thread->transaction_stack = t;
@@ -3099,6 +3164,7 @@ static void binder_transaction(struct binder_proc *proc,
3099 } else { 3164 } else {
3100 BUG_ON(target_node == NULL); 3165 BUG_ON(target_node == NULL);
3101 BUG_ON(t->buffer->async_transaction != 1); 3166 BUG_ON(t->buffer->async_transaction != 1);
3167 binder_enqueue_thread_work(thread, tcomplete);
3102 if (!binder_proc_transaction(t, target_proc, NULL)) 3168 if (!binder_proc_transaction(t, target_proc, NULL))
3103 goto err_dead_proc_or_thread; 3169 goto err_dead_proc_or_thread;
3104 } 3170 }
@@ -3177,15 +3243,11 @@ err_invalid_target_handle:
3177 BUG_ON(thread->return_error.cmd != BR_OK); 3243 BUG_ON(thread->return_error.cmd != BR_OK);
3178 if (in_reply_to) { 3244 if (in_reply_to) {
3179 thread->return_error.cmd = BR_TRANSACTION_COMPLETE; 3245 thread->return_error.cmd = BR_TRANSACTION_COMPLETE;
3180 binder_enqueue_work(thread->proc, 3246 binder_enqueue_thread_work(thread, &thread->return_error.work);
3181 &thread->return_error.work,
3182 &thread->todo);
3183 binder_send_failed_reply(in_reply_to, return_error); 3247 binder_send_failed_reply(in_reply_to, return_error);
3184 } else { 3248 } else {
3185 thread->return_error.cmd = return_error; 3249 thread->return_error.cmd = return_error;
3186 binder_enqueue_work(thread->proc, 3250 binder_enqueue_thread_work(thread, &thread->return_error.work);
3187 &thread->return_error.work,
3188 &thread->todo);
3189 } 3251 }
3190} 3252}
3191 3253
@@ -3489,10 +3551,9 @@ static int binder_thread_write(struct binder_proc *proc,
3489 WARN_ON(thread->return_error.cmd != 3551 WARN_ON(thread->return_error.cmd !=
3490 BR_OK); 3552 BR_OK);
3491 thread->return_error.cmd = BR_ERROR; 3553 thread->return_error.cmd = BR_ERROR;
3492 binder_enqueue_work( 3554 binder_enqueue_thread_work(
3493 thread->proc, 3555 thread,
3494 &thread->return_error.work, 3556 &thread->return_error.work);
3495 &thread->todo);
3496 binder_debug( 3557 binder_debug(
3497 BINDER_DEBUG_FAILED_TRANSACTION, 3558 BINDER_DEBUG_FAILED_TRANSACTION,
3498 "%d:%d BC_REQUEST_DEATH_NOTIFICATION failed\n", 3559 "%d:%d BC_REQUEST_DEATH_NOTIFICATION failed\n",
@@ -3572,9 +3633,9 @@ static int binder_thread_write(struct binder_proc *proc,
3572 if (thread->looper & 3633 if (thread->looper &
3573 (BINDER_LOOPER_STATE_REGISTERED | 3634 (BINDER_LOOPER_STATE_REGISTERED |
3574 BINDER_LOOPER_STATE_ENTERED)) 3635 BINDER_LOOPER_STATE_ENTERED))
3575 binder_enqueue_work_ilocked( 3636 binder_enqueue_thread_work_ilocked(
3576 &death->work, 3637 thread,
3577 &thread->todo); 3638 &death->work);
3578 else { 3639 else {
3579 binder_enqueue_work_ilocked( 3640 binder_enqueue_work_ilocked(
3580 &death->work, 3641 &death->work,
@@ -3629,8 +3690,8 @@ static int binder_thread_write(struct binder_proc *proc,
3629 if (thread->looper & 3690 if (thread->looper &
3630 (BINDER_LOOPER_STATE_REGISTERED | 3691 (BINDER_LOOPER_STATE_REGISTERED |
3631 BINDER_LOOPER_STATE_ENTERED)) 3692 BINDER_LOOPER_STATE_ENTERED))
3632 binder_enqueue_work_ilocked( 3693 binder_enqueue_thread_work_ilocked(
3633 &death->work, &thread->todo); 3694 thread, &death->work);
3634 else { 3695 else {
3635 binder_enqueue_work_ilocked( 3696 binder_enqueue_work_ilocked(
3636 &death->work, 3697 &death->work,
@@ -3804,6 +3865,8 @@ retry:
3804 break; 3865 break;
3805 } 3866 }
3806 w = binder_dequeue_work_head_ilocked(list); 3867 w = binder_dequeue_work_head_ilocked(list);
3868 if (binder_worklist_empty_ilocked(&thread->todo))
3869 thread->process_todo = false;
3807 3870
3808 switch (w->type) { 3871 switch (w->type) {
3809 case BINDER_WORK_TRANSACTION: { 3872 case BINDER_WORK_TRANSACTION: {