summaryrefslogtreecommitdiffstats
path: root/drivers/android
diff options
context:
space:
mode:
authorTodd Kjos <tkjos@android.com>2017-06-29 21:01:54 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-07-17 14:47:30 +0200
commitb6d282cea3f3ed3a5b09d687443213547db39499 (patch)
tree09c1fc3f387bb0d21c163532c988916262728f6d /drivers/android
parentbinder: use atomic for transaction_log index (diff)
downloadlinux-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.c30
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: {