FROMLIST: binder: refactor binder_pop_transaction
(from https://lkml.org/lkml/2017/6/29/754) 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). Change-Id: I848ae994cc27b3cd083cff2dbd1071762784f4a3 Test: tested manually Signed-off-by: Todd Kjos <tkjos@google.com>
This commit is contained in:
parent
0f32aeb35f
commit
1627353817
1 changed files with 15 additions and 15 deletions
|
@ -769,14 +769,16 @@ static int binder_dec_ref(struct binder_ref *ref, int strong)
|
||||||
static void binder_pop_transaction(struct binder_thread *target_thread,
|
static void binder_pop_transaction(struct binder_thread *target_thread,
|
||||||
struct binder_transaction *t)
|
struct binder_transaction *t)
|
||||||
{
|
{
|
||||||
if (target_thread) {
|
BUG_ON(!target_thread);
|
||||||
BUG_ON(target_thread->transaction_stack != t);
|
BUG_ON(target_thread->transaction_stack != t);
|
||||||
BUG_ON(target_thread->transaction_stack->from != target_thread);
|
BUG_ON(target_thread->transaction_stack->from != target_thread);
|
||||||
target_thread->transaction_stack =
|
target_thread->transaction_stack =
|
||||||
target_thread->transaction_stack->from_parent;
|
target_thread->transaction_stack->from_parent;
|
||||||
t->from = NULL;
|
t->from = NULL;
|
||||||
}
|
}
|
||||||
t->need_reply = 0;
|
|
||||||
|
static void binder_free_transaction(struct binder_transaction *t)
|
||||||
|
{
|
||||||
if (t->buffer)
|
if (t->buffer)
|
||||||
t->buffer->transaction = NULL;
|
t->buffer->transaction = NULL;
|
||||||
kfree(t);
|
kfree(t);
|
||||||
|
@ -809,6 +811,7 @@ static void binder_send_failed_reply(struct binder_transaction *t,
|
||||||
binder_pop_transaction(target_thread, t);
|
binder_pop_transaction(target_thread, t);
|
||||||
target_thread->return_error = error_code;
|
target_thread->return_error = error_code;
|
||||||
wake_up_interruptible(&target_thread->wait);
|
wake_up_interruptible(&target_thread->wait);
|
||||||
|
binder_free_transaction(t);
|
||||||
} else {
|
} else {
|
||||||
pr_err("reply failed, target thread, %d:%d, has error code %d already\n",
|
pr_err("reply failed, target thread, %d:%d, has error code %d already\n",
|
||||||
target_thread->proc->pid,
|
target_thread->proc->pid,
|
||||||
|
@ -823,7 +826,7 @@ static void binder_send_failed_reply(struct binder_transaction *t,
|
||||||
"send failed reply for transaction %d, target dead\n",
|
"send failed reply for transaction %d, target dead\n",
|
||||||
t->debug_id);
|
t->debug_id);
|
||||||
|
|
||||||
binder_pop_transaction(target_thread, t);
|
binder_free_transaction(t);
|
||||||
if (next == NULL) {
|
if (next == NULL) {
|
||||||
binder_debug(BINDER_DEBUG_DEAD_BINDER,
|
binder_debug(BINDER_DEBUG_DEAD_BINDER,
|
||||||
"reply failed, no target thread at root\n");
|
"reply failed, no target thread at root\n");
|
||||||
|
@ -1807,6 +1810,7 @@ static void binder_transaction(struct binder_proc *proc,
|
||||||
if (reply) {
|
if (reply) {
|
||||||
BUG_ON(t->buffer->async_transaction != 0);
|
BUG_ON(t->buffer->async_transaction != 0);
|
||||||
binder_pop_transaction(target_thread, in_reply_to);
|
binder_pop_transaction(target_thread, in_reply_to);
|
||||||
|
binder_free_transaction(in_reply_to);
|
||||||
} else if (!(t->flags & TF_ONE_WAY)) {
|
} else if (!(t->flags & TF_ONE_WAY)) {
|
||||||
BUG_ON(t->buffer->async_transaction != 0);
|
BUG_ON(t->buffer->async_transaction != 0);
|
||||||
t->need_reply = 1;
|
t->need_reply = 1;
|
||||||
|
@ -2636,9 +2640,7 @@ retry:
|
||||||
t->to_thread = thread;
|
t->to_thread = thread;
|
||||||
thread->transaction_stack = t;
|
thread->transaction_stack = t;
|
||||||
} else {
|
} else {
|
||||||
t->buffer->transaction = NULL;
|
binder_free_transaction(t);
|
||||||
kfree(t);
|
|
||||||
binder_stats_deleted(BINDER_STAT_TRANSACTION);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2681,9 +2683,7 @@ static void binder_release_work(struct list_head *list)
|
||||||
binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
|
binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
|
||||||
"undelivered transaction %d\n",
|
"undelivered transaction %d\n",
|
||||||
t->debug_id);
|
t->debug_id);
|
||||||
t->buffer->transaction = NULL;
|
binder_free_transaction(t);
|
||||||
kfree(t);
|
|
||||||
binder_stats_deleted(BINDER_STAT_TRANSACTION);
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case BINDER_WORK_TRANSACTION_COMPLETE: {
|
case BINDER_WORK_TRANSACTION_COMPLETE: {
|
||||||
|
|
Loading…
Add table
Reference in a new issue