@@ -652,6 +652,75 @@ static void rcu_preempt_deferred_qs_handler(struct irq_work *iwp)
652
652
local_irq_restore (flags );
653
653
}
654
654
655
+ /*
656
+ * Check if expedited grace period processing during unlock is needed.
657
+ *
658
+ * This function determines whether expedited handling is required based on:
659
+ * 1. Task blocking an expedited grace period (based on a heuristic, could be
660
+ * false-positive, see below.)
661
+ * 2. CPU participating in an expedited grace period
662
+ * 3. Strict grace period mode requiring expedited handling
663
+ * 4. RCU priority deboosting needs when interrupts were disabled
664
+ *
665
+ * @t: The task being checked
666
+ * @rdp: The per-CPU RCU data
667
+ * @rnp: The RCU node for this CPU
668
+ * @irqs_were_disabled: Whether interrupts were disabled before rcu_read_unlock()
669
+ *
670
+ * Returns true if expedited processing of the rcu_read_unlock() is needed.
671
+ */
672
+ static bool rcu_unlock_needs_exp_handling (struct task_struct * t ,
673
+ struct rcu_data * rdp ,
674
+ struct rcu_node * rnp ,
675
+ bool irqs_were_disabled )
676
+ {
677
+ /*
678
+ * Check if this task is blocking an expedited grace period. If the
679
+ * task was preempted within an RCU read-side critical section and is
680
+ * on the expedited grace period blockers list (exp_tasks), we need
681
+ * expedited handling to unblock the expedited GP. This is not an exact
682
+ * check because 't' might not be on the exp_tasks list at all - its
683
+ * just a fast heuristic that can be false-positive sometimes.
684
+ */
685
+ if (t -> rcu_blocked_node && READ_ONCE (t -> rcu_blocked_node -> exp_tasks ))
686
+ return true;
687
+
688
+ /*
689
+ * Check if this CPU is participating in an expedited grace period.
690
+ * The expmask bitmap tracks which CPUs need to check in for the
691
+ * current expedited GP. If our CPU's bit is set, we need expedited
692
+ * handling to help complete the expedited GP.
693
+ */
694
+ if (rdp -> grpmask & READ_ONCE (rnp -> expmask ))
695
+ return true;
696
+
697
+ /*
698
+ * In CONFIG_RCU_STRICT_GRACE_PERIOD=y kernels, all grace periods
699
+ * are treated as short for testing purposes even if that means
700
+ * disturbing the system more. Check if either:
701
+ * - This CPU has not yet reported a quiescent state, or
702
+ * - This task was preempted within an RCU critical section
703
+ * In either case, require expedited handling for strict GP mode.
704
+ */
705
+ if (IS_ENABLED (CONFIG_RCU_STRICT_GRACE_PERIOD ) &&
706
+ ((rdp -> grpmask & READ_ONCE (rnp -> qsmask )) || t -> rcu_blocked_node ))
707
+ return true;
708
+
709
+ /*
710
+ * RCU priority boosting case: If a task is subject to RCU priority
711
+ * boosting and exits an RCU read-side critical section with interrupts
712
+ * disabled, we need expedited handling to ensure timely deboosting.
713
+ * Without this, a low-priority task could incorrectly run at high
714
+ * real-time priority for an extended period degrading real-time
715
+ * responsiveness. This applies to all CONFIG_RCU_BOOST=y kernels,
716
+ * not just to PREEMPT_RT.
717
+ */
718
+ if (IS_ENABLED (CONFIG_RCU_BOOST ) && irqs_were_disabled && t -> rcu_blocked_node )
719
+ return true;
720
+
721
+ return false;
722
+ }
723
+
655
724
/*
656
725
* Handle special cases during rcu_read_unlock(), such as needing to
657
726
* notify RCU core processing or task having blocked during the RCU
@@ -671,18 +740,14 @@ static void rcu_read_unlock_special(struct task_struct *t)
671
740
local_irq_save (flags );
672
741
irqs_were_disabled = irqs_disabled_flags (flags );
673
742
if (preempt_bh_were_disabled || irqs_were_disabled ) {
674
- bool expboost ; // Expedited GP in flight or possible boosting .
743
+ bool needs_exp ; // Expedited handling needed .
675
744
struct rcu_data * rdp = this_cpu_ptr (& rcu_data );
676
745
struct rcu_node * rnp = rdp -> mynode ;
677
746
678
- expboost = (t -> rcu_blocked_node && READ_ONCE (t -> rcu_blocked_node -> exp_tasks )) ||
679
- (rdp -> grpmask & READ_ONCE (rnp -> expmask )) ||
680
- (IS_ENABLED (CONFIG_RCU_STRICT_GRACE_PERIOD ) &&
681
- ((rdp -> grpmask & READ_ONCE (rnp -> qsmask )) || t -> rcu_blocked_node )) ||
682
- (IS_ENABLED (CONFIG_RCU_BOOST ) && irqs_were_disabled &&
683
- t -> rcu_blocked_node );
747
+ needs_exp = rcu_unlock_needs_exp_handling (t , rdp , rnp , irqs_were_disabled );
748
+
684
749
// Need to defer quiescent state until everything is enabled.
685
- if (use_softirq && (in_hardirq () || (expboost && !irqs_were_disabled ))) {
750
+ if (use_softirq && (in_hardirq () || (needs_exp && !irqs_were_disabled ))) {
686
751
// Using softirq, safe to awaken, and either the
687
752
// wakeup is free or there is either an expedited
688
753
// GP in flight or a potential need to deboost.
@@ -695,7 +760,7 @@ static void rcu_read_unlock_special(struct task_struct *t)
695
760
set_tsk_need_resched (current );
696
761
set_preempt_need_resched ();
697
762
if (IS_ENABLED (CONFIG_IRQ_WORK ) && irqs_were_disabled &&
698
- expboost && rdp -> defer_qs_iw_pending != DEFER_QS_PENDING &&
763
+ needs_exp && rdp -> defer_qs_iw_pending != DEFER_QS_PENDING &&
699
764
cpu_online (rdp -> cpu )) {
700
765
// Get scheduler to re-evaluate and call hooks.
701
766
// If !IRQ_WORK, FQS scan will eventually IPI.
0 commit comments