diff options
author | Todd Kjos <tkjos@android.com> | 2017-06-29 21:01:54 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-07-17 14:47:30 +0200 |
commit | b6d282cea3f3ed3a5b09d687443213547db39499 (patch) | |
tree | 09c1fc3f387bb0d21c163532c988916262728f6d /drivers/android | |
parent | binder: use atomic for transaction_log index (diff) | |
download | linux-b6d282cea3f3ed3a5b09d687443213547db39499.tar.xz linux-b6d282cea3f3ed3a5b09d687443213547db39499.zip |
binder: refactor binder_pop_transaction
binder_pop_transaction needs to be split into 2 pieces to
to allow the proc lock to be held on entry to dequeue the
transaction stack, but no lock when kfree'ing the transaction.
Split into binder_pop_transaction_locked and binder_free_transaction
(the actual locks are still to be added).
Signed-off-by: Todd Kjos <tkjos@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/android')
-rw-r--r-- | drivers/android/binder.c | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/drivers/android/binder.c b/drivers/android/binder.c index cb78a4e6872d..d2fcf3cc29a6 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -768,14 +768,16 @@ static int binder_dec_ref(struct binder_ref *ref, int strong) static void binder_pop_transaction(struct binder_thread *target_thread, struct binder_transaction *t) { - if (target_thread) { - BUG_ON(target_thread->transaction_stack != t); - BUG_ON(target_thread->transaction_stack->from != target_thread); - target_thread->transaction_stack = - target_thread->transaction_stack->from_parent; - t->from = NULL; - } - t->need_reply = 0; + BUG_ON(!target_thread); + BUG_ON(target_thread->transaction_stack != t); + BUG_ON(target_thread->transaction_stack->from != target_thread); + target_thread->transaction_stack = + target_thread->transaction_stack->from_parent; + t->from = NULL; +} + +static void binder_free_transaction(struct binder_transaction *t) +{ if (t->buffer) t->buffer->transaction = NULL; kfree(t); @@ -808,6 +810,7 @@ static void binder_send_failed_reply(struct binder_transaction *t, binder_pop_transaction(target_thread, t); target_thread->return_error = error_code; wake_up_interruptible(&target_thread->wait); + binder_free_transaction(t); } else { pr_err("reply failed, target thread, %d:%d, has error code %d already\n", target_thread->proc->pid, @@ -822,7 +825,7 @@ static void binder_send_failed_reply(struct binder_transaction *t, "send failed reply for transaction %d, target dead\n", t->debug_id); - binder_pop_transaction(target_thread, t); + binder_free_transaction(t); if (next == NULL) { binder_debug(BINDER_DEBUG_DEAD_BINDER, "reply failed, no target thread at root\n"); @@ -1806,6 +1809,7 @@ static void binder_transaction(struct binder_proc *proc, if (reply) { BUG_ON(t->buffer->async_transaction != 0); binder_pop_transaction(target_thread, in_reply_to); + binder_free_transaction(in_reply_to); } else if (!(t->flags & TF_ONE_WAY)) { BUG_ON(t->buffer->async_transaction != 0); t->need_reply = 1; @@ -2635,9 +2639,7 @@ retry: t->to_thread = thread; thread->transaction_stack = t; } else { - t->buffer->transaction = NULL; - kfree(t); - binder_stats_deleted(BINDER_STAT_TRANSACTION); + binder_free_transaction(t); } break; } @@ -2680,9 +2682,7 @@ static void binder_release_work(struct list_head *list) binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, "undelivered transaction %d\n", t->debug_id); - t->buffer->transaction = NULL; - kfree(t); - binder_stats_deleted(BINDER_STAT_TRANSACTION); + binder_free_transaction(t); } } break; case BINDER_WORK_TRANSACTION_COMPLETE: { |