Lines Matching +full:async +full:- +full:prefix

1 // SPDX-License-Identifier: GPL-2.0-only
6 * Copyright (C) 2007-2008 Google, Inc.
15 * 1) proc->outer_lock : protects binder_ref
18 * 2) node->lock : protects most fields of binder_node.
21 * 3) proc->inner_lock : protects the thread and node lists
22 * (proc->threads, proc->waiting_threads, proc->nodes)
24 * (proc->todo, thread->todo, proc->delivered_death and
25 * node->async_todo), as well as thread->transaction_stack
35 * foo_olocked() : requires node->outer_lock
36 * foo_nlocked() : requires node->lock
37 * foo_ilocked() : requires proc->inner_lock
38 * foo_oilocked(): requires proc->outer_lock and proc->inner_lock
39 * foo_nilocked(): requires node->lock and proc->inner_lock
173 (ee)->id = _id; \
174 (ee)->command = _command; \
175 (ee)->param = _param; \
232 unsigned int cur = atomic_inc_return(&log->cur); in binder_transaction_log_add()
234 if (cur >= ARRAY_SIZE(log->entry)) in binder_transaction_log_add()
235 log->full = true; in binder_transaction_log_add()
236 e = &log->entry[cur % ARRAY_SIZE(log->entry)]; in binder_transaction_log_add()
237 WRITE_ONCE(e->debug_id_done, 0); in binder_transaction_log_add()
239 * write-barrier to synchronize access to e->debug_id_done. in binder_transaction_log_add()
263 * binder_proc_lock() - Acquire outer lock for given binder_proc
266 * Acquires proc->outer_lock. Used to protect binder_ref
272 __acquires(&proc->outer_lock) in _binder_proc_lock()
276 spin_lock(&proc->outer_lock); in _binder_proc_lock()
280 * binder_proc_unlock() - Release outer lock for given binder_proc
288 __releases(&proc->outer_lock) in _binder_proc_unlock()
292 spin_unlock(&proc->outer_lock); in _binder_proc_unlock()
296 * binder_inner_proc_lock() - Acquire inner lock for given binder_proc
299 * Acquires proc->inner_lock. Used to protect todo lists
304 __acquires(&proc->inner_lock) in _binder_inner_proc_lock()
308 spin_lock(&proc->inner_lock); in _binder_inner_proc_lock()
312 * binder_inner_proc_unlock() - Release inner lock for given binder_proc
320 __releases(&proc->inner_lock) in _binder_inner_proc_unlock()
324 spin_unlock(&proc->inner_lock); in _binder_inner_proc_unlock()
328 * binder_node_lock() - Acquire spinlock for given binder_node
331 * Acquires node->lock. Used to protect binder_node fields
336 __acquires(&node->lock) in _binder_node_lock()
340 spin_lock(&node->lock); in _binder_node_lock()
344 * binder_node_unlock() - Release spinlock for given binder_proc
352 __releases(&node->lock) in _binder_node_unlock()
356 spin_unlock(&node->lock); in _binder_node_unlock()
360 * binder_node_inner_lock() - Acquire node and inner locks
363 * Acquires node->lock. If node->proc also acquires
364 * proc->inner_lock. Used to protect binder_node fields
369 __acquires(&node->lock) __acquires(&node->proc->inner_lock) in _binder_node_inner_lock()
373 spin_lock(&node->lock); in _binder_node_inner_lock()
374 if (node->proc) in _binder_node_inner_lock()
375 binder_inner_proc_lock(node->proc); in _binder_node_inner_lock()
378 __acquire(&node->proc->inner_lock); in _binder_node_inner_lock()
382 * binder_node_inner_unlock() - Release node and inner locks
390 __releases(&node->lock) __releases(&node->proc->inner_lock) in _binder_node_inner_unlock()
392 struct binder_proc *proc = node->proc; in _binder_node_inner_unlock()
400 __release(&node->proc->inner_lock); in _binder_node_inner_unlock()
401 spin_unlock(&node->lock); in _binder_node_inner_unlock()
410 * binder_worklist_empty() - Check if no items on the work list
428 * binder_enqueue_work_ilocked() - Add an item to the work list
435 * Requires the proc->inner_lock to be held.
442 BUG_ON(work->entry.next && !list_empty(&work->entry)); in binder_enqueue_work_ilocked()
443 list_add_tail(&work->entry, target_list); in binder_enqueue_work_ilocked()
447 * binder_enqueue_deferred_thread_work_ilocked() - Add deferred thread work
455 * Requires the proc->inner_lock to be held.
461 WARN_ON(!list_empty(&thread->waiting_thread_node)); in binder_enqueue_deferred_thread_work_ilocked()
462 binder_enqueue_work_ilocked(work, &thread->todo); in binder_enqueue_deferred_thread_work_ilocked()
466 * binder_enqueue_thread_work_ilocked() - Add an item to the thread work list
473 * Requires the proc->inner_lock to be held.
479 WARN_ON(!list_empty(&thread->waiting_thread_node)); in binder_enqueue_thread_work_ilocked()
480 binder_enqueue_work_ilocked(work, &thread->todo); in binder_enqueue_thread_work_ilocked()
482 /* (e)poll-based threads require an explicit wakeup signal when in binder_enqueue_thread_work_ilocked()
487 if (thread->looper & BINDER_LOOPER_STATE_POLL && in binder_enqueue_thread_work_ilocked()
488 thread->pid == current->pid && !thread->process_todo) in binder_enqueue_thread_work_ilocked()
489 wake_up_interruptible_sync(&thread->wait); in binder_enqueue_thread_work_ilocked()
491 thread->process_todo = true; in binder_enqueue_thread_work_ilocked()
495 * binder_enqueue_thread_work() - Add an item to the thread work list
506 binder_inner_proc_lock(thread->proc); in binder_enqueue_thread_work()
508 binder_inner_proc_unlock(thread->proc); in binder_enqueue_thread_work()
514 list_del_init(&work->entry); in binder_dequeue_work_ilocked()
518 * binder_dequeue_work() - Removes an item from the work list
540 list_del_init(&w->entry); in binder_dequeue_work_head_ilocked()
553 return thread->process_todo || in binder_has_work_ilocked()
554 thread->looper_need_return || in binder_has_work_ilocked()
556 !binder_worklist_empty_ilocked(&thread->proc->todo)); in binder_has_work_ilocked()
563 binder_inner_proc_lock(thread->proc); in binder_has_work()
565 binder_inner_proc_unlock(thread->proc); in binder_has_work()
572 return !thread->transaction_stack && in binder_available_for_proc_work_ilocked()
573 binder_worklist_empty_ilocked(&thread->todo); in binder_available_for_proc_work_ilocked()
582 for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) { in binder_wakeup_poll_threads_ilocked()
584 if (thread->looper & BINDER_LOOPER_STATE_POLL && in binder_wakeup_poll_threads_ilocked()
587 wake_up_interruptible_sync(&thread->wait); in binder_wakeup_poll_threads_ilocked()
589 wake_up_interruptible(&thread->wait); in binder_wakeup_poll_threads_ilocked()
595 * binder_select_thread_ilocked() - selects a thread for doing proc work.
611 assert_spin_locked(&proc->inner_lock); in binder_select_thread_ilocked()
612 thread = list_first_entry_or_null(&proc->waiting_threads, in binder_select_thread_ilocked()
617 list_del_init(&thread->waiting_thread_node); in binder_select_thread_ilocked()
623 * binder_wakeup_thread_ilocked() - wakes up a thread for doing proc work.
625 * @thread: specific thread to wake-up (may be NULL)
626 * @sync: whether to do a synchronous wake-up
629 * The caller may provide a specific thread to wake-up in
642 assert_spin_locked(&proc->inner_lock); in binder_wakeup_thread_ilocked()
646 wake_up_interruptible_sync(&thread->wait); in binder_wakeup_thread_ilocked()
648 wake_up_interruptible(&thread->wait); in binder_wakeup_thread_ilocked()
662 * a thread that called into (e)poll is handling non-binder in binder_wakeup_thread_ilocked()
686 current->pid, nice, min_nice); in binder_set_nice()
690 binder_user_error("%d RLIMIT_NICE not set\n", current->pid); in binder_set_nice()
696 struct rb_node *n = proc->nodes.rb_node; in binder_get_node_ilocked()
699 assert_spin_locked(&proc->inner_lock); in binder_get_node_ilocked()
704 if (ptr < node->ptr) in binder_get_node_ilocked()
705 n = n->rb_left; in binder_get_node_ilocked()
706 else if (ptr > node->ptr) in binder_get_node_ilocked()
707 n = n->rb_right; in binder_get_node_ilocked()
737 struct rb_node **p = &proc->nodes.rb_node; in binder_init_node_ilocked()
740 binder_uintptr_t ptr = fp ? fp->binder : 0; in binder_init_node_ilocked()
741 binder_uintptr_t cookie = fp ? fp->cookie : 0; in binder_init_node_ilocked()
742 __u32 flags = fp ? fp->flags : 0; in binder_init_node_ilocked()
744 assert_spin_locked(&proc->inner_lock); in binder_init_node_ilocked()
751 if (ptr < node->ptr) in binder_init_node_ilocked()
752 p = &(*p)->rb_left; in binder_init_node_ilocked()
753 else if (ptr > node->ptr) in binder_init_node_ilocked()
754 p = &(*p)->rb_right; in binder_init_node_ilocked()
767 node->tmp_refs++; in binder_init_node_ilocked()
768 rb_link_node(&node->rb_node, parent, p); in binder_init_node_ilocked()
769 rb_insert_color(&node->rb_node, &proc->nodes); in binder_init_node_ilocked()
770 node->debug_id = atomic_inc_return(&binder_last_id); in binder_init_node_ilocked()
771 node->proc = proc; in binder_init_node_ilocked()
772 node->ptr = ptr; in binder_init_node_ilocked()
773 node->cookie = cookie; in binder_init_node_ilocked()
774 node->work.type = BINDER_WORK_NODE; in binder_init_node_ilocked()
775 node->min_priority = flags & FLAT_BINDER_FLAG_PRIORITY_MASK; in binder_init_node_ilocked()
776 node->accept_fds = !!(flags & FLAT_BINDER_FLAG_ACCEPTS_FDS); in binder_init_node_ilocked()
777 node->txn_security_ctx = !!(flags & FLAT_BINDER_FLAG_TXN_SECURITY_CTX); in binder_init_node_ilocked()
778 spin_lock_init(&node->lock); in binder_init_node_ilocked()
779 INIT_LIST_HEAD(&node->work.entry); in binder_init_node_ilocked()
780 INIT_LIST_HEAD(&node->async_todo); in binder_init_node_ilocked()
783 proc->pid, current->pid, node->debug_id, in binder_init_node_ilocked()
784 (u64)node->ptr, (u64)node->cookie); in binder_init_node_ilocked()
819 struct binder_proc *proc = node->proc; in binder_inc_node_nilocked()
821 assert_spin_locked(&node->lock); in binder_inc_node_nilocked()
823 assert_spin_locked(&proc->inner_lock); in binder_inc_node_nilocked()
827 node->internal_strong_refs == 0 && in binder_inc_node_nilocked()
828 !(node->proc && in binder_inc_node_nilocked()
829 node == node->proc->context->binder_context_mgr_node && in binder_inc_node_nilocked()
830 node->has_strong_ref)) { in binder_inc_node_nilocked()
832 node->debug_id); in binder_inc_node_nilocked()
833 return -EINVAL; in binder_inc_node_nilocked()
835 node->internal_strong_refs++; in binder_inc_node_nilocked()
837 node->local_strong_refs++; in binder_inc_node_nilocked()
838 if (!node->has_strong_ref && target_list) { in binder_inc_node_nilocked()
841 binder_dequeue_work_ilocked(&node->work); in binder_inc_node_nilocked()
842 BUG_ON(&thread->todo != target_list); in binder_inc_node_nilocked()
844 &node->work); in binder_inc_node_nilocked()
848 node->local_weak_refs++; in binder_inc_node_nilocked()
849 if (!node->has_weak_ref && list_empty(&node->work.entry)) { in binder_inc_node_nilocked()
852 node->debug_id); in binder_inc_node_nilocked()
853 return -EINVAL; in binder_inc_node_nilocked()
858 binder_enqueue_work_ilocked(&node->work, target_list); in binder_inc_node_nilocked()
879 struct binder_proc *proc = node->proc; in binder_dec_node_nilocked()
881 assert_spin_locked(&node->lock); in binder_dec_node_nilocked()
883 assert_spin_locked(&proc->inner_lock); in binder_dec_node_nilocked()
886 node->internal_strong_refs--; in binder_dec_node_nilocked()
888 node->local_strong_refs--; in binder_dec_node_nilocked()
889 if (node->local_strong_refs || node->internal_strong_refs) in binder_dec_node_nilocked()
893 node->local_weak_refs--; in binder_dec_node_nilocked()
894 if (node->local_weak_refs || node->tmp_refs || in binder_dec_node_nilocked()
895 !hlist_empty(&node->refs)) in binder_dec_node_nilocked()
899 if (proc && (node->has_strong_ref || node->has_weak_ref)) { in binder_dec_node_nilocked()
900 if (list_empty(&node->work.entry)) { in binder_dec_node_nilocked()
901 binder_enqueue_work_ilocked(&node->work, &proc->todo); in binder_dec_node_nilocked()
905 if (hlist_empty(&node->refs) && !node->local_strong_refs && in binder_dec_node_nilocked()
906 !node->local_weak_refs && !node->tmp_refs) { in binder_dec_node_nilocked()
908 binder_dequeue_work_ilocked(&node->work); in binder_dec_node_nilocked()
909 rb_erase(&node->rb_node, &proc->nodes); in binder_dec_node_nilocked()
912 node->debug_id); in binder_dec_node_nilocked()
914 BUG_ON(!list_empty(&node->work.entry)); in binder_dec_node_nilocked()
920 if (node->tmp_refs) { in binder_dec_node_nilocked()
924 hlist_del(&node->dead_node); in binder_dec_node_nilocked()
928 node->debug_id); in binder_dec_node_nilocked()
954 node->tmp_refs++; in binder_inc_node_tmpref_ilocked()
958 * binder_inc_node_tmpref() - take a temporary reference on node
965 * (node->proc is NULL), use binder_dead_nodes_lock to protect
966 * node->tmp_refs against dead-node-only cases where the node
973 if (node->proc) in binder_inc_node_tmpref()
974 binder_inner_proc_lock(node->proc); in binder_inc_node_tmpref()
978 if (node->proc) in binder_inc_node_tmpref()
979 binder_inner_proc_unlock(node->proc); in binder_inc_node_tmpref()
986 * binder_dec_node_tmpref() - remove a temporary reference on node
996 if (!node->proc) in binder_dec_node_tmpref()
1000 node->tmp_refs--; in binder_dec_node_tmpref()
1001 BUG_ON(node->tmp_refs < 0); in binder_dec_node_tmpref()
1002 if (!node->proc) in binder_dec_node_tmpref()
1026 struct rb_node *n = proc->refs_by_desc.rb_node; in binder_get_ref_olocked()
1032 if (desc < ref->data.desc) { in binder_get_ref_olocked()
1033 n = n->rb_left; in binder_get_ref_olocked()
1034 } else if (desc > ref->data.desc) { in binder_get_ref_olocked()
1035 n = n->rb_right; in binder_get_ref_olocked()
1036 } else if (need_strong_ref && !ref->data.strong) { in binder_get_ref_olocked()
1054 for (n = rb_first(&proc->refs_by_desc); n; n = rb_next(n)) { in slow_desc_lookup_olocked()
1056 if (ref->data.desc > desc) in slow_desc_lookup_olocked()
1058 desc = ref->data.desc + 1; in slow_desc_lookup_olocked()
1065 * Find an available reference descriptor ID. The proc->outer_lock might
1066 * be released in the process, in which case -EAGAIN is returned and the
1073 struct dbitmap *dmap = &proc->dmap; in get_ref_desc_olocked()
1078 offset = (node == proc->context->binder_context_mgr_node) ? 0 : 1; in get_ref_desc_olocked()
1091 * The dbitmap is full and needs to grow. The proc->outer_lock in get_ref_desc_olocked()
1100 return -EAGAIN; in get_ref_desc_olocked()
1104 * binder_get_ref_for_node_olocked() - get the ref associated with given node
1117 * returned ref would be different than the passed-in
1132 p = &proc->refs_by_node.rb_node; in binder_get_ref_for_node_olocked()
1138 if (node < ref->node) in binder_get_ref_for_node_olocked()
1139 p = &(*p)->rb_left; in binder_get_ref_for_node_olocked()
1140 else if (node > ref->node) in binder_get_ref_for_node_olocked()
1141 p = &(*p)->rb_right; in binder_get_ref_for_node_olocked()
1148 /* might release the proc->outer_lock */ in binder_get_ref_for_node_olocked()
1149 if (get_ref_desc_olocked(proc, node, &desc) == -EAGAIN) in binder_get_ref_for_node_olocked()
1153 new_ref->data.debug_id = atomic_inc_return(&binder_last_id); in binder_get_ref_for_node_olocked()
1154 new_ref->proc = proc; in binder_get_ref_for_node_olocked()
1155 new_ref->node = node; in binder_get_ref_for_node_olocked()
1156 rb_link_node(&new_ref->rb_node_node, parent, p); in binder_get_ref_for_node_olocked()
1157 rb_insert_color(&new_ref->rb_node_node, &proc->refs_by_node); in binder_get_ref_for_node_olocked()
1159 new_ref->data.desc = desc; in binder_get_ref_for_node_olocked()
1160 p = &proc->refs_by_desc.rb_node; in binder_get_ref_for_node_olocked()
1165 if (new_ref->data.desc < ref->data.desc) in binder_get_ref_for_node_olocked()
1166 p = &(*p)->rb_left; in binder_get_ref_for_node_olocked()
1167 else if (new_ref->data.desc > ref->data.desc) in binder_get_ref_for_node_olocked()
1168 p = &(*p)->rb_right; in binder_get_ref_for_node_olocked()
1172 rb_link_node(&new_ref->rb_node_desc, parent, p); in binder_get_ref_for_node_olocked()
1173 rb_insert_color(&new_ref->rb_node_desc, &proc->refs_by_desc); in binder_get_ref_for_node_olocked()
1176 hlist_add_head(&new_ref->node_entry, &node->refs); in binder_get_ref_for_node_olocked()
1180 proc->pid, new_ref->data.debug_id, new_ref->data.desc, in binder_get_ref_for_node_olocked()
1181 node->debug_id); in binder_get_ref_for_node_olocked()
1188 struct dbitmap *dmap = &ref->proc->dmap; in binder_cleanup_ref_olocked()
1193 ref->proc->pid, ref->data.debug_id, ref->data.desc, in binder_cleanup_ref_olocked()
1194 ref->node->debug_id); in binder_cleanup_ref_olocked()
1197 dbitmap_clear_bit(dmap, ref->data.desc); in binder_cleanup_ref_olocked()
1198 rb_erase(&ref->rb_node_desc, &ref->proc->refs_by_desc); in binder_cleanup_ref_olocked()
1199 rb_erase(&ref->rb_node_node, &ref->proc->refs_by_node); in binder_cleanup_ref_olocked()
1201 binder_node_inner_lock(ref->node); in binder_cleanup_ref_olocked()
1202 if (ref->data.strong) in binder_cleanup_ref_olocked()
1203 binder_dec_node_nilocked(ref->node, 1, 1); in binder_cleanup_ref_olocked()
1205 hlist_del(&ref->node_entry); in binder_cleanup_ref_olocked()
1206 delete_node = binder_dec_node_nilocked(ref->node, 0, 1); in binder_cleanup_ref_olocked()
1207 binder_node_inner_unlock(ref->node); in binder_cleanup_ref_olocked()
1209 * Clear ref->node unless we want the caller to free the node in binder_cleanup_ref_olocked()
1213 * The caller uses ref->node to determine in binder_cleanup_ref_olocked()
1217 ref->node = NULL; in binder_cleanup_ref_olocked()
1220 if (ref->death) { in binder_cleanup_ref_olocked()
1223 ref->proc->pid, ref->data.debug_id, in binder_cleanup_ref_olocked()
1224 ref->data.desc); in binder_cleanup_ref_olocked()
1225 binder_dequeue_work(ref->proc, &ref->death->work); in binder_cleanup_ref_olocked()
1232 * binder_inc_ref_olocked() - increment the ref for given handle
1237 * Increment the ref. @ref->proc->outer_lock must be held on entry
1247 if (ref->data.strong == 0) { in binder_inc_ref_olocked()
1248 ret = binder_inc_node(ref->node, 1, 1, target_list); in binder_inc_ref_olocked()
1252 ref->data.strong++; in binder_inc_ref_olocked()
1254 if (ref->data.weak == 0) { in binder_inc_ref_olocked()
1255 ret = binder_inc_node(ref->node, 0, 1, target_list); in binder_inc_ref_olocked()
1259 ref->data.weak++; in binder_inc_ref_olocked()
1265 * binder_dec_ref_olocked() - dec the ref for given handle
1276 if (ref->data.strong == 0) { in binder_dec_ref_olocked()
1278 ref->proc->pid, ref->data.debug_id, in binder_dec_ref_olocked()
1279 ref->data.desc, ref->data.strong, in binder_dec_ref_olocked()
1280 ref->data.weak); in binder_dec_ref_olocked()
1283 ref->data.strong--; in binder_dec_ref_olocked()
1284 if (ref->data.strong == 0) in binder_dec_ref_olocked()
1285 binder_dec_node(ref->node, strong, 1); in binder_dec_ref_olocked()
1287 if (ref->data.weak == 0) { in binder_dec_ref_olocked()
1289 ref->proc->pid, ref->data.debug_id, in binder_dec_ref_olocked()
1290 ref->data.desc, ref->data.strong, in binder_dec_ref_olocked()
1291 ref->data.weak); in binder_dec_ref_olocked()
1294 ref->data.weak--; in binder_dec_ref_olocked()
1296 if (ref->data.strong == 0 && ref->data.weak == 0) { in binder_dec_ref_olocked()
1304 * binder_get_node_from_ref() - get the node from the given proc/desc
1326 node = ref->node; in binder_get_node_from_ref()
1333 *rdata = ref->data; in binder_get_node_from_ref()
1344 * binder_free_ref() - free the binder_ref
1347 * Free the binder_ref. Free the binder_node indicated by ref->node
1348 * (if non-NULL) and the binder_ref_death indicated by ref->death.
1352 if (ref->node) in binder_free_ref()
1353 binder_free_node(ref->node); in binder_free_ref()
1354 kfree(ref->death); in binder_free_ref()
1355 kfree(ref->freeze); in binder_free_ref()
1366 nbits = dbitmap_shrink_nbits(&proc->dmap); in try_shrink_dmap()
1374 dbitmap_shrink(&proc->dmap, new, nbits); in try_shrink_dmap()
1379 * binder_update_ref_for_handle() - inc/dec the ref for given handle
1402 ret = -EINVAL; in binder_update_ref_for_handle()
1411 *rdata = ref->data; in binder_update_ref_for_handle()
1426 * binder_dec_ref_for_handle() - dec the ref for given handle
1444 * binder_inc_ref_for_node() - increment the ref for given proc/node
1472 return -ENOMEM; in binder_inc_ref_for_node()
1477 *rdata = ref->data; in binder_inc_ref_for_node()
1504 assert_spin_locked(&target_thread->proc->inner_lock); in binder_pop_transaction_ilocked()
1505 BUG_ON(target_thread->transaction_stack != t); in binder_pop_transaction_ilocked()
1506 BUG_ON(target_thread->transaction_stack->from != target_thread); in binder_pop_transaction_ilocked()
1507 target_thread->transaction_stack = in binder_pop_transaction_ilocked()
1508 target_thread->transaction_stack->from_parent; in binder_pop_transaction_ilocked()
1509 t->from = NULL; in binder_pop_transaction_ilocked()
1513 * binder_thread_dec_tmpref() - decrement thread->tmp_ref
1518 * extract t->from from a binder_transaction and keep the thread
1519 * indicated by t->from from being freed. When done with that
1528 * it cannot reach zero or thread->is_dead is false in binder_thread_dec_tmpref()
1530 binder_inner_proc_lock(thread->proc); in binder_thread_dec_tmpref()
1531 atomic_dec(&thread->tmp_ref); in binder_thread_dec_tmpref()
1532 if (thread->is_dead && !atomic_read(&thread->tmp_ref)) { in binder_thread_dec_tmpref()
1533 binder_inner_proc_unlock(thread->proc); in binder_thread_dec_tmpref()
1537 binder_inner_proc_unlock(thread->proc); in binder_thread_dec_tmpref()
1541 * binder_proc_dec_tmpref() - decrement proc->tmp_ref
1545 * handle a transaction. proc->tmp_ref is incremented when
1546 * creating a new transaction or the binder_proc is currently in-use
1550 * been released and not currently in-use to process a transaction).
1555 proc->tmp_ref--; in binder_proc_dec_tmpref()
1556 if (proc->is_dead && RB_EMPTY_ROOT(&proc->threads) && in binder_proc_dec_tmpref()
1557 !proc->tmp_ref) { in binder_proc_dec_tmpref()
1566 * binder_get_txn_from() - safely extract the "from" thread in transaction
1567 * @t: binder transaction for t->from
1573 * Return: the value of t->from
1580 spin_lock(&t->lock); in binder_get_txn_from()
1581 from = t->from; in binder_get_txn_from()
1583 atomic_inc(&from->tmp_ref); in binder_get_txn_from()
1584 spin_unlock(&t->lock); in binder_get_txn_from()
1589 * binder_get_txn_from_and_acq_inner() - get t->from and acquire inner lock
1590 * @t: binder transaction for t->from
1592 * Same as binder_get_txn_from() except it also acquires the proc->inner_lock
1597 * Return: the value of t->from
1601 __acquires(&t->from->proc->inner_lock) in binder_get_txn_from_and_acq_inner()
1607 __acquire(&from->proc->inner_lock); in binder_get_txn_from_and_acq_inner()
1610 binder_inner_proc_lock(from->proc); in binder_get_txn_from_and_acq_inner()
1611 if (t->from) { in binder_get_txn_from_and_acq_inner()
1612 BUG_ON(from != t->from); in binder_get_txn_from_and_acq_inner()
1615 binder_inner_proc_unlock(from->proc); in binder_get_txn_from_and_acq_inner()
1616 __acquire(&from->proc->inner_lock); in binder_get_txn_from_and_acq_inner()
1622 * binder_free_txn_fixups() - free unprocessed fd fixups
1623 * @t: binder transaction for t->from
1629 * processed -- in that case, the list will be empty.
1635 list_for_each_entry_safe(fixup, tmp, &t->fd_fixups, fixup_entry) { in binder_free_txn_fixups()
1636 fput(fixup->file); in binder_free_txn_fixups()
1637 if (fixup->target_fd >= 0) in binder_free_txn_fixups()
1638 put_unused_fd(fixup->target_fd); in binder_free_txn_fixups()
1639 list_del(&fixup->fixup_entry); in binder_free_txn_fixups()
1648 spin_lock(&t->lock); in binder_txn_latency_free()
1649 from_proc = t->from ? t->from->proc->pid : 0; in binder_txn_latency_free()
1650 from_thread = t->from ? t->from->pid : 0; in binder_txn_latency_free()
1651 to_proc = t->to_proc ? t->to_proc->pid : 0; in binder_txn_latency_free()
1652 to_thread = t->to_thread ? t->to_thread->pid : 0; in binder_txn_latency_free()
1653 spin_unlock(&t->lock); in binder_txn_latency_free()
1660 struct binder_proc *target_proc = t->to_proc; in binder_free_transaction()
1664 target_proc->outstanding_txns--; in binder_free_transaction()
1665 if (target_proc->outstanding_txns < 0) in binder_free_transaction()
1667 __func__, target_proc->outstanding_txns); in binder_free_transaction()
1668 if (!target_proc->outstanding_txns && target_proc->is_frozen) in binder_free_transaction()
1669 wake_up_interruptible_all(&target_proc->freeze_wait); in binder_free_transaction()
1670 if (t->buffer) in binder_free_transaction()
1671 t->buffer->transaction = NULL; in binder_free_transaction()
1678 * t->buffer->transaction has already been cleared. in binder_free_transaction()
1691 BUG_ON(t->flags & TF_ONE_WAY); in binder_send_failed_reply()
1697 t->debug_id, in binder_send_failed_reply()
1698 target_thread->proc->pid, in binder_send_failed_reply()
1699 target_thread->pid); in binder_send_failed_reply()
1702 if (target_thread->reply_error.cmd == BR_OK) { in binder_send_failed_reply()
1703 target_thread->reply_error.cmd = error_code; in binder_send_failed_reply()
1706 &target_thread->reply_error.work); in binder_send_failed_reply()
1707 wake_up_interruptible(&target_thread->wait); in binder_send_failed_reply()
1716 target_thread->reply_error.cmd); in binder_send_failed_reply()
1718 binder_inner_proc_unlock(target_thread->proc); in binder_send_failed_reply()
1723 __release(&target_thread->proc->inner_lock); in binder_send_failed_reply()
1724 next = t->from_parent; in binder_send_failed_reply()
1728 t->debug_id); in binder_send_failed_reply()
1738 "reply failed, no target thread -- retry %d\n", in binder_send_failed_reply()
1739 t->debug_id); in binder_send_failed_reply()
1744 * binder_cleanup_transaction() - cleans up undelivered transaction
1753 if (t->buffer->target_node && !(t->flags & TF_ONE_WAY)) { in binder_cleanup_transaction()
1758 t->debug_id, reason); in binder_cleanup_transaction()
1764 * binder_get_object() - gets object and checks for valid metadata
1789 read_size = min_t(size_t, sizeof(*object), buffer->data_size - offset); in binder_get_object()
1790 if (offset > buffer->data_size || read_size < sizeof(*hdr) || in binder_get_object()
1798 if (binder_alloc_copy_from_buffer(&proc->alloc, object, buffer, in binder_get_object()
1804 hdr = &object->hdr; in binder_get_object()
1805 switch (hdr->type) { in binder_get_object()
1824 if (offset <= buffer->data_size - object_size && in binder_get_object()
1825 buffer->data_size >= object_size) in binder_get_object()
1832 * binder_validate_ptr() - validates binder_buffer_object in a binder_buffer.
1850 * If @object_offsetp is non-NULL, then the offset within
1870 if (binder_alloc_copy_from_buffer(&proc->alloc, &object_offset, in binder_validate_ptr()
1875 if (!object_size || object->hdr.type != BINDER_TYPE_PTR) in binder_validate_ptr()
1880 return &object->bbo; in binder_validate_ptr()
1884 * binder_validate_fixup() - validates pointer/fd fixups happen in order.
1950 if ((last_bbo->flags & BINDER_BUFFER_FLAG_HAS_PARENT) == 0) in binder_validate_fixup()
1952 last_min_offset = last_bbo->parent_offset + sizeof(uintptr_t); in binder_validate_fixup()
1954 sizeof(binder_size_t) * last_bbo->parent; in binder_validate_fixup()
1955 if (binder_alloc_copy_from_buffer(&proc->alloc, in binder_validate_fixup()
1965 * struct binder_task_work_cb - for deferred close
1979 * binder_do_fd_close() - close list of file descriptors
1996 fput(twcb->file); in binder_do_fd_close()
2001 * binder_deferred_fd_close() - schedule a close for the given file-descriptor
2002 * @fd: file-descriptor to close
2005 * a file-descriptor to be closed after returning from binder_ioctl().
2014 init_task_work(&twcb->twork, binder_do_fd_close); in binder_deferred_fd_close()
2015 twcb->file = file_close_fd(fd); in binder_deferred_fd_close()
2016 if (twcb->file) { in binder_deferred_fd_close()
2018 get_file(twcb->file); in binder_deferred_fd_close()
2019 filp_close(twcb->file, current->files); in binder_deferred_fd_close()
2020 task_work_add(current, &twcb->twork, TWA_RESUME); in binder_deferred_fd_close()
2032 int debug_id = buffer->debug_id; in binder_transaction_buffer_release()
2036 "%d buffer release %d, size %zd-%zd, failed at %llx\n", in binder_transaction_buffer_release()
2037 proc->pid, buffer->debug_id, in binder_transaction_buffer_release()
2038 buffer->data_size, buffer->offsets_size, in binder_transaction_buffer_release()
2041 if (buffer->target_node) in binder_transaction_buffer_release()
2042 binder_dec_node(buffer->target_node, 1, 0); in binder_transaction_buffer_release()
2044 off_start_offset = ALIGN(buffer->data_size, sizeof(void *)); in binder_transaction_buffer_release()
2053 if (!binder_alloc_copy_from_buffer(&proc->alloc, &object_offset, in binder_transaction_buffer_release()
2060 debug_id, (u64)object_offset, buffer->data_size); in binder_transaction_buffer_release()
2064 switch (hdr->type) { in binder_transaction_buffer_release()
2071 node = binder_get_node(proc, fp->binder); in binder_transaction_buffer_release()
2074 debug_id, (u64)fp->binder); in binder_transaction_buffer_release()
2079 node->debug_id, (u64)node->ptr); in binder_transaction_buffer_release()
2080 binder_dec_node(node, hdr->type == BINDER_TYPE_BINDER, in binder_transaction_buffer_release()
2091 ret = binder_dec_ref_for_handle(proc, fp->handle, in binder_transaction_buffer_release()
2092 hdr->type == BINDER_TYPE_HANDLE, &rdata); in binder_transaction_buffer_release()
2096 debug_id, fp->handle, ret); in binder_transaction_buffer_release()
2106 * No need to close the file here since user-space in binder_transaction_buffer_release()
2138 num_valid = (buffer_offset - off_start_offset) / in binder_transaction_buffer_release()
2142 fda->parent, in binder_transaction_buffer_release()
2151 fd_buf_size = sizeof(u32) * fda->num_fds; in binder_transaction_buffer_release()
2152 if (fda->num_fds >= SIZE_MAX / sizeof(u32)) { in binder_transaction_buffer_release()
2154 debug_id, (u64)fda->num_fds); in binder_transaction_buffer_release()
2157 if (fd_buf_size > parent->length || in binder_transaction_buffer_release()
2158 fda->parent_offset > parent->length - fd_buf_size) { in binder_transaction_buffer_release()
2161 debug_id, (u64)fda->num_fds); in binder_transaction_buffer_release()
2166 * to user-space and the @buffer element is the user in binder_transaction_buffer_release()
2171 fda_offset = parent->buffer - buffer->user_data + in binder_transaction_buffer_release()
2172 fda->parent_offset; in binder_transaction_buffer_release()
2173 for (fd_index = 0; fd_index < fda->num_fds; in binder_transaction_buffer_release()
2181 &proc->alloc, &fd, buffer, in binder_transaction_buffer_release()
2192 thread->looper_need_return = true; in binder_transaction_buffer_release()
2198 debug_id, hdr->type); in binder_transaction_buffer_release()
2212 off_end_offset = ALIGN(buffer->data_size, sizeof(void *)); in binder_release_entire_buffer()
2213 off_end_offset += buffer->offsets_size; in binder_release_entire_buffer()
2224 struct binder_proc *proc = thread->proc; in binder_translate_binder()
2225 struct binder_proc *target_proc = t->to_proc; in binder_translate_binder()
2229 node = binder_get_node(proc, fp->binder); in binder_translate_binder()
2233 return -ENOMEM; in binder_translate_binder()
2235 if (fp->cookie != node->cookie) { in binder_translate_binder()
2237 proc->pid, thread->pid, (u64)fp->binder, in binder_translate_binder()
2238 node->debug_id, (u64)fp->cookie, in binder_translate_binder()
2239 (u64)node->cookie); in binder_translate_binder()
2240 ret = -EINVAL; in binder_translate_binder()
2243 if (security_binder_transfer_binder(proc->cred, target_proc->cred)) { in binder_translate_binder()
2244 ret = -EPERM; in binder_translate_binder()
2249 fp->hdr.type == BINDER_TYPE_BINDER, in binder_translate_binder()
2250 &thread->todo, &rdata); in binder_translate_binder()
2254 if (fp->hdr.type == BINDER_TYPE_BINDER) in binder_translate_binder()
2255 fp->hdr.type = BINDER_TYPE_HANDLE; in binder_translate_binder()
2257 fp->hdr.type = BINDER_TYPE_WEAK_HANDLE; in binder_translate_binder()
2258 fp->binder = 0; in binder_translate_binder()
2259 fp->handle = rdata.desc; in binder_translate_binder()
2260 fp->cookie = 0; in binder_translate_binder()
2264 " node %d u%016llx -> ref %d desc %d\n", in binder_translate_binder()
2265 node->debug_id, (u64)node->ptr, in binder_translate_binder()
2276 struct binder_proc *proc = thread->proc; in binder_translate_handle()
2277 struct binder_proc *target_proc = t->to_proc; in binder_translate_handle()
2282 node = binder_get_node_from_ref(proc, fp->handle, in binder_translate_handle()
2283 fp->hdr.type == BINDER_TYPE_HANDLE, &src_rdata); in binder_translate_handle()
2286 proc->pid, thread->pid, fp->handle); in binder_translate_handle()
2287 return -EINVAL; in binder_translate_handle()
2289 if (security_binder_transfer_binder(proc->cred, target_proc->cred)) { in binder_translate_handle()
2290 ret = -EPERM; in binder_translate_handle()
2295 if (node->proc == target_proc) { in binder_translate_handle()
2296 if (fp->hdr.type == BINDER_TYPE_HANDLE) in binder_translate_handle()
2297 fp->hdr.type = BINDER_TYPE_BINDER; in binder_translate_handle()
2299 fp->hdr.type = BINDER_TYPE_WEAK_BINDER; in binder_translate_handle()
2300 fp->binder = node->ptr; in binder_translate_handle()
2301 fp->cookie = node->cookie; in binder_translate_handle()
2302 if (node->proc) in binder_translate_handle()
2303 binder_inner_proc_lock(node->proc); in binder_translate_handle()
2305 __acquire(&node->proc->inner_lock); in binder_translate_handle()
2307 fp->hdr.type == BINDER_TYPE_BINDER, in binder_translate_handle()
2309 if (node->proc) in binder_translate_handle()
2310 binder_inner_proc_unlock(node->proc); in binder_translate_handle()
2312 __release(&node->proc->inner_lock); in binder_translate_handle()
2315 " ref %d desc %d -> node %d u%016llx\n", in binder_translate_handle()
2316 src_rdata.debug_id, src_rdata.desc, node->debug_id, in binder_translate_handle()
2317 (u64)node->ptr); in binder_translate_handle()
2324 fp->hdr.type == BINDER_TYPE_HANDLE, in binder_translate_handle()
2329 fp->binder = 0; in binder_translate_handle()
2330 fp->handle = dest_rdata.desc; in binder_translate_handle()
2331 fp->cookie = 0; in binder_translate_handle()
2335 " ref %d desc %d -> ref %d desc %d (node %d)\n", in binder_translate_handle()
2338 node->debug_id); in binder_translate_handle()
2350 struct binder_proc *proc = thread->proc; in binder_translate_fd()
2351 struct binder_proc *target_proc = t->to_proc; in binder_translate_fd()
2358 target_allows_fd = !!(in_reply_to->flags & TF_ACCEPT_FDS); in binder_translate_fd()
2360 target_allows_fd = t->buffer->target_node->accept_fds; in binder_translate_fd()
2363 proc->pid, thread->pid, in binder_translate_fd()
2366 ret = -EPERM; in binder_translate_fd()
2373 proc->pid, thread->pid, fd); in binder_translate_fd()
2374 ret = -EBADF; in binder_translate_fd()
2377 ret = security_binder_transfer_file(proc->cred, target_proc->cred, file); in binder_translate_fd()
2379 ret = -EPERM; in binder_translate_fd()
2390 ret = -ENOMEM; in binder_translate_fd()
2393 fixup->file = file; in binder_translate_fd()
2394 fixup->offset = fd_offset; in binder_translate_fd()
2395 fixup->target_fd = -1; in binder_translate_fd()
2396 trace_binder_transaction_fd_send(t, fd, fixup->offset); in binder_translate_fd()
2397 list_add_tail(&fixup->fixup_entry, &t->fd_fixups); in binder_translate_fd()
2410 * struct binder_ptr_fixup - data to be fixed-up in target buffer
2430 * struct binder_sg_copy - scatter-gather data to be copied
2450 * binder_do_deferred_txn_copies() - copy and fixup scatter-gather data
2453 * @sgc_head: list_head of scatter-gather copy list
2457 * and copying the scatter-gather data from the source process' user
2462 * Return: 0=success, else -errno
2479 while (bytes_copied < sgc->length) { in binder_do_deferred_txn_copies()
2481 size_t bytes_left = sgc->length - bytes_copied; in binder_do_deferred_txn_copies()
2482 size_t offset = sgc->offset + bytes_copied; in binder_do_deferred_txn_copies()
2487 copy_size = pf ? min(bytes_left, (size_t)pf->offset - offset) in binder_do_deferred_txn_copies()
2493 sgc->sender_uaddr + bytes_copied, in binder_do_deferred_txn_copies()
2499 if (pf->skip_size) { in binder_do_deferred_txn_copies()
2506 bytes_copied += pf->skip_size; in binder_do_deferred_txn_copies()
2512 pf->offset, in binder_do_deferred_txn_copies()
2513 &pf->fixup_data, in binder_do_deferred_txn_copies()
2514 sizeof(pf->fixup_data)); in binder_do_deferred_txn_copies()
2515 bytes_copied += sizeof(pf->fixup_data); in binder_do_deferred_txn_copies()
2517 list_del(&pf->node); in binder_do_deferred_txn_copies()
2523 list_del(&sgc->node); in binder_do_deferred_txn_copies()
2527 BUG_ON(pf->skip_size == 0); in binder_do_deferred_txn_copies()
2528 list_del(&pf->node); in binder_do_deferred_txn_copies()
2533 return ret > 0 ? -EINVAL : ret; in binder_do_deferred_txn_copies()
2537 * binder_cleanup_deferred_txn_lists() - free specified lists
2538 * @sgc_head: list_head of scatter-gather copy list
2551 list_del(&sgc->node); in binder_cleanup_deferred_txn_lists()
2555 list_del(&pf->node); in binder_cleanup_deferred_txn_lists()
2561 * binder_defer_copy() - queue a scatter-gather buffer for copy
2562 * @sgc_head: list_head of scatter-gather copy list
2567 * Specify a scatter-gather block to be copied. The actual copy must
2569 * Then the copy and fixups are done together so un-translated values
2576 * Return: 0=success, else -errno
2584 return -ENOMEM; in binder_defer_copy()
2586 bc->offset = offset; in binder_defer_copy()
2587 bc->sender_uaddr = sender_uaddr; in binder_defer_copy()
2588 bc->length = length; in binder_defer_copy()
2589 INIT_LIST_HEAD(&bc->node); in binder_defer_copy()
2592 * We are guaranteed that the deferred copies are in-order in binder_defer_copy()
2595 list_add_tail(&bc->node, sgc_head); in binder_defer_copy()
2601 * binder_add_fixup() - queue a fixup to be applied to sg copy
2608 * the scatter-gather buffers, the fixup will be copied instead of
2615 * exceptions. Since out-of-order inserts are relatively uncommon,
2619 * Return: 0=success, else -errno
2628 return -ENOMEM; in binder_add_fixup()
2630 pf->offset = offset; in binder_add_fixup()
2631 pf->fixup_data = fixup; in binder_add_fixup()
2632 pf->skip_size = skip_size; in binder_add_fixup()
2633 INIT_LIST_HEAD(&pf->node); in binder_add_fixup()
2635 /* Fixups are *mostly* added in-order, but there are some in binder_add_fixup()
2639 if (tmppf->offset < pf->offset) { in binder_add_fixup()
2640 list_add(&pf->node, &tmppf->node); in binder_add_fixup()
2648 list_add(&pf->node, pf_head); in binder_add_fixup()
2664 struct binder_proc *proc = thread->proc; in binder_translate_fd_array()
2667 if (fda->num_fds == 0) in binder_translate_fd_array()
2670 fd_buf_size = sizeof(u32) * fda->num_fds; in binder_translate_fd_array()
2671 if (fda->num_fds >= SIZE_MAX / sizeof(u32)) { in binder_translate_fd_array()
2673 proc->pid, thread->pid, (u64)fda->num_fds); in binder_translate_fd_array()
2674 return -EINVAL; in binder_translate_fd_array()
2676 if (fd_buf_size > parent->length || in binder_translate_fd_array()
2677 fda->parent_offset > parent->length - fd_buf_size) { in binder_translate_fd_array()
2680 proc->pid, thread->pid, (u64)fda->num_fds); in binder_translate_fd_array()
2681 return -EINVAL; in binder_translate_fd_array()
2685 * to user-space and the @buffer element is the user in binder_translate_fd_array()
2690 fda_offset = parent->buffer - t->buffer->user_data + in binder_translate_fd_array()
2691 fda->parent_offset; in binder_translate_fd_array()
2692 sender_ufda_base = (void __user *)(uintptr_t)sender_uparent->buffer + in binder_translate_fd_array()
2693 fda->parent_offset; in binder_translate_fd_array()
2698 proc->pid, thread->pid); in binder_translate_fd_array()
2699 return -EINVAL; in binder_translate_fd_array()
2701 ret = binder_add_fixup(pf_head, fda_offset, 0, fda->num_fds * sizeof(u32)); in binder_translate_fd_array()
2705 for (fdi = 0; fdi < fda->num_fds; fdi++) { in binder_translate_fd_array()
2715 return ret > 0 ? -EINVAL : ret; in binder_translate_fd_array()
2730 struct binder_buffer *b = t->buffer; in binder_fixup_parent()
2731 struct binder_proc *proc = thread->proc; in binder_fixup_parent()
2732 struct binder_proc *target_proc = t->to_proc; in binder_fixup_parent()
2737 if (!(bp->flags & BINDER_BUFFER_FLAG_HAS_PARENT)) in binder_fixup_parent()
2740 parent = binder_validate_ptr(target_proc, b, &object, bp->parent, in binder_fixup_parent()
2745 proc->pid, thread->pid); in binder_fixup_parent()
2746 return -EINVAL; in binder_fixup_parent()
2750 parent_offset, bp->parent_offset, in binder_fixup_parent()
2753 binder_user_error("%d:%d got transaction with out-of-order buffer fixup\n", in binder_fixup_parent()
2754 proc->pid, thread->pid); in binder_fixup_parent()
2755 return -EINVAL; in binder_fixup_parent()
2758 if (parent->length < sizeof(binder_uintptr_t) || in binder_fixup_parent()
2759 bp->parent_offset > parent->length - sizeof(binder_uintptr_t)) { in binder_fixup_parent()
2762 proc->pid, thread->pid); in binder_fixup_parent()
2763 return -EINVAL; in binder_fixup_parent()
2766 buffer_offset = bp->parent_offset + parent->buffer - b->user_data; in binder_fixup_parent()
2768 return binder_add_fixup(pf_head, buffer_offset, bp->buffer, 0); in binder_fixup_parent()
2772 * binder_can_update_transaction() - Can a txn be superseded by an updated one?
2773 * @t1: the pending async txn in the frozen process
2774 * @t2: the new async txn to supersede the outdated pending one
2782 if ((t1->flags & t2->flags & (TF_ONE_WAY | TF_UPDATE_TXN)) != in binder_can_update_transaction()
2783 (TF_ONE_WAY | TF_UPDATE_TXN) || !t1->to_proc || !t2->to_proc) in binder_can_update_transaction()
2785 if (t1->to_proc->tsk == t2->to_proc->tsk && t1->code == t2->code && in binder_can_update_transaction()
2786 t1->flags == t2->flags && t1->buffer->pid == t2->buffer->pid && in binder_can_update_transaction()
2787 t1->buffer->target_node->ptr == t2->buffer->target_node->ptr && in binder_can_update_transaction()
2788 t1->buffer->target_node->cookie == t2->buffer->target_node->cookie) in binder_can_update_transaction()
2794 * binder_find_outdated_transaction_ilocked() - Find the outdated transaction
2795 * @t: new async transaction
2801 * Requires the proc->inner_lock to be held.
2812 if (w->type != BINDER_WORK_TRANSACTION) in binder_find_outdated_transaction_ilocked()
2822 * binder_proc_transaction() - sends a transaction to a process and wakes it up
2840 * and the async transaction was successfully queued
2846 struct binder_node *node = t->buffer->target_node; in binder_proc_transaction()
2847 bool oneway = !!(t->flags & TF_ONE_WAY); in binder_proc_transaction()
2856 if (node->has_async_transaction) in binder_proc_transaction()
2859 node->has_async_transaction = true; in binder_proc_transaction()
2863 if (proc->is_frozen) { in binder_proc_transaction()
2865 proc->sync_recv |= !oneway; in binder_proc_transaction()
2866 proc->async_recv |= oneway; in binder_proc_transaction()
2869 if ((frozen && !oneway) || proc->is_dead || in binder_proc_transaction()
2870 (thread && thread->is_dead)) { in binder_proc_transaction()
2880 binder_enqueue_thread_work_ilocked(thread, &t->work); in binder_proc_transaction()
2882 binder_enqueue_work_ilocked(&t->work, &proc->todo); in binder_proc_transaction()
2884 if ((t->flags & TF_UPDATE_TXN) && frozen) { in binder_proc_transaction()
2886 &node->async_todo); in binder_proc_transaction()
2890 t->debug_id, t_outdated->debug_id); in binder_proc_transaction()
2891 list_del_init(&t_outdated->work.entry); in binder_proc_transaction()
2892 proc->outstanding_txns--; in binder_proc_transaction()
2895 binder_enqueue_work_ilocked(&t->work, &node->async_todo); in binder_proc_transaction()
2901 proc->outstanding_txns++; in binder_proc_transaction()
2910 struct binder_buffer *buffer = t_outdated->buffer; in binder_proc_transaction()
2912 t_outdated->buffer = NULL; in binder_proc_transaction()
2913 buffer->transaction = NULL; in binder_proc_transaction()
2916 binder_alloc_free_buf(&proc->alloc, buffer); in binder_proc_transaction()
2928 * binder_get_node_refs_for_txn() - Get required refs on node for txn
2930 * @procp: returns @node->proc if valid
2933 * User-space normally keeps the node alive when creating a transaction
2939 * Since user-space can cause the local strong ref to go away, we also take
2944 * Return: The target_node with refs taken or NULL if no @node->proc is NULL.
2945 * Also sets @procp if valid. If the @node->proc is NULL indicating that the
2956 if (node->proc) { in binder_get_node_refs_for_txn()
2960 node->proc->tmp_ref++; in binder_get_node_refs_for_txn()
2961 *procp = node->proc; in binder_get_node_refs_for_txn()
2976 __release(&from->proc->inner_lock); in binder_set_txn_from_error()
2981 if (from->ee.command == BR_OK) in binder_set_txn_from_error()
2982 binder_set_extended_error(&from->ee, id, command, param); in binder_set_txn_from_error()
2983 binder_inner_proc_unlock(from->proc); in binder_set_txn_from_error()
3011 struct binder_context *context = proc->context; in binder_transaction()
3019 (uintptr_t)tr->data.ptr.buffer; in binder_transaction()
3024 e->debug_id = t_debug_id; in binder_transaction()
3025 e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY); in binder_transaction()
3026 e->from_proc = proc->pid; in binder_transaction()
3027 e->from_thread = thread->pid; in binder_transaction()
3028 e->target_handle = tr->target.handle; in binder_transaction()
3029 e->data_size = tr->data_size; in binder_transaction()
3030 e->offsets_size = tr->offsets_size; in binder_transaction()
3031 strscpy(e->context_name, proc->context->name, BINDERFS_MAX_NAME); in binder_transaction()
3034 binder_set_extended_error(&thread->ee, t_debug_id, BR_OK, 0); in binder_transaction()
3039 in_reply_to = thread->transaction_stack; in binder_transaction()
3043 proc->pid, thread->pid); in binder_transaction()
3045 return_error_param = -EPROTO; in binder_transaction()
3049 if (in_reply_to->to_thread != thread) { in binder_transaction()
3050 spin_lock(&in_reply_to->lock); in binder_transaction()
3052 proc->pid, thread->pid, in_reply_to->debug_id, in binder_transaction()
3053 in_reply_to->to_proc ? in binder_transaction()
3054 in_reply_to->to_proc->pid : 0, in binder_transaction()
3055 in_reply_to->to_thread ? in binder_transaction()
3056 in_reply_to->to_thread->pid : 0); in binder_transaction()
3057 spin_unlock(&in_reply_to->lock); in binder_transaction()
3060 return_error_param = -EPROTO; in binder_transaction()
3065 thread->transaction_stack = in_reply_to->to_parent; in binder_transaction()
3067 binder_set_nice(in_reply_to->saved_priority); in binder_transaction()
3071 __release(&target_thread->proc->inner_lock); in binder_transaction()
3073 thread->pid, proc->pid); in binder_transaction()
3078 if (target_thread->transaction_stack != in_reply_to) { in binder_transaction()
3080 proc->pid, thread->pid, in binder_transaction()
3081 target_thread->transaction_stack ? in binder_transaction()
3082 target_thread->transaction_stack->debug_id : 0, in binder_transaction()
3083 in_reply_to->debug_id); in binder_transaction()
3084 binder_inner_proc_unlock(target_thread->proc); in binder_transaction()
3086 return_error_param = -EPROTO; in binder_transaction()
3092 target_proc = target_thread->proc; in binder_transaction()
3093 target_proc->tmp_ref++; in binder_transaction()
3094 binder_inner_proc_unlock(target_thread->proc); in binder_transaction()
3096 if (tr->target.handle) { in binder_transaction()
3107 ref = binder_get_ref_olocked(proc, tr->target.handle, in binder_transaction()
3111 ref->node, &target_proc, in binder_transaction()
3115 proc->pid, thread->pid, tr->target.handle); in binder_transaction()
3120 mutex_lock(&context->context_mgr_node_lock); in binder_transaction()
3121 target_node = context->binder_context_mgr_node; in binder_transaction()
3128 mutex_unlock(&context->context_mgr_node_lock); in binder_transaction()
3129 if (target_node && target_proc->pid == proc->pid) { in binder_transaction()
3131 proc->pid, thread->pid); in binder_transaction()
3133 return_error_param = -EINVAL; in binder_transaction()
3140 thread->pid, proc->pid); in binder_transaction()
3144 return_error_param = -EINVAL; in binder_transaction()
3148 e->to_node = target_node->debug_id; in binder_transaction()
3151 thread->pid, proc->pid); in binder_transaction()
3153 return_error_param = -EINVAL; in binder_transaction()
3157 if (security_binder_transaction(proc->cred, in binder_transaction()
3158 target_proc->cred) < 0) { in binder_transaction()
3160 thread->pid, proc->pid); in binder_transaction()
3162 return_error_param = -EPERM; in binder_transaction()
3168 w = list_first_entry_or_null(&thread->todo, in binder_transaction()
3170 if (!(tr->flags & TF_ONE_WAY) && w && in binder_transaction()
3171 w->type == BINDER_WORK_TRANSACTION) { in binder_transaction()
3177 * thread from proc->waiting_threads to enqueue in binder_transaction()
3182 proc->pid, thread->pid); in binder_transaction()
3185 return_error_param = -EPROTO; in binder_transaction()
3190 if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) { in binder_transaction()
3193 tmp = thread->transaction_stack; in binder_transaction()
3194 if (tmp->to_thread != thread) { in binder_transaction()
3195 spin_lock(&tmp->lock); in binder_transaction()
3197 proc->pid, thread->pid, tmp->debug_id, in binder_transaction()
3198 tmp->to_proc ? tmp->to_proc->pid : 0, in binder_transaction()
3199 tmp->to_thread ? in binder_transaction()
3200 tmp->to_thread->pid : 0); in binder_transaction()
3201 spin_unlock(&tmp->lock); in binder_transaction()
3204 return_error_param = -EPROTO; in binder_transaction()
3211 spin_lock(&tmp->lock); in binder_transaction()
3212 from = tmp->from; in binder_transaction()
3213 if (from && from->proc == target_proc) { in binder_transaction()
3214 atomic_inc(&from->tmp_ref); in binder_transaction()
3216 spin_unlock(&tmp->lock); in binder_transaction()
3219 spin_unlock(&tmp->lock); in binder_transaction()
3220 tmp = tmp->from_parent; in binder_transaction()
3226 e->to_thread = target_thread->pid; in binder_transaction()
3227 e->to_proc = target_proc->pid; in binder_transaction()
3233 thread->pid, proc->pid); in binder_transaction()
3235 return_error_param = -ENOMEM; in binder_transaction()
3239 INIT_LIST_HEAD(&t->fd_fixups); in binder_transaction()
3241 spin_lock_init(&t->lock); in binder_transaction()
3246 thread->pid, proc->pid); in binder_transaction()
3248 return_error_param = -ENOMEM; in binder_transaction()
3254 t->debug_id = t_debug_id; in binder_transaction()
3255 t->start_time = t_start_time; in binder_transaction()
3259 "%d:%d BC_REPLY %d -> %d:%d, data %016llx-%016llx size %lld-%lld-%lld\n", in binder_transaction()
3260 proc->pid, thread->pid, t->debug_id, in binder_transaction()
3261 target_proc->pid, target_thread->pid, in binder_transaction()
3262 (u64)tr->data.ptr.buffer, in binder_transaction()
3263 (u64)tr->data.ptr.offsets, in binder_transaction()
3264 (u64)tr->data_size, (u64)tr->offsets_size, in binder_transaction()
3268 "%d:%d BC_TRANSACTION %d -> %d - node %d, data %016llx-%016llx size %lld-%lld-%lld\n", in binder_transaction()
3269 proc->pid, thread->pid, t->debug_id, in binder_transaction()
3270 target_proc->pid, target_node->debug_id, in binder_transaction()
3271 (u64)tr->data.ptr.buffer, in binder_transaction()
3272 (u64)tr->data.ptr.offsets, in binder_transaction()
3273 (u64)tr->data_size, (u64)tr->offsets_size, in binder_transaction()
3276 if (!reply && !(tr->flags & TF_ONE_WAY)) in binder_transaction()
3277 t->from = thread; in binder_transaction()
3279 t->from = NULL; in binder_transaction()
3280 t->from_pid = proc->pid; in binder_transaction()
3281 t->from_tid = thread->pid; in binder_transaction()
3282 t->sender_euid = task_euid(proc->tsk); in binder_transaction()
3283 t->to_proc = target_proc; in binder_transaction()
3284 t->to_thread = target_thread; in binder_transaction()
3285 t->code = tr->code; in binder_transaction()
3286 t->flags = tr->flags; in binder_transaction()
3287 t->priority = task_nice(current); in binder_transaction()
3289 if (target_node && target_node->txn_security_ctx) { in binder_transaction()
3293 security_cred_getsecid(proc->cred, &secid); in binder_transaction()
3297 thread->pid, proc->pid); in binder_transaction()
3307 thread->pid, proc->pid); in binder_transaction()
3309 return_error_param = -EINVAL; in binder_transaction()
3317 t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size, in binder_transaction()
3318 tr->offsets_size, extra_buffers_size, in binder_transaction()
3319 !reply && (t->flags & TF_ONE_WAY)); in binder_transaction()
3320 if (IS_ERR(t->buffer)) { in binder_transaction()
3323 ret = PTR_ERR(t->buffer); in binder_transaction()
3324 s = (ret == -ESRCH) ? ": vma cleared, target dead or dying" in binder_transaction()
3325 : (ret == -ENOSPC) ? ": no space left" in binder_transaction()
3326 : (ret == -ENOMEM) ? ": memory allocation failed" in binder_transaction()
3330 return_error_param = PTR_ERR(t->buffer); in binder_transaction()
3331 return_error = return_error_param == -ESRCH ? in binder_transaction()
3334 t->buffer = NULL; in binder_transaction()
3339 size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) + in binder_transaction()
3340 ALIGN(tr->offsets_size, sizeof(void *)) + in binder_transaction()
3341 ALIGN(extra_buffers_size, sizeof(void *)) - in binder_transaction()
3344 t->security_ctx = t->buffer->user_data + buf_offset; in binder_transaction()
3345 err = binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3346 t->buffer, buf_offset, in binder_transaction()
3349 t->security_ctx = 0; in binder_transaction()
3355 t->buffer->debug_id = t->debug_id; in binder_transaction()
3356 t->buffer->transaction = t; in binder_transaction()
3357 t->buffer->target_node = target_node; in binder_transaction()
3358 t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF); in binder_transaction()
3359 trace_binder_transaction_alloc_buf(t->buffer); in binder_transaction()
3362 &target_proc->alloc, in binder_transaction()
3363 t->buffer, in binder_transaction()
3364 ALIGN(tr->data_size, sizeof(void *)), in binder_transaction()
3366 (uintptr_t)tr->data.ptr.offsets, in binder_transaction()
3367 tr->offsets_size)) { in binder_transaction()
3369 proc->pid, thread->pid); in binder_transaction()
3371 return_error_param = -EFAULT; in binder_transaction()
3375 if (!IS_ALIGNED(tr->offsets_size, sizeof(binder_size_t))) { in binder_transaction()
3377 proc->pid, thread->pid, (u64)tr->offsets_size); in binder_transaction()
3379 return_error_param = -EINVAL; in binder_transaction()
3385 proc->pid, thread->pid, in binder_transaction()
3388 return_error_param = -EINVAL; in binder_transaction()
3392 off_start_offset = ALIGN(tr->data_size, sizeof(void *)); in binder_transaction()
3394 off_end_offset = off_start_offset + tr->offsets_size; in binder_transaction()
3396 sg_buf_end_offset = sg_buf_offset + extra_buffers_size - in binder_transaction()
3407 if (binder_alloc_copy_from_buffer(&target_proc->alloc, in binder_transaction()
3409 t->buffer, in binder_transaction()
3413 thread->pid, proc->pid); in binder_transaction()
3415 return_error_param = -EINVAL; in binder_transaction()
3424 copy_size = object_offset - user_offset; in binder_transaction()
3426 object_offset > tr->data_size || in binder_transaction()
3428 &target_proc->alloc, in binder_transaction()
3429 t->buffer, user_offset, in binder_transaction()
3433 proc->pid, thread->pid); in binder_transaction()
3435 return_error_param = -EFAULT; in binder_transaction()
3440 t->buffer, object_offset, &object); in binder_transaction()
3443 proc->pid, thread->pid, in binder_transaction()
3446 (u64)t->buffer->data_size); in binder_transaction()
3448 return_error_param = -EINVAL; in binder_transaction()
3460 switch (hdr->type) { in binder_transaction()
3469 binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3470 t->buffer, in binder_transaction()
3474 thread->pid, proc->pid); in binder_transaction()
3488 binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3489 t->buffer, in binder_transaction()
3493 thread->pid, proc->pid); in binder_transaction()
3504 (uintptr_t)&fp->fd - (uintptr_t)fp; in binder_transaction()
3505 int ret = binder_translate_fd(fp->fd, fd_offset, t, in binder_transaction()
3508 fp->pad_binder = 0; in binder_transaction()
3510 binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3511 t->buffer, in binder_transaction()
3515 thread->pid, proc->pid); in binder_transaction()
3529 size_t num_valid = (buffer_offset - off_start_offset) / in binder_transaction()
3532 binder_validate_ptr(target_proc, t->buffer, in binder_transaction()
3533 &ptr_object, fda->parent, in binder_transaction()
3539 proc->pid, thread->pid); in binder_transaction()
3541 return_error_param = -EINVAL; in binder_transaction()
3545 if (!binder_validate_fixup(target_proc, t->buffer, in binder_transaction()
3548 fda->parent_offset, in binder_transaction()
3551 binder_user_error("%d:%d got transaction with out-of-order buffer fixup\n", in binder_transaction()
3552 proc->pid, thread->pid); in binder_transaction()
3554 return_error_param = -EINVAL; in binder_transaction()
3563 binder_get_object(proc, user_buffer, t->buffer, in binder_transaction()
3567 proc->pid, thread->pid, in binder_transaction()
3571 return_error_param = -EINVAL; in binder_transaction()
3580 ret = binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3581 t->buffer, in binder_transaction()
3586 thread->pid, proc->pid); in binder_transaction()
3588 return_error_param = ret > 0 ? -EINVAL : ret; in binder_transaction()
3594 fda->parent_offset + sizeof(u32) * fda->num_fds; in binder_transaction()
3599 size_t buf_left = sg_buf_end_offset - sg_buf_offset; in binder_transaction()
3602 if (bp->length > buf_left) { in binder_transaction()
3604 proc->pid, thread->pid); in binder_transaction()
3606 return_error_param = -EINVAL; in binder_transaction()
3611 (const void __user *)(uintptr_t)bp->buffer, in binder_transaction()
3612 bp->length); in binder_transaction()
3615 thread->pid, proc->pid); in binder_transaction()
3622 bp->buffer = t->buffer->user_data + sg_buf_offset; in binder_transaction()
3623 sg_buf_offset += ALIGN(bp->length, sizeof(u64)); in binder_transaction()
3625 num_valid = (buffer_offset - off_start_offset) / in binder_transaction()
3634 binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3635 t->buffer, in binder_transaction()
3639 thread->pid, proc->pid); in binder_transaction()
3650 proc->pid, thread->pid, hdr->type); in binder_transaction()
3652 return_error_param = -EINVAL; in binder_transaction()
3659 &target_proc->alloc, in binder_transaction()
3660 t->buffer, user_offset, in binder_transaction()
3662 tr->data_size - user_offset)) { in binder_transaction()
3664 proc->pid, thread->pid); in binder_transaction()
3666 return_error_param = -EFAULT; in binder_transaction()
3671 ret = binder_do_deferred_txn_copies(&target_proc->alloc, t->buffer, in binder_transaction()
3675 proc->pid, thread->pid); in binder_transaction()
3681 if (t->buffer->oneway_spam_suspect) in binder_transaction()
3682 tcomplete->type = BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT; in binder_transaction()
3684 tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; in binder_transaction()
3685 t->work.type = BINDER_WORK_TRANSACTION; in binder_transaction()
3690 if (target_thread->is_dead) { in binder_transaction()
3695 BUG_ON(t->buffer->async_transaction != 0); in binder_transaction()
3697 binder_enqueue_thread_work_ilocked(target_thread, &t->work); in binder_transaction()
3698 target_proc->outstanding_txns++; in binder_transaction()
3700 wake_up_interruptible_sync(&target_thread->wait); in binder_transaction()
3702 } else if (!(t->flags & TF_ONE_WAY)) { in binder_transaction()
3703 BUG_ON(t->buffer->async_transaction != 0); in binder_transaction()
3713 t->need_reply = 1; in binder_transaction()
3714 t->from_parent = thread->transaction_stack; in binder_transaction()
3715 thread->transaction_stack = t; in binder_transaction()
3727 BUG_ON(t->buffer->async_transaction != 1); in binder_transaction()
3730 * Let the caller know when async transaction reaches a frozen in binder_transaction()
3735 tcomplete->type = BINDER_WORK_TRANSACTION_PENDING; in binder_transaction()
3751 WRITE_ONCE(e->debug_id_done, t_debug_id); in binder_transaction()
3756 thread->pid, proc->pid); in binder_transaction()
3766 trace_binder_transaction_failed_buffer_release(t->buffer); in binder_transaction()
3767 binder_transaction_buffer_release(target_proc, NULL, t->buffer, in binder_transaction()
3772 t->buffer->transaction = NULL; in binder_transaction()
3773 binder_alloc_free_buf(&target_proc->alloc, t->buffer); in binder_transaction()
3798 "%d:%d transaction %s to %d:%d failed %d/%d/%d, size %lld-%lld line %d\n", in binder_transaction()
3799 proc->pid, thread->pid, reply ? "reply" : in binder_transaction()
3800 (tr->flags & TF_ONE_WAY ? "async" : "call"), in binder_transaction()
3801 target_proc ? target_proc->pid : 0, in binder_transaction()
3802 target_thread ? target_thread->pid : 0, in binder_transaction()
3804 (u64)tr->data_size, (u64)tr->offsets_size, in binder_transaction()
3815 e->return_error = return_error; in binder_transaction()
3816 e->return_error_param = return_error_param; in binder_transaction()
3817 e->return_error_line = return_error_line; in binder_transaction()
3825 WRITE_ONCE(e->debug_id_done, t_debug_id); in binder_transaction()
3826 WRITE_ONCE(fe->debug_id_done, t_debug_id); in binder_transaction()
3829 BUG_ON(thread->return_error.cmd != BR_OK); in binder_transaction()
3833 thread->return_error.cmd = BR_TRANSACTION_COMPLETE; in binder_transaction()
3834 binder_enqueue_thread_work(thread, &thread->return_error.work); in binder_transaction()
3838 binder_set_extended_error(&thread->ee, t_debug_id, in binder_transaction()
3841 thread->return_error.cmd = return_error; in binder_transaction()
3842 binder_enqueue_thread_work(thread, &thread->return_error.work); in binder_transaction()
3857 return -ENOMEM; in binder_request_freeze_notification()
3859 ref = binder_get_ref_olocked(proc, handle_cookie->handle, false); in binder_request_freeze_notification()
3862 proc->pid, thread->pid, handle_cookie->handle); in binder_request_freeze_notification()
3865 return -EINVAL; in binder_request_freeze_notification()
3868 binder_node_lock(ref->node); in binder_request_freeze_notification()
3870 if (ref->freeze || !ref->node->proc) { in binder_request_freeze_notification()
3872 proc->pid, thread->pid, in binder_request_freeze_notification()
3873 ref->freeze ? "already set" : "dead node"); in binder_request_freeze_notification()
3874 binder_node_unlock(ref->node); in binder_request_freeze_notification()
3877 return -EINVAL; in binder_request_freeze_notification()
3879 binder_inner_proc_lock(ref->node->proc); in binder_request_freeze_notification()
3880 is_frozen = ref->node->proc->is_frozen; in binder_request_freeze_notification()
3881 binder_inner_proc_unlock(ref->node->proc); in binder_request_freeze_notification()
3884 INIT_LIST_HEAD(&freeze->work.entry); in binder_request_freeze_notification()
3885 freeze->cookie = handle_cookie->cookie; in binder_request_freeze_notification()
3886 freeze->work.type = BINDER_WORK_FROZEN_BINDER; in binder_request_freeze_notification()
3887 freeze->is_frozen = is_frozen; in binder_request_freeze_notification()
3889 ref->freeze = freeze; in binder_request_freeze_notification()
3892 binder_enqueue_work_ilocked(&ref->freeze->work, &proc->todo); in binder_request_freeze_notification()
3896 binder_node_unlock(ref->node); in binder_request_freeze_notification()
3910 ref = binder_get_ref_olocked(proc, handle_cookie->handle, false); in binder_clear_freeze_notification()
3913 proc->pid, thread->pid, handle_cookie->handle); in binder_clear_freeze_notification()
3915 return -EINVAL; in binder_clear_freeze_notification()
3918 binder_node_lock(ref->node); in binder_clear_freeze_notification()
3920 if (!ref->freeze) { in binder_clear_freeze_notification()
3922 proc->pid, thread->pid); in binder_clear_freeze_notification()
3923 binder_node_unlock(ref->node); in binder_clear_freeze_notification()
3925 return -EINVAL; in binder_clear_freeze_notification()
3927 freeze = ref->freeze; in binder_clear_freeze_notification()
3929 if (freeze->cookie != handle_cookie->cookie) { in binder_clear_freeze_notification()
3931 proc->pid, thread->pid, (u64)freeze->cookie, in binder_clear_freeze_notification()
3932 (u64)handle_cookie->cookie); in binder_clear_freeze_notification()
3934 binder_node_unlock(ref->node); in binder_clear_freeze_notification()
3936 return -EINVAL; in binder_clear_freeze_notification()
3938 ref->freeze = NULL; in binder_clear_freeze_notification()
3947 freeze->work.type = BINDER_WORK_CLEAR_FREEZE_NOTIFICATION; in binder_clear_freeze_notification()
3948 if (list_empty(&freeze->work.entry)) { in binder_clear_freeze_notification()
3949 binder_enqueue_work_ilocked(&freeze->work, &proc->todo); in binder_clear_freeze_notification()
3951 } else if (freeze->sent) { in binder_clear_freeze_notification()
3952 freeze->resend = true; in binder_clear_freeze_notification()
3955 binder_node_unlock(ref->node); in binder_clear_freeze_notification()
3969 list_for_each_entry(w, &proc->delivered_freeze, entry) { in binder_freeze_notification_done()
3973 if (tmp_freeze->cookie == cookie) { in binder_freeze_notification_done()
3980 proc->pid, thread->pid, (u64)cookie); in binder_freeze_notification_done()
3982 return -EINVAL; in binder_freeze_notification_done()
3984 binder_dequeue_work_ilocked(&freeze->work); in binder_freeze_notification_done()
3985 freeze->sent = false; in binder_freeze_notification_done()
3986 if (freeze->resend) { in binder_freeze_notification_done()
3987 freeze->resend = false; in binder_freeze_notification_done()
3988 binder_enqueue_work_ilocked(&freeze->work, &proc->todo); in binder_freeze_notification_done()
3996 * binder_free_buf() - free the specified buffer
4001 * If buffer for an async transaction, enqueue the next async
4012 if (buffer->transaction) { in binder_free_buf()
4013 buffer->transaction->buffer = NULL; in binder_free_buf()
4014 buffer->transaction = NULL; in binder_free_buf()
4017 if (buffer->async_transaction && buffer->target_node) { in binder_free_buf()
4021 buf_node = buffer->target_node; in binder_free_buf()
4023 BUG_ON(!buf_node->has_async_transaction); in binder_free_buf()
4024 BUG_ON(buf_node->proc != proc); in binder_free_buf()
4026 &buf_node->async_todo); in binder_free_buf()
4028 buf_node->has_async_transaction = false; in binder_free_buf()
4031 w, &proc->todo); in binder_free_buf()
4038 binder_alloc_free_buf(&proc->alloc, buffer); in binder_free_buf()
4047 struct binder_context *context = proc->context; in binder_thread_write()
4052 while (ptr < end && thread->return_error.cmd == BR_OK) { in binder_thread_write()
4056 return -EFAULT; in binder_thread_write()
4061 atomic_inc(&proc->stats.bc[_IOC_NR(cmd)]); in binder_thread_write()
4062 atomic_inc(&thread->stats.bc[_IOC_NR(cmd)]); in binder_thread_write()
4076 return -EFAULT; in binder_thread_write()
4079 ret = -1; in binder_thread_write()
4083 mutex_lock(&context->context_mgr_node_lock); in binder_thread_write()
4084 ctx_mgr_node = context->binder_context_mgr_node; in binder_thread_write()
4086 if (ctx_mgr_node->proc == proc) { in binder_thread_write()
4088 proc->pid, thread->pid); in binder_thread_write()
4089 mutex_unlock(&context->context_mgr_node_lock); in binder_thread_write()
4090 return -EINVAL; in binder_thread_write()
4096 mutex_unlock(&context->context_mgr_node_lock); in binder_thread_write()
4104 proc->pid, thread->pid, in binder_thread_write()
4124 proc->pid, thread->pid, debug_string, in binder_thread_write()
4130 proc->pid, thread->pid, debug_string, in binder_thread_write()
4143 return -EFAULT; in binder_thread_write()
4146 return -EFAULT; in binder_thread_write()
4151 proc->pid, thread->pid, in binder_thread_write()
4158 if (cookie != node->cookie) { in binder_thread_write()
4160 proc->pid, thread->pid, in binder_thread_write()
4163 (u64)node_ptr, node->debug_id, in binder_thread_write()
4164 (u64)cookie, (u64)node->cookie); in binder_thread_write()
4170 if (node->pending_strong_ref == 0) { in binder_thread_write()
4172 proc->pid, thread->pid, in binder_thread_write()
4173 node->debug_id); in binder_thread_write()
4178 node->pending_strong_ref = 0; in binder_thread_write()
4180 if (node->pending_weak_ref == 0) { in binder_thread_write()
4182 proc->pid, thread->pid, in binder_thread_write()
4183 node->debug_id); in binder_thread_write()
4188 node->pending_weak_ref = 0; in binder_thread_write()
4195 proc->pid, thread->pid, in binder_thread_write()
4197 node->debug_id, node->local_strong_refs, in binder_thread_write()
4198 node->local_weak_refs, node->tmp_refs); in binder_thread_write()
4205 return -EINVAL; in binder_thread_write()
4208 return -EINVAL; in binder_thread_write()
4215 return -EFAULT; in binder_thread_write()
4218 buffer = binder_alloc_prepare_to_free(&proc->alloc, in binder_thread_write()
4221 if (PTR_ERR(buffer) == -EPERM) { in binder_thread_write()
4224 proc->pid, thread->pid, in binder_thread_write()
4229 proc->pid, thread->pid, in binder_thread_write()
4236 proc->pid, thread->pid, (u64)data_ptr, in binder_thread_write()
4237 buffer->debug_id, in binder_thread_write()
4238 buffer->transaction ? "active" : "finished"); in binder_thread_write()
4248 return -EFAULT; in binder_thread_write()
4259 return -EFAULT; in binder_thread_write()
4269 proc->pid, thread->pid); in binder_thread_write()
4271 if (thread->looper & BINDER_LOOPER_STATE_ENTERED) { in binder_thread_write()
4272 thread->looper |= BINDER_LOOPER_STATE_INVALID; in binder_thread_write()
4274 proc->pid, thread->pid); in binder_thread_write()
4275 } else if (proc->requested_threads == 0) { in binder_thread_write()
4276 thread->looper |= BINDER_LOOPER_STATE_INVALID; in binder_thread_write()
4278 proc->pid, thread->pid); in binder_thread_write()
4280 proc->requested_threads--; in binder_thread_write()
4281 proc->requested_threads_started++; in binder_thread_write()
4283 thread->looper |= BINDER_LOOPER_STATE_REGISTERED; in binder_thread_write()
4289 proc->pid, thread->pid); in binder_thread_write()
4290 if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) { in binder_thread_write()
4291 thread->looper |= BINDER_LOOPER_STATE_INVALID; in binder_thread_write()
4293 proc->pid, thread->pid); in binder_thread_write()
4295 thread->looper |= BINDER_LOOPER_STATE_ENTERED; in binder_thread_write()
4300 proc->pid, thread->pid); in binder_thread_write()
4301 thread->looper |= BINDER_LOOPER_STATE_EXITED; in binder_thread_write()
4312 return -EFAULT; in binder_thread_write()
4315 return -EFAULT; in binder_thread_write()
4324 WARN_ON(thread->return_error.cmd != in binder_thread_write()
4326 thread->return_error.cmd = BR_ERROR; in binder_thread_write()
4329 &thread->return_error.work); in binder_thread_write()
4333 proc->pid, thread->pid); in binder_thread_write()
4341 proc->pid, thread->pid, in binder_thread_write()
4353 proc->pid, thread->pid, in binder_thread_write()
4357 (u64)cookie, ref->data.debug_id, in binder_thread_write()
4358 ref->data.desc, ref->data.strong, in binder_thread_write()
4359 ref->data.weak, ref->node->debug_id); in binder_thread_write()
4361 binder_node_lock(ref->node); in binder_thread_write()
4363 if (ref->death) { in binder_thread_write()
4365 proc->pid, thread->pid); in binder_thread_write()
4366 binder_node_unlock(ref->node); in binder_thread_write()
4372 INIT_LIST_HEAD(&death->work.entry); in binder_thread_write()
4373 death->cookie = cookie; in binder_thread_write()
4374 ref->death = death; in binder_thread_write()
4375 if (ref->node->proc == NULL) { in binder_thread_write()
4376 ref->death->work.type = BINDER_WORK_DEAD_BINDER; in binder_thread_write()
4380 &ref->death->work, &proc->todo); in binder_thread_write()
4385 if (ref->death == NULL) { in binder_thread_write()
4387 proc->pid, thread->pid); in binder_thread_write()
4388 binder_node_unlock(ref->node); in binder_thread_write()
4392 death = ref->death; in binder_thread_write()
4393 if (death->cookie != cookie) { in binder_thread_write()
4395 proc->pid, thread->pid, in binder_thread_write()
4396 (u64)death->cookie, in binder_thread_write()
4398 binder_node_unlock(ref->node); in binder_thread_write()
4402 ref->death = NULL; in binder_thread_write()
4404 if (list_empty(&death->work.entry)) { in binder_thread_write()
4405 death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; in binder_thread_write()
4406 if (thread->looper & in binder_thread_write()
4411 &death->work); in binder_thread_write()
4414 &death->work, in binder_thread_write()
4415 &proc->todo); in binder_thread_write()
4420 BUG_ON(death->work.type != BINDER_WORK_DEAD_BINDER); in binder_thread_write()
4421 death->work.type = BINDER_WORK_DEAD_BINDER_AND_CLEAR; in binder_thread_write()
4425 binder_node_unlock(ref->node); in binder_thread_write()
4434 return -EFAULT; in binder_thread_write()
4438 list_for_each_entry(w, &proc->delivered_death, in binder_thread_write()
4445 if (tmp_death->cookie == cookie) { in binder_thread_write()
4452 proc->pid, thread->pid, (u64)cookie, in binder_thread_write()
4456 proc->pid, thread->pid, (u64)cookie); in binder_thread_write()
4460 binder_dequeue_work_ilocked(&death->work); in binder_thread_write()
4461 if (death->work.type == BINDER_WORK_DEAD_BINDER_AND_CLEAR) { in binder_thread_write()
4462 death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; in binder_thread_write()
4463 if (thread->looper & in binder_thread_write()
4467 thread, &death->work); in binder_thread_write()
4470 &death->work, in binder_thread_write()
4471 &proc->todo); in binder_thread_write()
4483 return -EFAULT; in binder_thread_write()
4496 return -EFAULT; in binder_thread_write()
4508 return -EFAULT; in binder_thread_write()
4518 proc->pid, thread->pid, cmd); in binder_thread_write()
4519 return -EINVAL; in binder_thread_write()
4521 *consumed = ptr - buffer; in binder_thread_write()
4532 atomic_inc(&proc->stats.br[_IOC_NR(cmd)]); in binder_stat_br()
4533 atomic_inc(&thread->stats.br[_IOC_NR(cmd)]); in binder_stat_br()
4548 return -EFAULT; in binder_put_node_cmd()
4552 return -EFAULT; in binder_put_node_cmd()
4556 return -EFAULT; in binder_put_node_cmd()
4561 proc->pid, thread->pid, cmd_name, node_debug_id, in binder_put_node_cmd()
4572 struct binder_proc *proc = thread->proc; in binder_wait_for_work()
4577 prepare_to_wait(&thread->wait, &wait, TASK_INTERRUPTIBLE|TASK_FREEZABLE); in binder_wait_for_work()
4581 list_add(&thread->waiting_thread_node, in binder_wait_for_work()
4582 &proc->waiting_threads); in binder_wait_for_work()
4586 list_del_init(&thread->waiting_thread_node); in binder_wait_for_work()
4588 ret = -EINTR; in binder_wait_for_work()
4592 finish_wait(&thread->wait, &wait); in binder_wait_for_work()
4599 * binder_apply_fd_fixups() - finish fd translation
4600 * @proc: binder_proc associated @t->buffer
4617 list_for_each_entry(fixup, &t->fd_fixups, fixup_entry) { in binder_apply_fd_fixups()
4623 t->debug_id, fd); in binder_apply_fd_fixups()
4624 ret = -ENOMEM; in binder_apply_fd_fixups()
4629 t->debug_id, fd); in binder_apply_fd_fixups()
4630 trace_binder_transaction_fd_recv(t, fd, fixup->offset); in binder_apply_fd_fixups()
4631 fixup->target_fd = fd; in binder_apply_fd_fixups()
4632 if (binder_alloc_copy_to_buffer(&proc->alloc, t->buffer, in binder_apply_fd_fixups()
4633 fixup->offset, &fd, in binder_apply_fd_fixups()
4635 ret = -EINVAL; in binder_apply_fd_fixups()
4639 list_for_each_entry_safe(fixup, tmp, &t->fd_fixups, fixup_entry) { in binder_apply_fd_fixups()
4640 fd_install(fixup->target_fd, fixup->file); in binder_apply_fd_fixups()
4641 list_del(&fixup->fixup_entry); in binder_apply_fd_fixups()
4666 return -EFAULT; in binder_thread_read()
4675 thread->looper |= BINDER_LOOPER_STATE_WAITING; in binder_thread_read()
4678 !!thread->transaction_stack, in binder_thread_read()
4679 !binder_worklist_empty(proc, &thread->todo)); in binder_thread_read()
4681 if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED | in binder_thread_read()
4684 proc->pid, thread->pid, thread->looper); in binder_thread_read()
4688 binder_set_nice(proc->default_priority); in binder_thread_read()
4693 ret = -EAGAIN; in binder_thread_read()
4698 thread->looper &= ~BINDER_LOOPER_STATE_WAITING; in binder_thread_read()
4714 if (!binder_worklist_empty_ilocked(&thread->todo)) in binder_thread_read()
4715 list = &thread->todo; in binder_thread_read()
4716 else if (!binder_worklist_empty_ilocked(&proc->todo) && in binder_thread_read()
4718 list = &proc->todo; in binder_thread_read()
4723 if (ptr - buffer == 4 && !thread->looper_need_return) in binder_thread_read()
4728 if (end - ptr < sizeof(tr) + 4) { in binder_thread_read()
4733 if (binder_worklist_empty_ilocked(&thread->todo)) in binder_thread_read()
4734 thread->process_todo = false; in binder_thread_read()
4736 switch (w->type) { in binder_thread_read()
4745 WARN_ON(e->cmd == BR_OK); in binder_thread_read()
4747 if (put_user(e->cmd, (uint32_t __user *)ptr)) in binder_thread_read()
4748 return -EFAULT; in binder_thread_read()
4749 cmd = e->cmd; in binder_thread_read()
4750 e->cmd = BR_OK; in binder_thread_read()
4758 if (proc->oneway_spam_detection_enabled && in binder_thread_read()
4759 w->type == BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT) in binder_thread_read()
4761 else if (w->type == BINDER_WORK_TRANSACTION_PENDING) in binder_thread_read()
4769 return -EFAULT; in binder_thread_read()
4775 proc->pid, thread->pid); in binder_thread_read()
4780 binder_uintptr_t node_ptr = node->ptr; in binder_thread_read()
4781 binder_uintptr_t node_cookie = node->cookie; in binder_thread_read()
4782 int node_debug_id = node->debug_id; in binder_thread_read()
4787 BUG_ON(proc != node->proc); in binder_thread_read()
4788 strong = node->internal_strong_refs || in binder_thread_read()
4789 node->local_strong_refs; in binder_thread_read()
4790 weak = !hlist_empty(&node->refs) || in binder_thread_read()
4791 node->local_weak_refs || in binder_thread_read()
4792 node->tmp_refs || strong; in binder_thread_read()
4793 has_strong_ref = node->has_strong_ref; in binder_thread_read()
4794 has_weak_ref = node->has_weak_ref; in binder_thread_read()
4797 node->has_weak_ref = 1; in binder_thread_read()
4798 node->pending_weak_ref = 1; in binder_thread_read()
4799 node->local_weak_refs++; in binder_thread_read()
4802 node->has_strong_ref = 1; in binder_thread_read()
4803 node->pending_strong_ref = 1; in binder_thread_read()
4804 node->local_strong_refs++; in binder_thread_read()
4807 node->has_strong_ref = 0; in binder_thread_read()
4809 node->has_weak_ref = 0; in binder_thread_read()
4813 proc->pid, thread->pid, in binder_thread_read()
4817 rb_erase(&node->rb_node, &proc->nodes); in binder_thread_read()
4857 proc->pid, thread->pid, in binder_thread_read()
4872 if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) in binder_thread_read()
4876 cookie = death->cookie; in binder_thread_read()
4880 proc->pid, thread->pid, in binder_thread_read()
4885 if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) { in binder_thread_read()
4891 w, &proc->delivered_death); in binder_thread_read()
4895 return -EFAULT; in binder_thread_read()
4899 return -EFAULT; in binder_thread_read()
4912 info.is_frozen = freeze->is_frozen; in binder_thread_read()
4913 info.cookie = freeze->cookie; in binder_thread_read()
4914 freeze->sent = true; in binder_thread_read()
4915 binder_enqueue_work_ilocked(w, &proc->delivered_freeze); in binder_thread_read()
4919 return -EFAULT; in binder_thread_read()
4922 return -EFAULT; in binder_thread_read()
4931 binder_uintptr_t cookie = freeze->cookie; in binder_thread_read()
4937 return -EFAULT; in binder_thread_read()
4940 return -EFAULT; in binder_thread_read()
4948 proc->pid, thread->pid, w->type); in binder_thread_read()
4955 BUG_ON(t->buffer == NULL); in binder_thread_read()
4956 if (t->buffer->target_node) { in binder_thread_read()
4957 struct binder_node *target_node = t->buffer->target_node; in binder_thread_read()
4959 trd->target.ptr = target_node->ptr; in binder_thread_read()
4960 trd->cookie = target_node->cookie; in binder_thread_read()
4961 t->saved_priority = task_nice(current); in binder_thread_read()
4962 if (t->priority < target_node->min_priority && in binder_thread_read()
4963 !(t->flags & TF_ONE_WAY)) in binder_thread_read()
4964 binder_set_nice(t->priority); in binder_thread_read()
4965 else if (!(t->flags & TF_ONE_WAY) || in binder_thread_read()
4966 t->saved_priority > target_node->min_priority) in binder_thread_read()
4967 binder_set_nice(target_node->min_priority); in binder_thread_read()
4970 trd->target.ptr = 0; in binder_thread_read()
4971 trd->cookie = 0; in binder_thread_read()
4974 trd->code = t->code; in binder_thread_read()
4975 trd->flags = t->flags; in binder_thread_read()
4976 trd->sender_euid = from_kuid(current_user_ns(), t->sender_euid); in binder_thread_read()
4980 struct task_struct *sender = t_from->proc->tsk; in binder_thread_read()
4982 trd->sender_pid = in binder_thread_read()
4986 trd->sender_pid = 0; in binder_thread_read()
4991 struct binder_buffer *buffer = t->buffer; in binder_thread_read()
4992 bool oneway = !!(t->flags & TF_ONE_WAY); in binder_thread_read()
4993 int tid = t->debug_id; in binder_thread_read()
4997 buffer->transaction = NULL; in binder_thread_read()
5003 proc->pid, thread->pid, in binder_thread_read()
5004 oneway ? "async " : in binder_thread_read()
5010 return -EFAULT; in binder_thread_read()
5017 trd->data_size = t->buffer->data_size; in binder_thread_read()
5018 trd->offsets_size = t->buffer->offsets_size; in binder_thread_read()
5019 trd->data.ptr.buffer = t->buffer->user_data; in binder_thread_read()
5020 trd->data.ptr.offsets = trd->data.ptr.buffer + in binder_thread_read()
5021 ALIGN(t->buffer->data_size, in binder_thread_read()
5024 tr.secctx = t->security_ctx; in binder_thread_read()
5025 if (t->security_ctx) { in binder_thread_read()
5036 return -EFAULT; in binder_thread_read()
5046 return -EFAULT; in binder_thread_read()
5053 "%d:%d %s %d %d:%d, cmd %u size %zd-%zd ptr %016llx-%016llx\n", in binder_thread_read()
5054 proc->pid, thread->pid, in binder_thread_read()
5058 t->debug_id, t_from ? t_from->proc->pid : 0, in binder_thread_read()
5059 t_from ? t_from->pid : 0, cmd, in binder_thread_read()
5060 t->buffer->data_size, t->buffer->offsets_size, in binder_thread_read()
5061 (u64)trd->data.ptr.buffer, in binder_thread_read()
5062 (u64)trd->data.ptr.offsets); in binder_thread_read()
5066 t->buffer->allow_user_free = 1; in binder_thread_read()
5067 if (cmd != BR_REPLY && !(t->flags & TF_ONE_WAY)) { in binder_thread_read()
5068 binder_inner_proc_lock(thread->proc); in binder_thread_read()
5069 t->to_parent = thread->transaction_stack; in binder_thread_read()
5070 t->to_thread = thread; in binder_thread_read()
5071 thread->transaction_stack = t; in binder_thread_read()
5072 binder_inner_proc_unlock(thread->proc); in binder_thread_read()
5081 *consumed = ptr - buffer; in binder_thread_read()
5083 if (proc->requested_threads == 0 && in binder_thread_read()
5084 list_empty(&thread->proc->waiting_threads) && in binder_thread_read()
5085 proc->requested_threads_started < proc->max_threads && in binder_thread_read()
5086 (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | in binder_thread_read()
5087 BINDER_LOOPER_STATE_ENTERED)) /* the user-space code fails to */ in binder_thread_read()
5089 proc->requested_threads++; in binder_thread_read()
5093 proc->pid, thread->pid); in binder_thread_read()
5095 return -EFAULT; in binder_thread_read()
5111 wtype = w ? w->type : 0; in binder_release_work()
5131 e->cmd); in binder_release_work()
5148 (u64)death->cookie); in binder_release_work()
5168 struct rb_node **p = &proc->threads.rb_node; in binder_get_thread_ilocked()
5174 if (current->pid < thread->pid) in binder_get_thread_ilocked()
5175 p = &(*p)->rb_left; in binder_get_thread_ilocked()
5176 else if (current->pid > thread->pid) in binder_get_thread_ilocked()
5177 p = &(*p)->rb_right; in binder_get_thread_ilocked()
5185 thread->proc = proc; in binder_get_thread_ilocked()
5186 thread->pid = current->pid; in binder_get_thread_ilocked()
5187 atomic_set(&thread->tmp_ref, 0); in binder_get_thread_ilocked()
5188 init_waitqueue_head(&thread->wait); in binder_get_thread_ilocked()
5189 INIT_LIST_HEAD(&thread->todo); in binder_get_thread_ilocked()
5190 rb_link_node(&thread->rb_node, parent, p); in binder_get_thread_ilocked()
5191 rb_insert_color(&thread->rb_node, &proc->threads); in binder_get_thread_ilocked()
5192 thread->looper_need_return = true; in binder_get_thread_ilocked()
5193 thread->return_error.work.type = BINDER_WORK_RETURN_ERROR; in binder_get_thread_ilocked()
5194 thread->return_error.cmd = BR_OK; in binder_get_thread_ilocked()
5195 thread->reply_error.work.type = BINDER_WORK_RETURN_ERROR; in binder_get_thread_ilocked()
5196 thread->reply_error.cmd = BR_OK; in binder_get_thread_ilocked()
5197 thread->ee.command = BR_OK; in binder_get_thread_ilocked()
5198 INIT_LIST_HEAD(&new_thread->waiting_thread_node); in binder_get_thread_ilocked()
5227 BUG_ON(!list_empty(&proc->todo)); in binder_free_proc()
5228 BUG_ON(!list_empty(&proc->delivered_death)); in binder_free_proc()
5229 if (proc->outstanding_txns) in binder_free_proc()
5231 __func__, proc->outstanding_txns); in binder_free_proc()
5232 device = container_of(proc->context, struct binder_device, context); in binder_free_proc()
5233 if (refcount_dec_and_test(&device->ref)) { in binder_free_proc()
5234 kfree(proc->context->name); in binder_free_proc()
5237 binder_alloc_deferred_release(&proc->alloc); in binder_free_proc()
5238 put_task_struct(proc->tsk); in binder_free_proc()
5239 put_cred(proc->cred); in binder_free_proc()
5241 dbitmap_free(&proc->dmap); in binder_free_proc()
5247 BUG_ON(!list_empty(&thread->todo)); in binder_free_thread()
5249 binder_proc_dec_tmpref(thread->proc); in binder_free_thread()
5261 binder_inner_proc_lock(thread->proc); in binder_thread_release()
5264 * after we remove this thread from proc->threads. in binder_thread_release()
5268 proc->tmp_ref++; in binder_thread_release()
5273 atomic_inc(&thread->tmp_ref); in binder_thread_release()
5274 rb_erase(&thread->rb_node, &proc->threads); in binder_thread_release()
5275 t = thread->transaction_stack; in binder_thread_release()
5277 spin_lock(&t->lock); in binder_thread_release()
5278 if (t->to_thread == thread) in binder_thread_release()
5281 __acquire(&t->lock); in binder_thread_release()
5283 thread->is_dead = true; in binder_thread_release()
5290 proc->pid, thread->pid, in binder_thread_release()
5291 t->debug_id, in binder_thread_release()
5292 (t->to_thread == thread) ? "in" : "out"); in binder_thread_release()
5294 if (t->to_thread == thread) { in binder_thread_release()
5295 thread->proc->outstanding_txns--; in binder_thread_release()
5296 t->to_proc = NULL; in binder_thread_release()
5297 t->to_thread = NULL; in binder_thread_release()
5298 if (t->buffer) { in binder_thread_release()
5299 t->buffer->transaction = NULL; in binder_thread_release()
5300 t->buffer = NULL; in binder_thread_release()
5302 t = t->to_parent; in binder_thread_release()
5303 } else if (t->from == thread) { in binder_thread_release()
5304 t->from = NULL; in binder_thread_release()
5305 t = t->from_parent; in binder_thread_release()
5308 spin_unlock(&last_t->lock); in binder_thread_release()
5310 spin_lock(&t->lock); in binder_thread_release()
5312 __acquire(&t->lock); in binder_thread_release()
5315 __release(&t->lock); in binder_thread_release()
5321 if (thread->looper & BINDER_LOOPER_STATE_POLL) in binder_thread_release()
5322 wake_up_pollfree(&thread->wait); in binder_thread_release()
5324 binder_inner_proc_unlock(thread->proc); in binder_thread_release()
5333 if (thread->looper & BINDER_LOOPER_STATE_POLL) in binder_thread_release()
5338 binder_release_work(proc, &thread->todo); in binder_thread_release()
5346 struct binder_proc *proc = filp->private_data; in binder_poll()
5354 binder_inner_proc_lock(thread->proc); in binder_poll()
5355 thread->looper |= BINDER_LOOPER_STATE_POLL; in binder_poll()
5358 binder_inner_proc_unlock(thread->proc); in binder_poll()
5360 poll_wait(filp, &thread->wait, wait); in binder_poll()
5372 struct binder_proc *proc = filp->private_data; in binder_ioctl_write_read()
5377 ret = -EFAULT; in binder_ioctl_write_read()
5382 proc->pid, thread->pid, in binder_ioctl_write_read()
5395 ret = -EFAULT; in binder_ioctl_write_read()
5403 filp->f_flags & O_NONBLOCK); in binder_ioctl_write_read()
5406 if (!binder_worklist_empty_ilocked(&proc->todo)) in binder_ioctl_write_read()
5411 ret = -EFAULT; in binder_ioctl_write_read()
5417 proc->pid, thread->pid, in binder_ioctl_write_read()
5421 ret = -EFAULT; in binder_ioctl_write_read()
5432 struct binder_proc *proc = filp->private_data; in binder_ioctl_set_ctx_mgr()
5433 struct binder_context *context = proc->context; in binder_ioctl_set_ctx_mgr()
5437 mutex_lock(&context->context_mgr_node_lock); in binder_ioctl_set_ctx_mgr()
5438 if (context->binder_context_mgr_node) { in binder_ioctl_set_ctx_mgr()
5440 ret = -EBUSY; in binder_ioctl_set_ctx_mgr()
5443 ret = security_binder_set_context_mgr(proc->cred); in binder_ioctl_set_ctx_mgr()
5446 if (uid_valid(context->binder_context_mgr_uid)) { in binder_ioctl_set_ctx_mgr()
5447 if (!uid_eq(context->binder_context_mgr_uid, curr_euid)) { in binder_ioctl_set_ctx_mgr()
5451 context->binder_context_mgr_uid)); in binder_ioctl_set_ctx_mgr()
5452 ret = -EPERM; in binder_ioctl_set_ctx_mgr()
5456 context->binder_context_mgr_uid = curr_euid; in binder_ioctl_set_ctx_mgr()
5460 ret = -ENOMEM; in binder_ioctl_set_ctx_mgr()
5464 new_node->local_weak_refs++; in binder_ioctl_set_ctx_mgr()
5465 new_node->local_strong_refs++; in binder_ioctl_set_ctx_mgr()
5466 new_node->has_strong_ref = 1; in binder_ioctl_set_ctx_mgr()
5467 new_node->has_weak_ref = 1; in binder_ioctl_set_ctx_mgr()
5468 context->binder_context_mgr_node = new_node; in binder_ioctl_set_ctx_mgr()
5472 mutex_unlock(&context->context_mgr_node_lock); in binder_ioctl_set_ctx_mgr()
5480 struct binder_context *context = proc->context; in binder_ioctl_get_node_info_for_ref()
5481 __u32 handle = info->handle; in binder_ioctl_get_node_info_for_ref()
5483 if (info->strong_count || info->weak_count || info->reserved1 || in binder_ioctl_get_node_info_for_ref()
5484 info->reserved2 || info->reserved3) { in binder_ioctl_get_node_info_for_ref()
5485 binder_user_error("%d BINDER_GET_NODE_INFO_FOR_REF: only handle may be non-zero.", in binder_ioctl_get_node_info_for_ref()
5486 proc->pid); in binder_ioctl_get_node_info_for_ref()
5487 return -EINVAL; in binder_ioctl_get_node_info_for_ref()
5491 mutex_lock(&context->context_mgr_node_lock); in binder_ioctl_get_node_info_for_ref()
5492 if (!context->binder_context_mgr_node || in binder_ioctl_get_node_info_for_ref()
5493 context->binder_context_mgr_node->proc != proc) { in binder_ioctl_get_node_info_for_ref()
5494 mutex_unlock(&context->context_mgr_node_lock); in binder_ioctl_get_node_info_for_ref()
5495 return -EPERM; in binder_ioctl_get_node_info_for_ref()
5497 mutex_unlock(&context->context_mgr_node_lock); in binder_ioctl_get_node_info_for_ref()
5501 return -EINVAL; in binder_ioctl_get_node_info_for_ref()
5503 info->strong_count = node->local_strong_refs + in binder_ioctl_get_node_info_for_ref()
5504 node->internal_strong_refs; in binder_ioctl_get_node_info_for_ref()
5505 info->weak_count = node->local_weak_refs; in binder_ioctl_get_node_info_for_ref()
5516 binder_uintptr_t ptr = info->ptr; in binder_ioctl_get_node_debug_info()
5521 for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) { in binder_ioctl_get_node_debug_info()
5524 if (node->ptr > ptr) { in binder_ioctl_get_node_debug_info()
5525 info->ptr = node->ptr; in binder_ioctl_get_node_debug_info()
5526 info->cookie = node->cookie; in binder_ioctl_get_node_debug_info()
5527 info->has_strong_ref = node->has_strong_ref; in binder_ioctl_get_node_debug_info()
5528 info->has_weak_ref = node->has_weak_ref; in binder_ioctl_get_node_debug_info()
5542 if (proc->outstanding_txns > 0) in binder_txns_pending_ilocked()
5545 for (n = rb_first(&proc->threads); n; n = rb_next(n)) { in binder_txns_pending_ilocked()
5547 if (thread->transaction_stack) in binder_txns_pending_ilocked()
5559 for (n = rb_first(&proc->nodes); n; n = rb_next(n)) { in binder_add_freeze_work()
5565 hlist_for_each_entry(ref, &node->refs, node_entry) { in binder_add_freeze_work()
5572 binder_inner_proc_lock(ref->proc); in binder_add_freeze_work()
5573 if (!ref->freeze) { in binder_add_freeze_work()
5574 binder_inner_proc_unlock(ref->proc); in binder_add_freeze_work()
5577 ref->freeze->work.type = BINDER_WORK_FROZEN_BINDER; in binder_add_freeze_work()
5578 if (list_empty(&ref->freeze->work.entry)) { in binder_add_freeze_work()
5579 ref->freeze->is_frozen = is_frozen; in binder_add_freeze_work()
5580 binder_enqueue_work_ilocked(&ref->freeze->work, &ref->proc->todo); in binder_add_freeze_work()
5581 binder_wakeup_proc_ilocked(ref->proc); in binder_add_freeze_work()
5583 if (ref->freeze->sent && ref->freeze->is_frozen != is_frozen) in binder_add_freeze_work()
5584 ref->freeze->resend = true; in binder_add_freeze_work()
5585 ref->freeze->is_frozen = is_frozen; in binder_add_freeze_work()
5587 binder_inner_proc_unlock(ref->proc); in binder_add_freeze_work()
5600 if (!info->enable) { in binder_ioctl_freeze()
5602 target_proc->sync_recv = false; in binder_ioctl_freeze()
5603 target_proc->async_recv = false; in binder_ioctl_freeze()
5604 target_proc->is_frozen = false; in binder_ioctl_freeze()
5616 target_proc->sync_recv = false; in binder_ioctl_freeze()
5617 target_proc->async_recv = false; in binder_ioctl_freeze()
5618 target_proc->is_frozen = true; in binder_ioctl_freeze()
5621 if (info->timeout_ms > 0) in binder_ioctl_freeze()
5623 target_proc->freeze_wait, in binder_ioctl_freeze()
5624 (!target_proc->outstanding_txns), in binder_ioctl_freeze()
5625 msecs_to_jiffies(info->timeout_ms)); in binder_ioctl_freeze()
5631 ret = -EAGAIN; in binder_ioctl_freeze()
5637 target_proc->is_frozen = false; in binder_ioctl_freeze()
5653 info->sync_recv = 0; in binder_ioctl_get_freezer_info()
5654 info->async_recv = 0; in binder_ioctl_get_freezer_info()
5658 if (target_proc->pid == info->pid) { in binder_ioctl_get_freezer_info()
5662 info->sync_recv |= target_proc->sync_recv | in binder_ioctl_get_freezer_info()
5664 info->async_recv |= target_proc->async_recv; in binder_ioctl_get_freezer_info()
5671 return -EINVAL; in binder_ioctl_get_freezer_info()
5681 binder_inner_proc_lock(thread->proc); in binder_ioctl_get_extended_error()
5682 ee = thread->ee; in binder_ioctl_get_extended_error()
5683 binder_set_extended_error(&thread->ee, 0, BR_OK, 0); in binder_ioctl_get_extended_error()
5684 binder_inner_proc_unlock(thread->proc); in binder_ioctl_get_extended_error()
5687 return -EFAULT; in binder_ioctl_get_extended_error()
5695 struct binder_proc *proc = filp->private_data; in binder_ioctl()
5700 proc->pid, current->pid, cmd, arg);*/ in binder_ioctl()
5702 binder_selftest_alloc(&proc->alloc); in binder_ioctl()
5712 ret = -ENOMEM; in binder_ioctl()
5727 ret = -EINVAL; in binder_ioctl()
5731 proc->max_threads = max_threads; in binder_ioctl()
5739 ret = -EINVAL; in binder_ioctl()
5754 proc->pid, thread->pid); in binder_ioctl()
5762 &ver->protocol_version)) { in binder_ioctl()
5763 ret = -EINVAL; in binder_ioctl()
5772 ret = -EFAULT; in binder_ioctl()
5781 ret = -EFAULT; in binder_ioctl()
5791 ret = -EFAULT; in binder_ioctl()
5800 ret = -EFAULT; in binder_ioctl()
5813 ret = -EFAULT; in binder_ioctl()
5819 if (target_proc->pid == info.pid) in binder_ioctl()
5825 ret = -EINVAL; in binder_ioctl()
5835 ret = -ENOMEM; in binder_ioctl()
5840 if (target_proc->pid != info.pid) in binder_ioctl()
5844 target_proc->tmp_ref++; in binder_ioctl()
5869 ret = -EFAULT; in binder_ioctl()
5878 ret = -EFAULT; in binder_ioctl()
5887 ret = -EFAULT; in binder_ioctl()
5891 proc->oneway_spam_detection_enabled = (bool)enable; in binder_ioctl()
5901 ret = -EINVAL; in binder_ioctl()
5907 thread->looper_need_return = false; in binder_ioctl()
5909 if (ret && ret != -EINTR) in binder_ioctl()
5910 pr_info("%d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret); in binder_ioctl()
5918 struct binder_proc *proc = vma->vm_private_data; in binder_vma_open()
5921 "%d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", in binder_vma_open()
5922 proc->pid, vma->vm_start, vma->vm_end, in binder_vma_open()
5923 (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, in binder_vma_open()
5924 (unsigned long)pgprot_val(vma->vm_page_prot)); in binder_vma_open()
5929 struct binder_proc *proc = vma->vm_private_data; in binder_vma_close()
5932 "%d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", in binder_vma_close()
5933 proc->pid, vma->vm_start, vma->vm_end, in binder_vma_close()
5934 (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, in binder_vma_close()
5935 (unsigned long)pgprot_val(vma->vm_page_prot)); in binder_vma_close()
5936 binder_alloc_vma_close(&proc->alloc); in binder_vma_close()
5952 struct binder_proc *proc = filp->private_data; in binder_mmap()
5954 if (proc->tsk != current->group_leader) in binder_mmap()
5955 return -EINVAL; in binder_mmap()
5958 "%s: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", in binder_mmap()
5959 __func__, proc->pid, vma->vm_start, vma->vm_end, in binder_mmap()
5960 (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, in binder_mmap()
5961 (unsigned long)pgprot_val(vma->vm_page_prot)); in binder_mmap()
5963 if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) { in binder_mmap()
5964 pr_err("%s: %d %lx-%lx %s failed %d\n", __func__, in binder_mmap()
5965 proc->pid, vma->vm_start, vma->vm_end, "bad vm_flags", -EPERM); in binder_mmap()
5966 return -EPERM; in binder_mmap()
5970 vma->vm_ops = &binder_vm_ops; in binder_mmap()
5971 vma->vm_private_data = proc; in binder_mmap()
5973 return binder_alloc_mmap_handler(&proc->alloc, vma); in binder_mmap()
5985 current->group_leader->pid, current->pid); in binder_open()
5989 return -ENOMEM; in binder_open()
5991 dbitmap_init(&proc->dmap); in binder_open()
5992 spin_lock_init(&proc->inner_lock); in binder_open()
5993 spin_lock_init(&proc->outer_lock); in binder_open()
5994 get_task_struct(current->group_leader); in binder_open()
5995 proc->tsk = current->group_leader; in binder_open()
5996 proc->cred = get_cred(filp->f_cred); in binder_open()
5997 INIT_LIST_HEAD(&proc->todo); in binder_open()
5998 init_waitqueue_head(&proc->freeze_wait); in binder_open()
5999 proc->default_priority = task_nice(current); in binder_open()
6002 binder_dev = nodp->i_private; in binder_open()
6003 info = nodp->i_sb->s_fs_info; in binder_open()
6004 binder_binderfs_dir_entry_proc = info->proc_log_dir; in binder_open()
6006 binder_dev = container_of(filp->private_data, in binder_open()
6009 refcount_inc(&binder_dev->ref); in binder_open()
6010 proc->context = &binder_dev->context; in binder_open()
6011 binder_alloc_init(&proc->alloc); in binder_open()
6014 proc->pid = current->group_leader->pid; in binder_open()
6015 INIT_LIST_HEAD(&proc->delivered_death); in binder_open()
6016 INIT_LIST_HEAD(&proc->delivered_freeze); in binder_open()
6017 INIT_LIST_HEAD(&proc->waiting_threads); in binder_open()
6018 filp->private_data = proc; in binder_open()
6022 if (itr->pid == proc->pid) { in binder_open()
6027 hlist_add_head(&proc->proc_node, &binder_procs); in binder_open()
6033 snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); in binder_open()
6040 proc->debugfs_entry = debugfs_create_file(strbuf, 0444, in binder_open()
6042 (void *)(unsigned long)proc->pid, in binder_open()
6050 snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); in binder_open()
6058 strbuf, &proc_fops, (void *)(unsigned long)proc->pid); in binder_open()
6060 proc->binderfs_entry = binderfs_entry; in binder_open()
6075 struct binder_proc *proc = filp->private_data; in binder_flush()
6088 for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) { in binder_deferred_flush()
6091 thread->looper_need_return = true; in binder_deferred_flush()
6092 if (thread->looper & BINDER_LOOPER_STATE_WAITING) { in binder_deferred_flush()
6093 wake_up_interruptible(&thread->wait); in binder_deferred_flush()
6100 "binder_flush: %d woke %d threads\n", proc->pid, in binder_deferred_flush()
6106 struct binder_proc *proc = filp->private_data; in binder_release()
6108 debugfs_remove(proc->debugfs_entry); in binder_release()
6110 if (proc->binderfs_entry) { in binder_release()
6111 binderfs_remove_file(proc->binderfs_entry); in binder_release()
6112 proc->binderfs_entry = NULL; in binder_release()
6124 struct binder_proc *proc = node->proc; in binder_node_release()
6126 binder_release_work(proc, &node->async_todo); in binder_node_release()
6130 binder_dequeue_work_ilocked(&node->work); in binder_node_release()
6134 BUG_ON(!node->tmp_refs); in binder_node_release()
6135 if (hlist_empty(&node->refs) && node->tmp_refs == 1) { in binder_node_release()
6143 node->proc = NULL; in binder_node_release()
6144 node->local_strong_refs = 0; in binder_node_release()
6145 node->local_weak_refs = 0; in binder_node_release()
6149 hlist_add_head(&node->dead_node, &binder_dead_nodes); in binder_node_release()
6152 hlist_for_each_entry(ref, &node->refs, node_entry) { in binder_node_release()
6160 binder_inner_proc_lock(ref->proc); in binder_node_release()
6161 if (!ref->death) { in binder_node_release()
6162 binder_inner_proc_unlock(ref->proc); in binder_node_release()
6168 BUG_ON(!list_empty(&ref->death->work.entry)); in binder_node_release()
6169 ref->death->work.type = BINDER_WORK_DEAD_BINDER; in binder_node_release()
6170 binder_enqueue_work_ilocked(&ref->death->work, in binder_node_release()
6171 &ref->proc->todo); in binder_node_release()
6172 binder_wakeup_proc_ilocked(ref->proc); in binder_node_release()
6173 binder_inner_proc_unlock(ref->proc); in binder_node_release()
6178 node->debug_id, refs, death); in binder_node_release()
6187 struct binder_context *context = proc->context; in binder_deferred_release()
6192 hlist_del(&proc->proc_node); in binder_deferred_release()
6195 mutex_lock(&context->context_mgr_node_lock); in binder_deferred_release()
6196 if (context->binder_context_mgr_node && in binder_deferred_release()
6197 context->binder_context_mgr_node->proc == proc) { in binder_deferred_release()
6200 __func__, proc->pid); in binder_deferred_release()
6201 context->binder_context_mgr_node = NULL; in binder_deferred_release()
6203 mutex_unlock(&context->context_mgr_node_lock); in binder_deferred_release()
6209 proc->tmp_ref++; in binder_deferred_release()
6211 proc->is_dead = true; in binder_deferred_release()
6212 proc->is_frozen = false; in binder_deferred_release()
6213 proc->sync_recv = false; in binder_deferred_release()
6214 proc->async_recv = false; in binder_deferred_release()
6217 while ((n = rb_first(&proc->threads))) { in binder_deferred_release()
6229 while ((n = rb_first(&proc->nodes))) { in binder_deferred_release()
6240 rb_erase(&node->rb_node, &proc->nodes); in binder_deferred_release()
6249 while ((n = rb_first(&proc->refs_by_desc))) { in binder_deferred_release()
6261 binder_release_work(proc, &proc->todo); in binder_deferred_release()
6262 binder_release_work(proc, &proc->delivered_death); in binder_deferred_release()
6266 __func__, proc->pid, threads, nodes, incoming_refs, in binder_deferred_release()
6283 hlist_del_init(&proc->deferred_work_node); in binder_deferred_func()
6284 defer = proc->deferred_work; in binder_deferred_func()
6285 proc->deferred_work = 0; in binder_deferred_func()
6305 proc->deferred_work |= defer; in binder_defer_work()
6306 if (hlist_unhashed(&proc->deferred_work_node)) { in binder_defer_work()
6307 hlist_add_head(&proc->deferred_work_node, in binder_defer_work()
6316 const char *prefix, in print_binder_transaction_ilocked() argument
6320 struct binder_buffer *buffer = t->buffer; in print_binder_transaction_ilocked()
6323 spin_lock(&t->lock); in print_binder_transaction_ilocked()
6324 to_proc = t->to_proc; in print_binder_transaction_ilocked()
6327 prefix, t->debug_id, t, in print_binder_transaction_ilocked()
6328 t->from_pid, in print_binder_transaction_ilocked()
6329 t->from_tid, in print_binder_transaction_ilocked()
6330 to_proc ? to_proc->pid : 0, in print_binder_transaction_ilocked()
6331 t->to_thread ? t->to_thread->pid : 0, in print_binder_transaction_ilocked()
6332 t->code, t->flags, t->priority, t->need_reply, in print_binder_transaction_ilocked()
6333 ktime_ms_delta(current_time, t->start_time)); in print_binder_transaction_ilocked()
6334 spin_unlock(&t->lock); in print_binder_transaction_ilocked()
6349 if (buffer->target_node) in print_binder_transaction_ilocked()
6350 seq_printf(m, " node %d", buffer->target_node->debug_id); in print_binder_transaction_ilocked()
6352 buffer->data_size, buffer->offsets_size, in print_binder_transaction_ilocked()
6353 proc->alloc.buffer - buffer->user_data); in print_binder_transaction_ilocked()
6358 const char *prefix, in print_binder_work_ilocked() argument
6365 switch (w->type) { in print_binder_work_ilocked()
6376 prefix, e->cmd); in print_binder_work_ilocked()
6379 seq_printf(m, "%stransaction complete\n", prefix); in print_binder_work_ilocked()
6384 prefix, node->debug_id, in print_binder_work_ilocked()
6385 (u64)node->ptr, (u64)node->cookie); in print_binder_work_ilocked()
6388 seq_printf(m, "%shas dead binder\n", prefix); in print_binder_work_ilocked()
6391 seq_printf(m, "%shas cleared dead binder\n", prefix); in print_binder_work_ilocked()
6394 seq_printf(m, "%shas cleared death notification\n", prefix); in print_binder_work_ilocked()
6397 seq_printf(m, "%sunknown work: type %d\n", prefix, w->type); in print_binder_work_ilocked()
6408 size_t start_pos = m->count; in print_binder_thread_ilocked()
6412 thread->pid, thread->looper, in print_binder_thread_ilocked()
6413 thread->looper_need_return, in print_binder_thread_ilocked()
6414 atomic_read(&thread->tmp_ref)); in print_binder_thread_ilocked()
6415 header_pos = m->count; in print_binder_thread_ilocked()
6416 t = thread->transaction_stack; in print_binder_thread_ilocked()
6418 if (t->from == thread) { in print_binder_thread_ilocked()
6419 print_binder_transaction_ilocked(m, thread->proc, in print_binder_thread_ilocked()
6421 t = t->from_parent; in print_binder_thread_ilocked()
6422 } else if (t->to_thread == thread) { in print_binder_thread_ilocked()
6423 print_binder_transaction_ilocked(m, thread->proc, in print_binder_thread_ilocked()
6425 t = t->to_parent; in print_binder_thread_ilocked()
6427 print_binder_transaction_ilocked(m, thread->proc, in print_binder_thread_ilocked()
6432 list_for_each_entry(w, &thread->todo, entry) { in print_binder_thread_ilocked()
6433 print_binder_work_ilocked(m, thread->proc, " ", in print_binder_thread_ilocked()
6436 if (!print_always && m->count == header_pos) in print_binder_thread_ilocked()
6437 m->count = start_pos; in print_binder_thread_ilocked()
6447 count = hlist_count_nodes(&node->refs); in print_binder_node_nilocked()
6450 node->debug_id, (u64)node->ptr, (u64)node->cookie, in print_binder_node_nilocked()
6451 node->has_strong_ref, node->has_weak_ref, in print_binder_node_nilocked()
6452 node->local_strong_refs, node->local_weak_refs, in print_binder_node_nilocked()
6453 node->internal_strong_refs, count, node->tmp_refs); in print_binder_node_nilocked()
6456 hlist_for_each_entry(ref, &node->refs, node_entry) in print_binder_node_nilocked()
6457 seq_printf(m, " %d", ref->proc->pid); in print_binder_node_nilocked()
6460 if (node->proc) { in print_binder_node_nilocked()
6461 list_for_each_entry(w, &node->async_todo, entry) in print_binder_node_nilocked()
6462 print_binder_work_ilocked(m, node->proc, " ", in print_binder_node_nilocked()
6463 " pending async transaction", w); in print_binder_node_nilocked()
6470 binder_node_lock(ref->node); in print_binder_ref_olocked()
6472 ref->data.debug_id, ref->data.desc, in print_binder_ref_olocked()
6473 ref->node->proc ? "" : "dead ", in print_binder_ref_olocked()
6474 ref->node->debug_id, ref->data.strong, in print_binder_ref_olocked()
6475 ref->data.weak, ref->death); in print_binder_ref_olocked()
6476 binder_node_unlock(ref->node); in print_binder_ref_olocked()
6484 size_t start_pos = m->count; in print_binder_proc()
6488 seq_printf(m, "proc %d\n", proc->pid); in print_binder_proc()
6489 seq_printf(m, "context %s\n", proc->context->name); in print_binder_proc()
6490 header_pos = m->count; in print_binder_proc()
6493 for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) in print_binder_proc()
6497 for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) { in print_binder_proc()
6500 if (!print_all && !node->has_async_transaction) in print_binder_proc()
6525 for (n = rb_first(&proc->refs_by_desc); in print_binder_proc()
6533 binder_alloc_print_allocated(m, &proc->alloc); in print_binder_proc()
6535 list_for_each_entry(w, &proc->todo, entry) in print_binder_proc()
6538 list_for_each_entry(w, &proc->delivered_death, entry) { in print_binder_proc()
6543 if (!print_all && m->count == header_pos) in print_binder_proc()
6544 m->count = start_pos; in print_binder_proc()
6609 static void print_binder_stats(struct seq_file *m, const char *prefix, in print_binder_stats() argument
6614 BUILD_BUG_ON(ARRAY_SIZE(stats->bc) != in print_binder_stats()
6616 for (i = 0; i < ARRAY_SIZE(stats->bc); i++) { in print_binder_stats()
6617 int temp = atomic_read(&stats->bc[i]); in print_binder_stats()
6620 seq_printf(m, "%s%s: %d\n", prefix, in print_binder_stats()
6624 BUILD_BUG_ON(ARRAY_SIZE(stats->br) != in print_binder_stats()
6626 for (i = 0; i < ARRAY_SIZE(stats->br); i++) { in print_binder_stats()
6627 int temp = atomic_read(&stats->br[i]); in print_binder_stats()
6630 seq_printf(m, "%s%s: %d\n", prefix, in print_binder_stats()
6634 BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != in print_binder_stats()
6636 BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != in print_binder_stats()
6637 ARRAY_SIZE(stats->obj_deleted)); in print_binder_stats()
6638 for (i = 0; i < ARRAY_SIZE(stats->obj_created); i++) { in print_binder_stats()
6639 int created = atomic_read(&stats->obj_created[i]); in print_binder_stats()
6640 int deleted = atomic_read(&stats->obj_deleted[i]); in print_binder_stats()
6644 prefix, in print_binder_stats()
6646 created - deleted, in print_binder_stats()
6659 binder_alloc_get_free_async_space(&proc->alloc); in print_binder_proc_stats()
6661 seq_printf(m, "proc %d\n", proc->pid); in print_binder_proc_stats()
6662 seq_printf(m, "context %s\n", proc->context->name); in print_binder_proc_stats()
6666 for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) in print_binder_proc_stats()
6669 list_for_each_entry(thread, &proc->waiting_threads, waiting_thread_node) in print_binder_proc_stats()
6675 " free async space %zd\n", proc->requested_threads, in print_binder_proc_stats()
6676 proc->requested_threads_started, proc->max_threads, in print_binder_proc_stats()
6680 for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) in print_binder_proc_stats()
6688 for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) { in print_binder_proc_stats()
6692 strong += ref->data.strong; in print_binder_proc_stats()
6693 weak += ref->data.weak; in print_binder_proc_stats()
6698 count = binder_alloc_get_allocated_count(&proc->alloc); in print_binder_proc_stats()
6701 binder_alloc_print_pages(m, &proc->alloc); in print_binder_proc_stats()
6705 list_for_each_entry(w, &proc->todo, entry) { in print_binder_proc_stats()
6706 if (w->type == BINDER_WORK_TRANSACTION) in print_binder_proc_stats()
6712 print_binder_stats(m, " ", &proc->stats); in print_binder_proc_stats()
6732 node->tmp_refs++; in state_show()
6786 int pid = (unsigned long)m->private; in proc_show()
6790 if (itr->pid == pid) { in proc_show()
6803 int debug_id = READ_ONCE(e->debug_id_done); in print_binder_transaction_log_entry()
6811 e->debug_id, (e->call_type == 2) ? "reply" : in print_binder_transaction_log_entry()
6812 ((e->call_type == 1) ? "async" : "call "), e->from_proc, in print_binder_transaction_log_entry()
6813 e->from_thread, e->to_proc, e->to_thread, e->context_name, in print_binder_transaction_log_entry()
6814 e->to_node, e->target_handle, e->data_size, e->offsets_size, in print_binder_transaction_log_entry()
6815 e->return_error, e->return_error_param, in print_binder_transaction_log_entry()
6816 e->return_error_line); in print_binder_transaction_log_entry()
6818 * read-barrier to guarantee read of debug_id_done after in print_binder_transaction_log_entry()
6822 seq_printf(m, debug_id && debug_id == READ_ONCE(e->debug_id_done) ? in print_binder_transaction_log_entry()
6828 struct binder_transaction_log *log = m->private; in transaction_log_show()
6829 unsigned int log_cur = atomic_read(&log->cur); in transaction_log_show()
6835 cur = count < ARRAY_SIZE(log->entry) && !log->full ? in transaction_log_show()
6836 0 : count % ARRAY_SIZE(log->entry); in transaction_log_show()
6837 if (count > ARRAY_SIZE(log->entry) || log->full) in transaction_log_show()
6838 count = ARRAY_SIZE(log->entry); in transaction_log_show()
6840 unsigned int index = cur++ % ARRAY_SIZE(log->entry); in transaction_log_show()
6842 print_binder_transaction_log_entry(m, &log->entry[index]); in transaction_log_show()
6904 return -ENOMEM; in init_binder_device()
6906 binder_device->miscdev.fops = &binder_fops; in init_binder_device()
6907 binder_device->miscdev.minor = MISC_DYNAMIC_MINOR; in init_binder_device()
6908 binder_device->miscdev.name = name; in init_binder_device()
6910 refcount_set(&binder_device->ref, 1); in init_binder_device()
6911 binder_device->context.binder_context_mgr_uid = INVALID_UID; in init_binder_device()
6912 binder_device->context.name = name; in init_binder_device()
6913 mutex_init(&binder_device->context.context_mgr_node_lock); in init_binder_device()
6915 ret = misc_register(&binder_device->miscdev); in init_binder_device()
6921 hlist_add_head(&binder_device->hlist, &binder_devices); in init_binder_device()
6945 debugfs_create_file(db_entry->name, in binder_init()
6946 db_entry->mode, in binder_init()
6948 db_entry->data, in binder_init()
6949 db_entry->fops); in binder_init()
6958 * tokenize it in-place. in binder_init()
6962 ret = -ENOMEM; in binder_init()
6982 misc_deregister(&device->miscdev); in binder_init()
6983 hlist_del(&device->hlist); in binder_init()