diff options
-rw-r--r-- | kernel/rcutree.c | 16 | ||||
-rw-r--r-- | kernel/rcutree.h | 7 |
2 files changed, 15 insertions, 8 deletions
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 0536125b0497..f3077c0ab181 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
@@ -59,7 +59,7 @@ | |||
59 | NUM_RCU_LVL_2, \ | 59 | NUM_RCU_LVL_2, \ |
60 | NUM_RCU_LVL_3, /* == MAX_RCU_LVLS */ \ | 60 | NUM_RCU_LVL_3, /* == MAX_RCU_LVLS */ \ |
61 | }, \ | 61 | }, \ |
62 | .signaled = RCU_SIGNAL_INIT, \ | 62 | .signaled = RCU_GP_IDLE, \ |
63 | .gpnum = -300, \ | 63 | .gpnum = -300, \ |
64 | .completed = -300, \ | 64 | .completed = -300, \ |
65 | .onofflock = __SPIN_LOCK_UNLOCKED(&name.onofflock), \ | 65 | .onofflock = __SPIN_LOCK_UNLOCKED(&name.onofflock), \ |
@@ -657,14 +657,17 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags) | |||
657 | * irqs disabled. | 657 | * irqs disabled. |
658 | */ | 658 | */ |
659 | rcu_for_each_node_breadth_first(rsp, rnp) { | 659 | rcu_for_each_node_breadth_first(rsp, rnp) { |
660 | spin_lock(&rnp->lock); /* irqs already disabled. */ | 660 | spin_lock(&rnp->lock); /* irqs already disabled. */ |
661 | rcu_preempt_check_blocked_tasks(rnp); | 661 | rcu_preempt_check_blocked_tasks(rnp); |
662 | rnp->qsmask = rnp->qsmaskinit; | 662 | rnp->qsmask = rnp->qsmaskinit; |
663 | rnp->gpnum = rsp->gpnum; | 663 | rnp->gpnum = rsp->gpnum; |
664 | spin_unlock(&rnp->lock); /* irqs already disabled. */ | 664 | spin_unlock(&rnp->lock); /* irqs remain disabled. */ |
665 | } | 665 | } |
666 | 666 | ||
667 | rnp = rcu_get_root(rsp); | ||
668 | spin_lock(&rnp->lock); /* irqs already disabled. */ | ||
667 | rsp->signaled = RCU_SIGNAL_INIT; /* force_quiescent_state now OK. */ | 669 | rsp->signaled = RCU_SIGNAL_INIT; /* force_quiescent_state now OK. */ |
670 | spin_unlock(&rnp->lock); /* irqs remain disabled. */ | ||
668 | spin_unlock_irqrestore(&rsp->onofflock, flags); | 671 | spin_unlock_irqrestore(&rsp->onofflock, flags); |
669 | } | 672 | } |
670 | 673 | ||
@@ -706,6 +709,7 @@ static void cpu_quiet_msk_finish(struct rcu_state *rsp, unsigned long flags) | |||
706 | { | 709 | { |
707 | WARN_ON_ONCE(!rcu_gp_in_progress(rsp)); | 710 | WARN_ON_ONCE(!rcu_gp_in_progress(rsp)); |
708 | rsp->completed = rsp->gpnum; | 711 | rsp->completed = rsp->gpnum; |
712 | rsp->signaled = RCU_GP_IDLE; | ||
709 | rcu_process_gp_end(rsp, rsp->rda[smp_processor_id()]); | 713 | rcu_process_gp_end(rsp, rsp->rda[smp_processor_id()]); |
710 | rcu_start_gp(rsp, flags); /* releases root node's rnp->lock. */ | 714 | rcu_start_gp(rsp, flags); /* releases root node's rnp->lock. */ |
711 | } | 715 | } |
@@ -1162,9 +1166,10 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed) | |||
1162 | } | 1166 | } |
1163 | spin_unlock(&rnp->lock); | 1167 | spin_unlock(&rnp->lock); |
1164 | switch (signaled) { | 1168 | switch (signaled) { |
1169 | case RCU_GP_IDLE: | ||
1165 | case RCU_GP_INIT: | 1170 | case RCU_GP_INIT: |
1166 | 1171 | ||
1167 | break; /* grace period still initializing, ignore. */ | 1172 | break; /* grace period idle or initializing, ignore. */ |
1168 | 1173 | ||
1169 | case RCU_SAVE_DYNTICK: | 1174 | case RCU_SAVE_DYNTICK: |
1170 | 1175 | ||
@@ -1178,7 +1183,8 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed) | |||
1178 | 1183 | ||
1179 | /* Update state, record completion counter. */ | 1184 | /* Update state, record completion counter. */ |
1180 | spin_lock(&rnp->lock); | 1185 | spin_lock(&rnp->lock); |
1181 | if (lastcomp == rsp->completed) { | 1186 | if (lastcomp == rsp->completed && |
1187 | rsp->signaled == RCU_SAVE_DYNTICK) { | ||
1182 | rsp->signaled = RCU_FORCE_QS; | 1188 | rsp->signaled = RCU_FORCE_QS; |
1183 | dyntick_record_completed(rsp, lastcomp); | 1189 | dyntick_record_completed(rsp, lastcomp); |
1184 | } | 1190 | } |
diff --git a/kernel/rcutree.h b/kernel/rcutree.h index 1823c6e20609..1899023b0962 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h | |||
@@ -201,9 +201,10 @@ struct rcu_data { | |||
201 | }; | 201 | }; |
202 | 202 | ||
203 | /* Values for signaled field in struct rcu_state. */ | 203 | /* Values for signaled field in struct rcu_state. */ |
204 | #define RCU_GP_INIT 0 /* Grace period being initialized. */ | 204 | #define RCU_GP_IDLE 0 /* No grace period in progress. */ |
205 | #define RCU_SAVE_DYNTICK 1 /* Need to scan dyntick state. */ | 205 | #define RCU_GP_INIT 1 /* Grace period being initialized. */ |
206 | #define RCU_FORCE_QS 2 /* Need to force quiescent state. */ | 206 | #define RCU_SAVE_DYNTICK 2 /* Need to scan dyntick state. */ |
207 | #define RCU_FORCE_QS 3 /* Need to force quiescent state. */ | ||
207 | #ifdef CONFIG_NO_HZ | 208 | #ifdef CONFIG_NO_HZ |
208 | #define RCU_SIGNAL_INIT RCU_SAVE_DYNTICK | 209 | #define RCU_SIGNAL_INIT RCU_SAVE_DYNTICK |
209 | #else /* #ifdef CONFIG_NO_HZ */ | 210 | #else /* #ifdef CONFIG_NO_HZ */ |