@@ -652,6 +652,75 @@ static void rcu_preempt_deferred_qs_handler(struct irq_work *iwp)
652652 local_irq_restore (flags );
653653}
654654
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+
655724/*
656725 * Handle special cases during rcu_read_unlock(), such as needing to
657726 * 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)
671740 local_irq_save (flags );
672741 irqs_were_disabled = irqs_disabled_flags (flags );
673742 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 .
675744 struct rcu_data * rdp = this_cpu_ptr (& rcu_data );
676745 struct rcu_node * rnp = rdp -> mynode ;
677746
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+
684749 // 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 ))) {
686751 // Using softirq, safe to awaken, and either the
687752 // wakeup is free or there is either an expedited
688753 // GP in flight or a potential need to deboost.
@@ -695,7 +760,7 @@ static void rcu_read_unlock_special(struct task_struct *t)
695760 set_tsk_need_resched (current );
696761 set_preempt_need_resched ();
697762 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 &&
699764 cpu_online (rdp -> cpu )) {
700765 // Get scheduler to re-evaluate and call hooks.
701766 // If !IRQ_WORK, FQS scan will eventually IPI.
0 commit comments