|
@@ -59,7 +59,7 @@
|
|
|
NUM_RCU_LVL_2, \
|
|
|
NUM_RCU_LVL_3, /* == MAX_RCU_LVLS */ \
|
|
|
}, \
|
|
|
- .signaled = RCU_SIGNAL_INIT, \
|
|
|
+ .signaled = RCU_GP_IDLE, \
|
|
|
.gpnum = -300, \
|
|
|
.completed = -300, \
|
|
|
.onofflock = __SPIN_LOCK_UNLOCKED(&name.onofflock), \
|
|
@@ -657,14 +657,17 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
|
|
|
* irqs disabled.
|
|
|
*/
|
|
|
rcu_for_each_node_breadth_first(rsp, rnp) {
|
|
|
- spin_lock(&rnp->lock); /* irqs already disabled. */
|
|
|
+ spin_lock(&rnp->lock); /* irqs already disabled. */
|
|
|
rcu_preempt_check_blocked_tasks(rnp);
|
|
|
rnp->qsmask = rnp->qsmaskinit;
|
|
|
rnp->gpnum = rsp->gpnum;
|
|
|
- spin_unlock(&rnp->lock); /* irqs already disabled. */
|
|
|
+ spin_unlock(&rnp->lock); /* irqs remain disabled. */
|
|
|
}
|
|
|
|
|
|
+ rnp = rcu_get_root(rsp);
|
|
|
+ spin_lock(&rnp->lock); /* irqs already disabled. */
|
|
|
rsp->signaled = RCU_SIGNAL_INIT; /* force_quiescent_state now OK. */
|
|
|
+ spin_unlock(&rnp->lock); /* irqs remain disabled. */
|
|
|
spin_unlock_irqrestore(&rsp->onofflock, flags);
|
|
|
}
|
|
|
|
|
@@ -706,6 +709,7 @@ static void cpu_quiet_msk_finish(struct rcu_state *rsp, unsigned long flags)
|
|
|
{
|
|
|
WARN_ON_ONCE(!rcu_gp_in_progress(rsp));
|
|
|
rsp->completed = rsp->gpnum;
|
|
|
+ rsp->signaled = RCU_GP_IDLE;
|
|
|
rcu_process_gp_end(rsp, rsp->rda[smp_processor_id()]);
|
|
|
rcu_start_gp(rsp, flags); /* releases root node's rnp->lock. */
|
|
|
}
|
|
@@ -1162,9 +1166,10 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
|
|
|
}
|
|
|
spin_unlock(&rnp->lock);
|
|
|
switch (signaled) {
|
|
|
+ case RCU_GP_IDLE:
|
|
|
case RCU_GP_INIT:
|
|
|
|
|
|
- break; /* grace period still initializing, ignore. */
|
|
|
+ break; /* grace period idle or initializing, ignore. */
|
|
|
|
|
|
case RCU_SAVE_DYNTICK:
|
|
|
|
|
@@ -1178,7 +1183,8 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
|
|
|
|
|
|
/* Update state, record completion counter. */
|
|
|
spin_lock(&rnp->lock);
|
|
|
- if (lastcomp == rsp->completed) {
|
|
|
+ if (lastcomp == rsp->completed &&
|
|
|
+ rsp->signaled == RCU_SAVE_DYNTICK) {
|
|
|
rsp->signaled = RCU_FORCE_QS;
|
|
|
dyntick_record_completed(rsp, lastcomp);
|
|
|
}
|