diff --git a/drivers/android/binder.c b/drivers/android/binder.c index fd25b66ddb7a..f5414f11d4f2 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -6645,7 +6645,7 @@ static void print_binder_work_ilocked(struct seq_file *m, struct binder_proc *proc, const char *prefix, const char *transaction_prefix, - struct binder_work *w) + struct binder_work *w, bool hash_ptrs) { struct binder_node *node; struct binder_transaction *t; @@ -6668,9 +6668,15 @@ static void print_binder_work_ilocked(struct seq_file *m, break; case BINDER_WORK_NODE: node = container_of(w, struct binder_node, work); - seq_printf(m, "%snode work %d: u%016llx c%016llx\n", - prefix, node->debug_id, - (u64)node->ptr, (u64)node->cookie); + if (hash_ptrs) + seq_printf(m, "%snode work %d: u%p c%p\n", + prefix, node->debug_id, + (void *)(long)node->ptr, + (void *)(long)node->cookie); + else + seq_printf(m, "%snode work %d: u%016llx c%016llx\n", + prefix, node->debug_id, + (u64)node->ptr, (u64)node->cookie); break; case BINDER_WORK_DEAD_BINDER: seq_printf(m, "%shas dead binder\n", prefix); @@ -6695,7 +6701,7 @@ static void print_binder_work_ilocked(struct seq_file *m, static void print_binder_thread_ilocked(struct seq_file *m, struct binder_thread *thread, - bool print_always) + bool print_always, bool hash_ptrs) { struct binder_transaction *t; struct binder_work *w; @@ -6725,14 +6731,16 @@ static void print_binder_thread_ilocked(struct seq_file *m, } list_for_each_entry(w, &thread->todo, entry) { print_binder_work_ilocked(m, thread->proc, " ", - " pending transaction", w); + " pending transaction", + w, hash_ptrs); } if (!print_always && m->count == header_pos) m->count = start_pos; } static void print_binder_node_nilocked(struct seq_file *m, - struct binder_node *node) + struct binder_node *node, + bool hash_ptrs) { struct binder_ref *ref; struct binder_work *w; @@ -6742,8 +6750,13 @@ static void print_binder_node_nilocked(struct seq_file *m, hlist_for_each_entry(ref, &node->refs, node_entry) count++; - seq_printf(m, " node %d: u%016llx c%016llx pri %d:%d hs %d hw %d ls %d lw %d is %d iw %d tr %d", - node->debug_id, (u64)node->ptr, (u64)node->cookie, + if (hash_ptrs) + seq_printf(m, " node %d: u%p c%p", node->debug_id, + (void *)(long)node->ptr, (void *)(long)node->cookie); + else + seq_printf(m, " node %d: u%016llx c%016llx", node->debug_id, + (u64)node->ptr, (u64)node->cookie); + seq_printf(m, " pri %d:%d hs %d hw %d ls %d lw %d is %d iw %d tr %d", node->sched_policy, node->min_priority, node->has_strong_ref, node->has_weak_ref, node->local_strong_refs, node->local_weak_refs, @@ -6757,7 +6770,8 @@ static void print_binder_node_nilocked(struct seq_file *m, if (node->proc) { list_for_each_entry(w, &node->async_todo, entry) print_binder_work_ilocked(m, node->proc, " ", - " pending async transaction", w); + " pending async transaction", + w, hash_ptrs); } } @@ -6779,6 +6793,7 @@ static void print_binder_ref_olocked(struct seq_file *m, * @proc: struct binder_proc we hold the inner_proc_lock to (if any) * @node: struct binder_node to print fields of * @prev_node: struct binder_node we hold a temporary reference to (if any) + * @hash_ptrs: whether to hash @node's binder_uintptr_t fields * * Helper function to handle synchronization around printing a struct * binder_node while iterating through @proc->nodes or the dead nodes list. @@ -6791,7 +6806,7 @@ static void print_binder_ref_olocked(struct seq_file *m, static struct binder_node * print_next_binder_node_ilocked(struct seq_file *m, struct binder_proc *proc, struct binder_node *node, - struct binder_node *prev_node) + struct binder_node *prev_node, bool hash_ptrs) { /* * Take a temporary reference on the node so that isn't freed while @@ -6809,7 +6824,7 @@ print_next_binder_node_ilocked(struct seq_file *m, struct binder_proc *proc, if (prev_node) binder_put_node(prev_node); binder_node_inner_lock(node); - print_binder_node_nilocked(m, node); + print_binder_node_nilocked(m, node, hash_ptrs); binder_node_inner_unlock(node); if (proc) binder_inner_proc_lock(proc); @@ -6819,7 +6834,7 @@ print_next_binder_node_ilocked(struct seq_file *m, struct binder_proc *proc, } static void print_binder_proc(struct seq_file *m, struct binder_proc *proc, - bool print_all) + bool print_all, bool hash_ptrs) { struct binder_work *w; struct rb_node *n; @@ -6834,7 +6849,7 @@ static void print_binder_proc(struct seq_file *m, struct binder_proc *proc, binder_inner_proc_lock(proc); for (n = rb_first(&proc->threads); n; n = rb_next(n)) print_binder_thread_ilocked(m, rb_entry(n, struct binder_thread, - rb_node), print_all); + rb_node), print_all, hash_ptrs); for (n = rb_first(&proc->nodes); n; n = rb_next(n)) { struct binder_node *node = rb_entry(n, struct binder_node, @@ -6843,7 +6858,8 @@ static void print_binder_proc(struct seq_file *m, struct binder_proc *proc, continue; last_node = print_next_binder_node_ilocked(m, proc, node, - last_node); + last_node, + hash_ptrs); } binder_inner_proc_unlock(proc); if (last_node) @@ -6861,7 +6877,8 @@ static void print_binder_proc(struct seq_file *m, struct binder_proc *proc, binder_inner_proc_lock(proc); list_for_each_entry(w, &proc->todo, entry) print_binder_work_ilocked(m, proc, " ", - " pending transaction", w); + " pending transaction", w, + hash_ptrs); list_for_each_entry(w, &proc->delivered_death, entry) { seq_puts(m, " has delivered dead binder\n"); break; @@ -7037,7 +7054,7 @@ static void print_binder_proc_stats(struct seq_file *m, print_binder_stats(m, " ", &proc->stats); } -static int state_show(struct seq_file *m, void *unused) +static void print_binder_state(struct seq_file *m, bool hash_ptrs) { struct binder_proc *proc; struct binder_node *node; @@ -7050,16 +7067,38 @@ static int state_show(struct seq_file *m, void *unused) seq_puts(m, "dead nodes:\n"); hlist_for_each_entry(node, &binder_dead_nodes, dead_node) last_node = print_next_binder_node_ilocked(m, NULL, node, - last_node); + last_node, + hash_ptrs); spin_unlock(&binder_dead_nodes_lock); if (last_node) binder_put_node(last_node); mutex_lock(&binder_procs_lock); hlist_for_each_entry(proc, &binder_procs, proc_node) - print_binder_proc(m, proc, true); + print_binder_proc(m, proc, true, hash_ptrs); mutex_unlock(&binder_procs_lock); +} +static void print_binder_transactions(struct seq_file *m, bool hash_ptrs) +{ + struct binder_proc *proc; + + seq_puts(m, "binder transactions:\n"); + mutex_lock(&binder_procs_lock); + hlist_for_each_entry(proc, &binder_procs, proc_node) + print_binder_proc(m, proc, false, hash_ptrs); + mutex_unlock(&binder_procs_lock); +} + +static int state_show(struct seq_file *m, void *unused) +{ + print_binder_state(m, false); + return 0; +} + +static int state_hashed_show(struct seq_file *m, void *unused) +{ + print_binder_state(m, true); return 0; } @@ -7081,14 +7120,13 @@ static int stats_show(struct seq_file *m, void *unused) static int transactions_show(struct seq_file *m, void *unused) { - struct binder_proc *proc; - - seq_puts(m, "binder transactions:\n"); - mutex_lock(&binder_procs_lock); - hlist_for_each_entry(proc, &binder_procs, proc_node) - print_binder_proc(m, proc, false); - mutex_unlock(&binder_procs_lock); + print_binder_transactions(m, false); + return 0; +} +static int transactions_hashed_show(struct seq_file *m, void *unused) +{ + print_binder_transactions(m, true); return 0; } @@ -7101,7 +7139,7 @@ static int proc_show(struct seq_file *m, void *unused) hlist_for_each_entry(itr, &binder_procs, proc_node) { if (itr->pid == pid) { seq_puts(m, "binder proc state:\n"); - print_binder_proc(m, itr, true); + print_binder_proc(m, itr, true, false); } } mutex_unlock(&binder_procs_lock); @@ -7168,8 +7206,10 @@ const struct file_operations binder_fops = { }; DEFINE_SHOW_ATTRIBUTE(state); +DEFINE_SHOW_ATTRIBUTE(state_hashed); DEFINE_SHOW_ATTRIBUTE(stats); DEFINE_SHOW_ATTRIBUTE(transactions); +DEFINE_SHOW_ATTRIBUTE(transactions_hashed); DEFINE_SHOW_ATTRIBUTE(transaction_log); const struct binder_debugfs_entry binder_debugfs_entries[] = { @@ -7179,6 +7219,12 @@ const struct binder_debugfs_entry binder_debugfs_entries[] = { .fops = &state_fops, .data = NULL, }, + { + .name = "state_hashed", + .mode = 0444, + .fops = &state_hashed_fops, + .data = NULL, + }, { .name = "stats", .mode = 0444, @@ -7191,6 +7237,12 @@ const struct binder_debugfs_entry binder_debugfs_entries[] = { .fops = &transactions_fops, .data = NULL, }, + { + .name = "transactions_hashed", + .mode = 0444, + .fops = &transactions_hashed_fops, + .data = NULL, + }, { .name = "transaction_log", .mode = 0444,