@@ -542,6 +542,65 @@ static bool synchronize_rcu_expedited_wait_once(long tlimit)
542
542
return false;
543
543
}
544
544
545
+ /*
546
+ * Print out an expedited RCU CPU stall warning message.
547
+ */
548
+ static void synchronize_rcu_expedited_stall (unsigned long jiffies_start , unsigned long j )
549
+ {
550
+ int cpu ;
551
+ unsigned long mask ;
552
+ int ndetected ;
553
+ struct rcu_node * rnp ;
554
+ struct rcu_node * rnp_root = rcu_get_root ();
555
+
556
+ pr_err ("INFO: %s detected expedited stalls on CPUs/tasks: {" , rcu_state .name );
557
+ ndetected = 0 ;
558
+ rcu_for_each_leaf_node (rnp ) {
559
+ ndetected += rcu_print_task_exp_stall (rnp );
560
+ for_each_leaf_node_possible_cpu (rnp , cpu ) {
561
+ struct rcu_data * rdp ;
562
+
563
+ mask = leaf_node_cpu_bit (rnp , cpu );
564
+ if (!(READ_ONCE (rnp -> expmask ) & mask ))
565
+ continue ;
566
+ ndetected ++ ;
567
+ rdp = per_cpu_ptr (& rcu_data , cpu );
568
+ pr_cont (" %d-%c%c%c%c" , cpu ,
569
+ "O." [!!cpu_online (cpu )],
570
+ "o." [!!(rdp -> grpmask & rnp -> expmaskinit )],
571
+ "N." [!!(rdp -> grpmask & rnp -> expmaskinitnext )],
572
+ "D." [!!data_race (rdp -> cpu_no_qs .b .exp )]);
573
+ }
574
+ }
575
+ pr_cont (" } %lu jiffies s: %lu root: %#lx/%c\n" ,
576
+ j - jiffies_start , rcu_state .expedited_sequence , data_race (rnp_root -> expmask ),
577
+ ".T" [!!data_race (rnp_root -> exp_tasks )]);
578
+ if (ndetected ) {
579
+ pr_err ("blocking rcu_node structures (internal RCU debug):" );
580
+ rcu_for_each_node_breadth_first (rnp ) {
581
+ if (rnp == rnp_root )
582
+ continue ; /* printed unconditionally */
583
+ if (sync_rcu_exp_done_unlocked (rnp ))
584
+ continue ;
585
+ pr_cont (" l=%u:%d-%d:%#lx/%c" ,
586
+ rnp -> level , rnp -> grplo , rnp -> grphi , data_race (rnp -> expmask ),
587
+ ".T" [!!data_race (rnp -> exp_tasks )]);
588
+ }
589
+ pr_cont ("\n" );
590
+ }
591
+ rcu_for_each_leaf_node (rnp ) {
592
+ for_each_leaf_node_possible_cpu (rnp , cpu ) {
593
+ mask = leaf_node_cpu_bit (rnp , cpu );
594
+ if (!(READ_ONCE (rnp -> expmask ) & mask ))
595
+ continue ;
596
+ preempt_disable (); // For smp_processor_id() in dump_cpu_task().
597
+ dump_cpu_task (cpu );
598
+ preempt_enable ();
599
+ }
600
+ rcu_exp_print_detail_task_stall_rnp (rnp );
601
+ }
602
+ }
603
+
545
604
/*
546
605
* Wait for the expedited grace period to elapse, issuing any needed
547
606
* RCU CPU stall warnings along the way.
@@ -553,10 +612,8 @@ static void synchronize_rcu_expedited_wait(void)
553
612
unsigned long jiffies_stall ;
554
613
unsigned long jiffies_start ;
555
614
unsigned long mask ;
556
- int ndetected ;
557
615
struct rcu_data * rdp ;
558
616
struct rcu_node * rnp ;
559
- struct rcu_node * rnp_root = rcu_get_root ();
560
617
unsigned long flags ;
561
618
562
619
trace_rcu_exp_grace_period (rcu_state .name , rcu_exp_gp_seq_endval (), TPS ("startwait" ));
@@ -593,55 +650,7 @@ static void synchronize_rcu_expedited_wait(void)
593
650
j = jiffies ;
594
651
rcu_stall_notifier_call_chain (RCU_STALL_NOTIFY_EXP , (void * )(j - jiffies_start ));
595
652
trace_rcu_stall_warning (rcu_state .name , TPS ("ExpeditedStall" ));
596
- pr_err ("INFO: %s detected expedited stalls on CPUs/tasks: {" ,
597
- rcu_state .name );
598
- ndetected = 0 ;
599
- rcu_for_each_leaf_node (rnp ) {
600
- ndetected += rcu_print_task_exp_stall (rnp );
601
- for_each_leaf_node_possible_cpu (rnp , cpu ) {
602
- struct rcu_data * rdp ;
603
-
604
- mask = leaf_node_cpu_bit (rnp , cpu );
605
- if (!(READ_ONCE (rnp -> expmask ) & mask ))
606
- continue ;
607
- ndetected ++ ;
608
- rdp = per_cpu_ptr (& rcu_data , cpu );
609
- pr_cont (" %d-%c%c%c%c" , cpu ,
610
- "O." [!!cpu_online (cpu )],
611
- "o." [!!(rdp -> grpmask & rnp -> expmaskinit )],
612
- "N." [!!(rdp -> grpmask & rnp -> expmaskinitnext )],
613
- "D." [!!data_race (rdp -> cpu_no_qs .b .exp )]);
614
- }
615
- }
616
- pr_cont (" } %lu jiffies s: %lu root: %#lx/%c\n" ,
617
- j - jiffies_start , rcu_state .expedited_sequence ,
618
- data_race (rnp_root -> expmask ),
619
- ".T" [!!data_race (rnp_root -> exp_tasks )]);
620
- if (ndetected ) {
621
- pr_err ("blocking rcu_node structures (internal RCU debug):" );
622
- rcu_for_each_node_breadth_first (rnp ) {
623
- if (rnp == rnp_root )
624
- continue ; /* printed unconditionally */
625
- if (sync_rcu_exp_done_unlocked (rnp ))
626
- continue ;
627
- pr_cont (" l=%u:%d-%d:%#lx/%c" ,
628
- rnp -> level , rnp -> grplo , rnp -> grphi ,
629
- data_race (rnp -> expmask ),
630
- ".T" [!!data_race (rnp -> exp_tasks )]);
631
- }
632
- pr_cont ("\n" );
633
- }
634
- rcu_for_each_leaf_node (rnp ) {
635
- for_each_leaf_node_possible_cpu (rnp , cpu ) {
636
- mask = leaf_node_cpu_bit (rnp , cpu );
637
- if (!(READ_ONCE (rnp -> expmask ) & mask ))
638
- continue ;
639
- preempt_disable (); // For smp_processor_id() in dump_cpu_task().
640
- dump_cpu_task (cpu );
641
- preempt_enable ();
642
- }
643
- rcu_exp_print_detail_task_stall_rnp (rnp );
644
- }
653
+ synchronize_rcu_expedited_stall (jiffies_start , j );
645
654
jiffies_stall = 3 * rcu_exp_jiffies_till_stall_check () + 3 ;
646
655
panic_on_rcu_stall ();
647
656
}
0 commit comments