Give every case in the switch statement its own dedicated function. Remove the process argument to binder_transact, as it can be derived from the thread argument as with all of the other newly created functions. Signed-off-by: Riley Andrews <riandrews@xxxxxxxxxxx> --- drivers/android/binder.c | 613 +++++++++++++++++++++++++++-------------------- 1 file changed, 350 insertions(+), 263 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 2069759..e47c2d4 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -1314,8 +1314,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, } } -static void binder_transaction(struct binder_proc *proc, - struct binder_thread *thread, +static void binder_transaction(struct binder_thread *thread, struct binder_transaction_data *tr, int reply) { struct binder_transaction *t; @@ -1328,6 +1327,7 @@ static void binder_transaction(struct binder_proc *proc, wait_queue_head_t *target_wait; struct binder_transaction *in_reply_to = NULL; struct binder_transaction_log_entry *e; + struct binder_proc *proc = thread->proc; uint32_t return_error; e = binder_transaction_log_add(&binder_transaction_log); @@ -1752,10 +1752,329 @@ err_no_context_mgr_node: thread->return_error = return_error; } +static void binder_call_inc_dec_ref(struct binder_thread *thread, + uint32_t target, uint32_t cmd) +{ + struct binder_proc *proc = thread->proc; + struct binder_ref *ref; + const char *debug_string; + + if (target == 0 && binder_context_mgr_node && + (cmd == BC_INCREFS || cmd == BC_ACQUIRE)) { + ref = binder_get_ref_for_node(proc, binder_context_mgr_node); + if (ref->desc != target) { + binder_user_error("%d:%d tried to acquire reference to desc 0, got %d instead\n", + proc->pid, thread->pid, ref->desc); + return; + } + } else { + ref = binder_get_ref(proc, target); + } + if (!ref) { + binder_user_error("%d:%d refcount change on invalid ref %d\n", + proc->pid, thread->pid, target); + return; + } + switch (cmd) { + case BC_INCREFS: + debug_string = "IncRefs"; + binder_inc_ref(ref, 0, NULL); + break; + case BC_ACQUIRE: + debug_string = "Acquire"; + binder_inc_ref(ref, 1, NULL); + break; + case BC_RELEASE: + debug_string = "Release"; + binder_dec_ref(ref, 1); + break; + case BC_DECREFS: + default: + debug_string = "DecRefs"; + binder_dec_ref(ref, 0); + break; + } + binder_debug(BINDER_DEBUG_USER_REFS, + "%d:%d %s ref %d desc %d s %d w %d for node %d\n", + proc->pid, thread->pid, debug_string, ref->debug_id, + ref->desc, ref->strong, ref->weak, ref->node->debug_id); +} + +static void binder_call_inc_ref_done(struct binder_thread *thread, + binder_uintptr_t node_ptr, + binder_uintptr_t cookie, uint32_t cmd) +{ + struct binder_node *node; + struct binder_proc *proc = thread->proc; + + node = binder_get_node(proc, node_ptr); + if (!node) { + binder_user_error("%d:%d %s u%016llx no match\n", + proc->pid, thread->pid, + cmd == BC_INCREFS_DONE ? + "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", + (u64)node_ptr); + return; + } + if (cookie != node->cookie) { + binder_user_error("%d:%d %s u%016llx node %d cookie mismatch %016llx != %016llx\n", + proc->pid, thread->pid, + cmd == BC_INCREFS_DONE ? + "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", + (u64)node_ptr, node->debug_id, + (u64)cookie, (u64)node->cookie); + return; + } + if (cmd == BC_ACQUIRE_DONE) { + if (node->pending_strong_ref == 0) { + binder_user_error("%d:%d BC_ACQUIRE_DONE node %d has no pending acquire request\n", + proc->pid, thread->pid, + node->debug_id); + return; + } + node->pending_strong_ref = 0; + } else { + if (node->pending_weak_ref == 0) { + binder_user_error("%d:%d BC_INCREFS_DONE node %d has no pending increfs request\n", + proc->pid, thread->pid, + node->debug_id); + return; + } + node->pending_weak_ref = 0; + } + binder_dec_node(node, cmd == BC_ACQUIRE_DONE, 0); + binder_debug(BINDER_DEBUG_USER_REFS, "%d:%d %s node %d ls %d lw %d\n", + proc->pid, thread->pid, cmd == BC_INCREFS_DONE ? + "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", + node->debug_id, node->local_strong_refs, + node->local_weak_refs); +} + +static void binder_call_free_buffer(struct binder_thread *thread, + binder_uintptr_t data_ptr) +{ + struct binder_buffer *buffer; + struct binder_proc *proc = thread->proc; + + buffer = binder_buffer_lookup(proc, data_ptr); + if (!buffer) { + binder_user_error("%d:%d BC_FREE_BUFFER u%016llx no match\n", + proc->pid, thread->pid, (u64)data_ptr); + return; + } + if (!buffer->allow_user_free) { + binder_user_error("%d:%d BC_FREE_BUFFER u%016llx matched unreturned buffer\n", + proc->pid, thread->pid, (u64)data_ptr); + return; + } + binder_debug(BINDER_DEBUG_FREE_BUFFER, + "%d:%d BC_FREE_BUFFER u%016llx found buffer %d for %s transaction\n", + proc->pid, thread->pid, (u64)data_ptr, buffer->debug_id, + buffer->transaction ? "active" : "finished"); + + if (buffer->transaction) { + buffer->transaction->buffer = NULL; + buffer->transaction = NULL; + } + if (buffer->async_transaction && buffer->target_node) { + BUG_ON(!buffer->target_node->has_async_transaction); + if (list_empty(&buffer->target_node->async_todo)) + buffer->target_node->has_async_transaction = 0; + else + list_move_tail(buffer->target_node->async_todo.next, + &thread->todo); + } + trace_binder_transaction_buffer_release(buffer); + binder_transaction_buffer_release(proc, buffer, NULL); + binder_free_buf(proc, buffer); +} + +static void binder_call_register_looper(struct binder_thread *thread) +{ + struct binder_proc *proc = thread->proc; + + binder_debug(BINDER_DEBUG_THREADS, "%d:%d BC_REGISTER_LOOPER\n", + proc->pid, thread->pid); + if (thread->looper & BINDER_LOOPER_STATE_ENTERED) { + thread->looper |= BINDER_LOOPER_STATE_INVALID; + binder_user_error("%d:%d ERROR: BC_REGISTER_LOOPER called after BC_ENTER_LOOPER\n", + proc->pid, thread->pid); + } else if (proc->requested_threads == 0) { + thread->looper |= BINDER_LOOPER_STATE_INVALID; + binder_user_error("%d:%d ERROR: BC_REGISTER_LOOPER called without request\n", + proc->pid, thread->pid); + } else { + proc->requested_threads--; + proc->requested_threads_started++; + } + thread->looper |= BINDER_LOOPER_STATE_REGISTERED; +} + +static void binder_call_enter_looper(struct binder_thread *thread) +{ + struct binder_proc *proc = thread->proc; + + binder_debug(BINDER_DEBUG_THREADS, "%d:%d BC_ENTER_LOOPER\n", + proc->pid, thread->pid); + if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) { + thread->looper |= BINDER_LOOPER_STATE_INVALID; + binder_user_error("%d:%d ERROR: BC_ENTER_LOOPER called after BC_REGISTER_LOOPER\n", + proc->pid, thread->pid); + } + thread->looper |= BINDER_LOOPER_STATE_ENTERED; +} + +static void binder_call_req_death_notification(struct binder_thread *thread, + uint32_t target, + binder_uintptr_t cookie) +{ + struct binder_ref *ref; + struct binder_ref_death *death; + struct binder_proc *proc = thread->proc; + + ref = binder_get_ref(proc, target); + if (!ref) { + binder_user_error("%d:%d %s invalid ref %d\n", + proc->pid, thread->pid, + "BC_REQUEST_DEATH_NOTIFICATION", + target); + return; + } + + binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION, + "%d:%d %s %016llx ref %d desc %d s %d w %d for node %d\n", + proc->pid, thread->pid, + "BC_REQUEST_DEATH_NOTIFICATION", + (u64)cookie, ref->debug_id, ref->desc, + ref->strong, ref->weak, ref->node->debug_id); + + if (ref->death) { + binder_user_error("%d:%d BC_REQUEST_DEATH_NOTIFICATION death notification already set\n", + proc->pid, thread->pid); + return; + } + death = kzalloc(sizeof(*death), GFP_KERNEL); + if (!death) { + thread->return_error = BR_ERROR; + binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, + "%d:%d BC_REQUEST_DEATH_NOTIFICATION failed\n", + proc->pid, thread->pid); + return; + } + binder_stats_created(BINDER_STAT_DEATH); + INIT_LIST_HEAD(&death->work.entry); + death->cookie = cookie; + ref->death = death; + if (!ref->node->proc) { + ref->death->work.type = BINDER_WORK_DEAD_BINDER; + if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | + BINDER_LOOPER_STATE_ENTERED)) { + list_add_tail(&ref->death->work.entry, + &thread->todo); + } else { + list_add_tail(&ref->death->work.entry, + &proc->todo); + wake_up_interruptible(&proc->wait); + } + } +} + +static void binder_call_clear_death_notification(struct binder_thread *thread, + uint32_t target, + binder_uintptr_t cookie) +{ + struct binder_ref *ref; + struct binder_ref_death *death; + struct binder_proc *proc = thread->proc; + + ref = binder_get_ref(proc, target); + if (!ref) { + binder_user_error("%d:%d %s invalid ref %d\n", + proc->pid, thread->pid, + "BC_CLEAR_DEATH_NOTIFICATION", + target); + return; + } + + binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION, + "%d:%d %s %016llx ref %d desc %d s %d w %d for node %d\n", + proc->pid, thread->pid, + "BC_CLEAR_DEATH_NOTIFICATION", + (u64)cookie, ref->debug_id, ref->desc, + ref->strong, ref->weak, ref->node->debug_id); + + if (!ref->death) { + binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification not active\n", + proc->pid, thread->pid); + return; + } + death = ref->death; + if (death->cookie != cookie) { + binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification cookie mismatch %016llx != %016llx\n", + proc->pid, thread->pid, + (u64)death->cookie, (u64)cookie); + return; + } + ref->death = NULL; + if (list_empty(&death->work.entry)) { + death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; + if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | + BINDER_LOOPER_STATE_ENTERED)) { + list_add_tail(&death->work.entry, + &thread->todo); + } else { + list_add_tail(&death->work.entry, &proc->todo); + wake_up_interruptible(&proc->wait); + } + } else { + BUG_ON(death->work.type != BINDER_WORK_DEAD_BINDER); + death->work.type = BINDER_WORK_DEAD_BINDER_AND_CLEAR; + } +} + +static void binder_call_dead_binder_done(struct binder_thread *thread, + binder_uintptr_t cookie) +{ + struct binder_work *work; + struct binder_ref_death *death = NULL; + struct binder_proc *proc = thread->proc; + + list_for_each_entry(work, &proc->delivered_death, entry) { + struct binder_ref_death *tmp_death; + + tmp_death = container_of(work, struct binder_ref_death, work); + if (tmp_death->cookie == cookie) { + death = tmp_death; + break; + } + } + binder_debug(BINDER_DEBUG_DEAD_BINDER, + "%d:%d BC_DEAD_BINDER_DONE %016llx found %p\n", + proc->pid, thread->pid, (u64)cookie, + death); + if (!death) { + binder_user_error("%d:%d BC_DEAD_BINDER_DONE %016llx not found\n", + proc->pid, thread->pid, (u64)cookie); + return; + } + + list_del_init(&death->work.entry); + if (death->work.type == BINDER_WORK_DEAD_BINDER_AND_CLEAR) { + death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; + if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | + BINDER_LOOPER_STATE_ENTERED)) { + list_add_tail(&death->work.entry, &thread->todo); + } else { + list_add_tail(&death->work.entry, &proc->todo); + wake_up_interruptible(&proc->wait); + } + } +} + static int binder_thread_write(struct binder_proc *proc, - struct binder_thread *thread, - binder_uintptr_t binder_buffer, size_t size, - binder_size_t *consumed) + struct binder_thread *thread, + binder_uintptr_t binder_buffer, size_t size, + binder_size_t *consumed) { uint32_t cmd; void __user *buffer = (void __user *)(uintptr_t)binder_buffer; @@ -1778,58 +2097,17 @@ static int binder_thread_write(struct binder_proc *proc, case BC_RELEASE: case BC_DECREFS: { uint32_t target; - struct binder_ref *ref; - const char *debug_string; if (get_user(target, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); - if (target == 0 && binder_context_mgr_node && - (cmd == BC_INCREFS || cmd == BC_ACQUIRE)) { - ref = binder_get_ref_for_node(proc, - binder_context_mgr_node); - if (ref->desc != target) { - binder_user_error("%d:%d tried to acquire reference to desc 0, got %d instead\n", - proc->pid, thread->pid, - ref->desc); - } - } else - ref = binder_get_ref(proc, target); - if (ref == NULL) { - binder_user_error("%d:%d refcount change on invalid ref %d\n", - proc->pid, thread->pid, target); - break; - } - switch (cmd) { - case BC_INCREFS: - debug_string = "IncRefs"; - binder_inc_ref(ref, 0, NULL); - break; - case BC_ACQUIRE: - debug_string = "Acquire"; - binder_inc_ref(ref, 1, NULL); - break; - case BC_RELEASE: - debug_string = "Release"; - binder_dec_ref(ref, 1); - break; - case BC_DECREFS: - default: - debug_string = "DecRefs"; - binder_dec_ref(ref, 0); - break; - } - binder_debug(BINDER_DEBUG_USER_REFS, - "%d:%d %s ref %d desc %d s %d w %d for node %d\n", - proc->pid, thread->pid, debug_string, ref->debug_id, - ref->desc, ref->strong, ref->weak, ref->node->debug_id); + binder_call_inc_dec_ref(thread, target, cmd); break; } case BC_INCREFS_DONE: case BC_ACQUIRE_DONE: { binder_uintptr_t node_ptr; binder_uintptr_t cookie; - struct binder_node *node; if (get_user(node_ptr, (binder_uintptr_t __user *)ptr)) return -EFAULT; @@ -1837,48 +2115,7 @@ static int binder_thread_write(struct binder_proc *proc, if (get_user(cookie, (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); - node = binder_get_node(proc, node_ptr); - if (node == NULL) { - binder_user_error("%d:%d %s u%016llx no match\n", - proc->pid, thread->pid, - cmd == BC_INCREFS_DONE ? - "BC_INCREFS_DONE" : - "BC_ACQUIRE_DONE", - (u64)node_ptr); - break; - } - if (cookie != node->cookie) { - binder_user_error("%d:%d %s u%016llx node %d cookie mismatch %016llx != %016llx\n", - proc->pid, thread->pid, - cmd == BC_INCREFS_DONE ? - "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", - (u64)node_ptr, node->debug_id, - (u64)cookie, (u64)node->cookie); - break; - } - if (cmd == BC_ACQUIRE_DONE) { - if (node->pending_strong_ref == 0) { - binder_user_error("%d:%d BC_ACQUIRE_DONE node %d has no pending acquire request\n", - proc->pid, thread->pid, - node->debug_id); - break; - } - node->pending_strong_ref = 0; - } else { - if (node->pending_weak_ref == 0) { - binder_user_error("%d:%d BC_INCREFS_DONE node %d has no pending increfs request\n", - proc->pid, thread->pid, - node->debug_id); - break; - } - node->pending_weak_ref = 0; - } - binder_dec_node(node, cmd == BC_ACQUIRE_DONE, 0); - binder_debug(BINDER_DEBUG_USER_REFS, - "%d:%d %s node %d ls %d lw %d\n", - proc->pid, thread->pid, - cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", - node->debug_id, node->local_strong_refs, node->local_weak_refs); + binder_call_inc_ref_done(thread, node_ptr, cookie, cmd); break; } case BC_ATTEMPT_ACQUIRE: @@ -1887,49 +2124,15 @@ static int binder_thread_write(struct binder_proc *proc, case BC_ACQUIRE_RESULT: pr_err("BC_ACQUIRE_RESULT not supported\n"); return -EINVAL; - case BC_FREE_BUFFER: { binder_uintptr_t data_ptr; - struct binder_buffer *buffer; if (get_user(data_ptr, (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); - - buffer = binder_buffer_lookup(proc, data_ptr); - if (buffer == NULL) { - binder_user_error("%d:%d BC_FREE_BUFFER u%016llx no match\n", - proc->pid, thread->pid, (u64)data_ptr); - break; - } - if (!buffer->allow_user_free) { - binder_user_error("%d:%d BC_FREE_BUFFER u%016llx matched unreturned buffer\n", - proc->pid, thread->pid, (u64)data_ptr); - break; - } - binder_debug(BINDER_DEBUG_FREE_BUFFER, - "%d:%d BC_FREE_BUFFER u%016llx found buffer %d for %s transaction\n", - proc->pid, thread->pid, (u64)data_ptr, - buffer->debug_id, - buffer->transaction ? "active" : "finished"); - - if (buffer->transaction) { - buffer->transaction->buffer = NULL; - buffer->transaction = NULL; - } - if (buffer->async_transaction && buffer->target_node) { - BUG_ON(!buffer->target_node->has_async_transaction); - if (list_empty(&buffer->target_node->async_todo)) - buffer->target_node->has_async_transaction = 0; - else - list_move_tail(buffer->target_node->async_todo.next, &thread->todo); - } - trace_binder_transaction_buffer_release(buffer); - binder_transaction_buffer_release(proc, buffer, NULL); - binder_free_buf(proc, buffer); + binder_call_free_buffer(thread, data_ptr); break; } - case BC_TRANSACTION: case BC_REPLY: { struct binder_transaction_data tr; @@ -1937,38 +2140,14 @@ static int binder_thread_write(struct binder_proc *proc, if (copy_from_user(&tr, ptr, sizeof(tr))) return -EFAULT; ptr += sizeof(tr); - binder_transaction(proc, thread, &tr, cmd == BC_REPLY); + binder_transaction(thread, &tr, cmd == BC_REPLY); break; } - case BC_REGISTER_LOOPER: - binder_debug(BINDER_DEBUG_THREADS, - "%d:%d BC_REGISTER_LOOPER\n", - proc->pid, thread->pid); - if (thread->looper & BINDER_LOOPER_STATE_ENTERED) { - thread->looper |= BINDER_LOOPER_STATE_INVALID; - binder_user_error("%d:%d ERROR: BC_REGISTER_LOOPER called after BC_ENTER_LOOPER\n", - proc->pid, thread->pid); - } else if (proc->requested_threads == 0) { - thread->looper |= BINDER_LOOPER_STATE_INVALID; - binder_user_error("%d:%d ERROR: BC_REGISTER_LOOPER called without request\n", - proc->pid, thread->pid); - } else { - proc->requested_threads--; - proc->requested_threads_started++; - } - thread->looper |= BINDER_LOOPER_STATE_REGISTERED; + binder_call_register_looper(thread); break; case BC_ENTER_LOOPER: - binder_debug(BINDER_DEBUG_THREADS, - "%d:%d BC_ENTER_LOOPER\n", - proc->pid, thread->pid); - if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) { - thread->looper |= BINDER_LOOPER_STATE_INVALID; - binder_user_error("%d:%d ERROR: BC_ENTER_LOOPER called after BC_REGISTER_LOOPER\n", - proc->pid, thread->pid); - } - thread->looper |= BINDER_LOOPER_STATE_ENTERED; + binder_call_enter_looper(thread); break; case BC_EXIT_LOOPER: binder_debug(BINDER_DEBUG_THREADS, @@ -1976,13 +2155,23 @@ static int binder_thread_write(struct binder_proc *proc, proc->pid, thread->pid); thread->looper |= BINDER_LOOPER_STATE_EXITED; break; + case BC_REQUEST_DEATH_NOTIFICATION: { + uint32_t target; + binder_uintptr_t cookie; - case BC_REQUEST_DEATH_NOTIFICATION: + if (get_user(target, (uint32_t __user *)ptr)) + return -EFAULT; + ptr += sizeof(uint32_t); + if (get_user(cookie, (binder_uintptr_t __user *)ptr)) + return -EFAULT; + ptr += sizeof(binder_uintptr_t); + binder_call_req_death_notification(thread, target, + cookie); + break; + } case BC_CLEAR_DEATH_NOTIFICATION: { uint32_t target; binder_uintptr_t cookie; - struct binder_ref *ref; - struct binder_ref_death *death; if (get_user(target, (uint32_t __user *)ptr)) return -EFAULT; @@ -1990,121 +2179,19 @@ static int binder_thread_write(struct binder_proc *proc, if (get_user(cookie, (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); - ref = binder_get_ref(proc, target); - if (ref == NULL) { - binder_user_error("%d:%d %s invalid ref %d\n", - proc->pid, thread->pid, - cmd == BC_REQUEST_DEATH_NOTIFICATION ? - "BC_REQUEST_DEATH_NOTIFICATION" : - "BC_CLEAR_DEATH_NOTIFICATION", - target); - break; - } - - binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION, - "%d:%d %s %016llx ref %d desc %d s %d w %d for node %d\n", - proc->pid, thread->pid, - cmd == BC_REQUEST_DEATH_NOTIFICATION ? - "BC_REQUEST_DEATH_NOTIFICATION" : - "BC_CLEAR_DEATH_NOTIFICATION", - (u64)cookie, ref->debug_id, ref->desc, - ref->strong, ref->weak, ref->node->debug_id); - - if (cmd == BC_REQUEST_DEATH_NOTIFICATION) { - if (ref->death) { - binder_user_error("%d:%d BC_REQUEST_DEATH_NOTIFICATION death notification already set\n", - proc->pid, thread->pid); - break; - } - death = kzalloc(sizeof(*death), GFP_KERNEL); - if (death == NULL) { - thread->return_error = BR_ERROR; - binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "%d:%d BC_REQUEST_DEATH_NOTIFICATION failed\n", - proc->pid, thread->pid); - break; - } - binder_stats_created(BINDER_STAT_DEATH); - INIT_LIST_HEAD(&death->work.entry); - death->cookie = cookie; - ref->death = death; - if (ref->node->proc == NULL) { - ref->death->work.type = BINDER_WORK_DEAD_BINDER; - if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { - list_add_tail(&ref->death->work.entry, &thread->todo); - } else { - list_add_tail(&ref->death->work.entry, &proc->todo); - wake_up_interruptible(&proc->wait); - } - } - } else { - if (ref->death == NULL) { - binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification not active\n", - proc->pid, thread->pid); - break; - } - death = ref->death; - if (death->cookie != cookie) { - binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification cookie mismatch %016llx != %016llx\n", - proc->pid, thread->pid, - (u64)death->cookie, - (u64)cookie); - break; - } - ref->death = NULL; - if (list_empty(&death->work.entry)) { - death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; - if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { - list_add_tail(&death->work.entry, &thread->todo); - } else { - list_add_tail(&death->work.entry, &proc->todo); - wake_up_interruptible(&proc->wait); - } - } else { - BUG_ON(death->work.type != BINDER_WORK_DEAD_BINDER); - death->work.type = BINDER_WORK_DEAD_BINDER_AND_CLEAR; - } - } - } break; + binder_call_clear_death_notification(thread, target, + cookie); + break; + } case BC_DEAD_BINDER_DONE: { - struct binder_work *w; binder_uintptr_t cookie; - struct binder_ref_death *death = NULL; if (get_user(cookie, (binder_uintptr_t __user *)ptr)) return -EFAULT; - ptr += sizeof(cookie); - list_for_each_entry(w, &proc->delivered_death, entry) { - struct binder_ref_death *tmp_death = container_of(w, struct binder_ref_death, work); - - if (tmp_death->cookie == cookie) { - death = tmp_death; - break; - } - } - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "%d:%d BC_DEAD_BINDER_DONE %016llx found %p\n", - proc->pid, thread->pid, (u64)cookie, - death); - if (death == NULL) { - binder_user_error("%d:%d BC_DEAD_BINDER_DONE %016llx not found\n", - proc->pid, thread->pid, (u64)cookie); - break; - } - - list_del_init(&death->work.entry); - if (death->work.type == BINDER_WORK_DEAD_BINDER_AND_CLEAR) { - death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; - if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { - list_add_tail(&death->work.entry, &thread->todo); - } else { - list_add_tail(&death->work.entry, &proc->todo); - wake_up_interruptible(&proc->wait); - } - } - } break; - + binder_call_dead_binder_done(thread, cookie); + break; + } default: pr_err("%d:%d unknown command %d\n", proc->pid, thread->pid, cmd); -- 2.2.0.rc0.207.ga3a616c _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel