Skip to content

Commit 5390473

Browse files
committed
rcu: Don't penalize priority boosting when there is nothing to boost
RCU priority boosting cannot do anything unless there is at least one task blocking the current RCU grace period that was preempted within the RCU read-side critical section that it still resides in. However, the current rcu_torture_boost_failed() code will count this as an RCU priority-boosting failure if there were no CPUs blocking the current grace period. This situation can happen (for example) if the last CPU blocking the current grace period was subjected to vCPU preemption, which is always a risk for rcutorture guest OSes. This commit therefore causes rcu_torture_boost_failed() to refrain from reporting failure unless there is at least one task blocking the current RCU grace period that was preempted within the RCU read-side critical section that it still resides in. Signed-off-by: Paul E. McKenney <[email protected]>
1 parent 7ab2bd3 commit 5390473

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

kernel/rcu/tree_stall.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -723,25 +723,36 @@ static void check_cpu_stall(struct rcu_data *rdp)
723723
* count this as an RCU priority boosting failure. A return of true says
724724
* RCU priority boosting is to blame, and false says otherwise. If false
725725
* is returned, the first of the CPUs to blame is stored through cpup.
726+
* If there was no CPU blocking the current grace period, but also nothing
727+
* in need of being boosted, *cpup is set to -1. This can happen in case
728+
* of vCPU preemption while the last CPU is reporting its quiscent state,
729+
* for example.
726730
*
727731
* If cpup is NULL, then a lockless quick check is carried out, suitable
728732
* for high-rate usage. On the other hand, if cpup is non-NULL, each
729733
* rcu_node structure's ->lock is acquired, ruling out high-rate usage.
730734
*/
731735
bool rcu_check_boost_fail(unsigned long gp_state, int *cpup)
732736
{
737+
bool atb = false;
733738
int cpu;
734739
unsigned long flags;
735740
struct rcu_node *rnp;
736741

737742
rcu_for_each_leaf_node(rnp) {
738743
if (!cpup) {
739-
if (READ_ONCE(rnp->qsmask))
744+
if (READ_ONCE(rnp->qsmask)) {
740745
return false;
741-
else
746+
} else {
747+
if (READ_ONCE(rnp->gp_tasks))
748+
atb = true;
742749
continue;
750+
}
743751
}
752+
*cpup = -1;
744753
raw_spin_lock_irqsave_rcu_node(rnp, flags);
754+
if (rnp->gp_tasks)
755+
atb = true;
745756
if (!rnp->qsmask) {
746757
// No CPUs without quiescent states for this rnp.
747758
raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
@@ -758,7 +769,7 @@ bool rcu_check_boost_fail(unsigned long gp_state, int *cpup)
758769
raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
759770
}
760771
// Can't blame CPUs, so must blame RCU priority boosting.
761-
return true;
772+
return atb;
762773
}
763774
EXPORT_SYMBOL_GPL(rcu_check_boost_fail);
764775

0 commit comments

Comments
 (0)