@@ -6374,10 +6374,10 @@ static void print_binder_transaction_ilocked(struct seq_file *m,
63746374}
63756375
63766376static void print_binder_work_ilocked (struct seq_file * m ,
6377- struct binder_proc * proc ,
6378- const char * prefix ,
6379- const char * transaction_prefix ,
6380- struct binder_work * w )
6377+ struct binder_proc * proc ,
6378+ const char * prefix ,
6379+ const char * transaction_prefix ,
6380+ struct binder_work * w )
63816381{
63826382 struct binder_node * node ;
63836383 struct binder_transaction * t ;
@@ -6427,7 +6427,7 @@ static void print_binder_work_ilocked(struct seq_file *m,
64276427
64286428static void print_binder_thread_ilocked (struct seq_file * m ,
64296429 struct binder_thread * thread ,
6430- int print_always )
6430+ bool print_always )
64316431{
64326432 struct binder_transaction * t ;
64336433 struct binder_work * w ;
@@ -6502,8 +6502,53 @@ static void print_binder_ref_olocked(struct seq_file *m,
65026502 binder_node_unlock (ref -> node );
65036503}
65046504
6505- static void print_binder_proc (struct seq_file * m ,
6506- struct binder_proc * proc , int print_all )
6505+ /**
6506+ * print_next_binder_node_ilocked() - Print binder_node from a locked list
6507+ * @m: struct seq_file for output via seq_printf()
6508+ * @proc: struct binder_proc we hold the inner_proc_lock to (if any)
6509+ * @node: struct binder_node to print fields of
6510+ * @prev_node: struct binder_node we hold a temporary reference to (if any)
6511+ *
6512+ * Helper function to handle synchronization around printing a struct
6513+ * binder_node while iterating through @proc->nodes or the dead nodes list.
6514+ * Caller must hold either @proc->inner_lock (for live nodes) or
6515+ * binder_dead_nodes_lock. This lock will be released during the body of this
6516+ * function, but it will be reacquired before returning to the caller.
6517+ *
6518+ * Return: pointer to the struct binder_node we hold a tmpref on
6519+ */
6520+ static struct binder_node *
6521+ print_next_binder_node_ilocked (struct seq_file * m , struct binder_proc * proc ,
6522+ struct binder_node * node ,
6523+ struct binder_node * prev_node )
6524+ {
6525+ /*
6526+ * Take a temporary reference on the node so that isn't freed while
6527+ * we print it.
6528+ */
6529+ binder_inc_node_tmpref_ilocked (node );
6530+ /*
6531+ * Live nodes need to drop the inner proc lock and dead nodes need to
6532+ * drop the binder_dead_nodes_lock before trying to take the node lock.
6533+ */
6534+ if (proc )
6535+ binder_inner_proc_unlock (proc );
6536+ else
6537+ spin_unlock (& binder_dead_nodes_lock );
6538+ if (prev_node )
6539+ binder_put_node (prev_node );
6540+ binder_node_inner_lock (node );
6541+ print_binder_node_nilocked (m , node );
6542+ binder_node_inner_unlock (node );
6543+ if (proc )
6544+ binder_inner_proc_lock (proc );
6545+ else
6546+ spin_lock (& binder_dead_nodes_lock );
6547+ return node ;
6548+ }
6549+
6550+ static void print_binder_proc (struct seq_file * m , struct binder_proc * proc ,
6551+ bool print_all )
65076552{
65086553 struct binder_work * w ;
65096554 struct rb_node * n ;
@@ -6516,44 +6561,29 @@ static void print_binder_proc(struct seq_file *m,
65166561 header_pos = m -> count ;
65176562
65186563 binder_inner_proc_lock (proc );
6519- for (n = rb_first (& proc -> threads ); n != NULL ; n = rb_next (n ))
6564+ for (n = rb_first (& proc -> threads ); n ; n = rb_next (n ))
65206565 print_binder_thread_ilocked (m , rb_entry (n , struct binder_thread ,
65216566 rb_node ), print_all );
65226567
6523- for (n = rb_first (& proc -> nodes ); n != NULL ; n = rb_next (n )) {
6568+ for (n = rb_first (& proc -> nodes ); n ; n = rb_next (n )) {
65246569 struct binder_node * node = rb_entry (n , struct binder_node ,
65256570 rb_node );
65266571 if (!print_all && !node -> has_async_transaction )
65276572 continue ;
65286573
6529- /*
6530- * take a temporary reference on the node so it
6531- * survives and isn't removed from the tree
6532- * while we print it.
6533- */
6534- binder_inc_node_tmpref_ilocked (node );
6535- /* Need to drop inner lock to take node lock */
6536- binder_inner_proc_unlock (proc );
6537- if (last_node )
6538- binder_put_node (last_node );
6539- binder_node_inner_lock (node );
6540- print_binder_node_nilocked (m , node );
6541- binder_node_inner_unlock (node );
6542- last_node = node ;
6543- binder_inner_proc_lock (proc );
6574+ last_node = print_next_binder_node_ilocked (m , proc , node ,
6575+ last_node );
65446576 }
65456577 binder_inner_proc_unlock (proc );
65466578 if (last_node )
65476579 binder_put_node (last_node );
65486580
65496581 if (print_all ) {
65506582 binder_proc_lock (proc );
6551- for (n = rb_first (& proc -> refs_by_desc );
6552- n != NULL ;
6553- n = rb_next (n ))
6583+ for (n = rb_first (& proc -> refs_by_desc ); n ; n = rb_next (n ))
65546584 print_binder_ref_olocked (m , rb_entry (n ,
6555- struct binder_ref ,
6556- rb_node_desc ));
6585+ struct binder_ref ,
6586+ rb_node_desc ));
65576587 binder_proc_unlock (proc );
65586588 }
65596589 binder_alloc_print_allocated (m , & proc -> alloc );
@@ -6693,7 +6723,7 @@ static void print_binder_proc_stats(struct seq_file *m,
66936723 count = 0 ;
66946724 ready_threads = 0 ;
66956725 binder_inner_proc_lock (proc );
6696- for (n = rb_first (& proc -> threads ); n != NULL ; n = rb_next (n ))
6726+ for (n = rb_first (& proc -> threads ); n ; n = rb_next (n ))
66976727 count ++ ;
66986728
66996729 list_for_each_entry (thread , & proc -> waiting_threads , waiting_thread_node )
@@ -6707,15 +6737,15 @@ static void print_binder_proc_stats(struct seq_file *m,
67076737 ready_threads ,
67086738 free_async_space );
67096739 count = 0 ;
6710- for (n = rb_first (& proc -> nodes ); n != NULL ; n = rb_next (n ))
6740+ for (n = rb_first (& proc -> nodes ); n ; n = rb_next (n ))
67116741 count ++ ;
67126742 binder_inner_proc_unlock (proc );
67136743 seq_printf (m , " nodes: %d\n" , count );
67146744 count = 0 ;
67156745 strong = 0 ;
67166746 weak = 0 ;
67176747 binder_proc_lock (proc );
6718- for (n = rb_first (& proc -> refs_by_desc ); n != NULL ; n = rb_next (n )) {
6748+ for (n = rb_first (& proc -> refs_by_desc ); n ; n = rb_next (n )) {
67196749 struct binder_ref * ref = rb_entry (n , struct binder_ref ,
67206750 rb_node_desc );
67216751 count ++ ;
@@ -6753,29 +6783,16 @@ static int state_show(struct seq_file *m, void *unused)
67536783 spin_lock (& binder_dead_nodes_lock );
67546784 if (!hlist_empty (& binder_dead_nodes ))
67556785 seq_puts (m , "dead nodes:\n" );
6756- hlist_for_each_entry (node , & binder_dead_nodes , dead_node ) {
6757- /*
6758- * take a temporary reference on the node so it
6759- * survives and isn't removed from the list
6760- * while we print it.
6761- */
6762- node -> tmp_refs ++ ;
6763- spin_unlock (& binder_dead_nodes_lock );
6764- if (last_node )
6765- binder_put_node (last_node );
6766- binder_node_lock (node );
6767- print_binder_node_nilocked (m , node );
6768- binder_node_unlock (node );
6769- last_node = node ;
6770- spin_lock (& binder_dead_nodes_lock );
6771- }
6786+ hlist_for_each_entry (node , & binder_dead_nodes , dead_node )
6787+ last_node = print_next_binder_node_ilocked (m , NULL , node ,
6788+ last_node );
67726789 spin_unlock (& binder_dead_nodes_lock );
67736790 if (last_node )
67746791 binder_put_node (last_node );
67756792
67766793 mutex_lock (& binder_procs_lock );
67776794 hlist_for_each_entry (proc , & binder_procs , proc_node )
6778- print_binder_proc (m , proc , 1 );
6795+ print_binder_proc (m , proc , true );
67796796 mutex_unlock (& binder_procs_lock );
67806797
67816798 return 0 ;
@@ -6804,7 +6821,7 @@ static int transactions_show(struct seq_file *m, void *unused)
68046821 seq_puts (m , "binder transactions:\n" );
68056822 mutex_lock (& binder_procs_lock );
68066823 hlist_for_each_entry (proc , & binder_procs , proc_node )
6807- print_binder_proc (m , proc , 0 );
6824+ print_binder_proc (m , proc , false );
68086825 mutex_unlock (& binder_procs_lock );
68096826
68106827 return 0 ;
@@ -6819,7 +6836,7 @@ static int proc_show(struct seq_file *m, void *unused)
68196836 hlist_for_each_entry (itr , & binder_procs , proc_node ) {
68206837 if (itr -> pid == pid ) {
68216838 seq_puts (m , "binder proc state:\n" );
6822- print_binder_proc (m , itr , 1 );
6839+ print_binder_proc (m , itr , true );
68236840 }
68246841 }
68256842 mutex_unlock (& binder_procs_lock );
0 commit comments