diff options
Diffstat (limited to 'kernel/rcutree.c')
-rw-r--r-- | kernel/rcutree.c | 60 |
1 files changed, 49 insertions, 11 deletions
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 705f02ac7433..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 | } |
@@ -913,7 +917,20 @@ static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp) | |||
913 | spin_unlock(&rnp->lock); /* irqs remain disabled. */ | 917 | spin_unlock(&rnp->lock); /* irqs remain disabled. */ |
914 | break; | 918 | break; |
915 | } | 919 | } |
916 | rcu_preempt_offline_tasks(rsp, rnp, rdp); | 920 | |
921 | /* | ||
922 | * If there was a task blocking the current grace period, | ||
923 | * and if all CPUs have checked in, we need to propagate | ||
924 | * the quiescent state up the rcu_node hierarchy. But that | ||
925 | * is inconvenient at the moment due to deadlock issues if | ||
926 | * this should end the current grace period. So set the | ||
927 | * offlined CPU's bit in ->qsmask in order to force the | ||
928 | * next force_quiescent_state() invocation to clean up this | ||
929 | * mess in a deadlock-free manner. | ||
930 | */ | ||
931 | if (rcu_preempt_offline_tasks(rsp, rnp, rdp) && !rnp->qsmask) | ||
932 | rnp->qsmask |= mask; | ||
933 | |||
917 | mask = rnp->grpmask; | 934 | mask = rnp->grpmask; |
918 | spin_unlock(&rnp->lock); /* irqs remain disabled. */ | 935 | spin_unlock(&rnp->lock); /* irqs remain disabled. */ |
919 | rnp = rnp->parent; | 936 | rnp = rnp->parent; |
@@ -958,7 +975,7 @@ static void rcu_offline_cpu(int cpu) | |||
958 | * Invoke any RCU callbacks that have made it to the end of their grace | 975 | * Invoke any RCU callbacks that have made it to the end of their grace |
959 | * period. Thottle as specified by rdp->blimit. | 976 | * period. Thottle as specified by rdp->blimit. |
960 | */ | 977 | */ |
961 | static void rcu_do_batch(struct rcu_data *rdp) | 978 | static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp) |
962 | { | 979 | { |
963 | unsigned long flags; | 980 | unsigned long flags; |
964 | struct rcu_head *next, *list, **tail; | 981 | struct rcu_head *next, *list, **tail; |
@@ -1011,6 +1028,13 @@ static void rcu_do_batch(struct rcu_data *rdp) | |||
1011 | if (rdp->blimit == LONG_MAX && rdp->qlen <= qlowmark) | 1028 | if (rdp->blimit == LONG_MAX && rdp->qlen <= qlowmark) |
1012 | rdp->blimit = blimit; | 1029 | rdp->blimit = blimit; |
1013 | 1030 | ||
1031 | /* Reset ->qlen_last_fqs_check trigger if enough CBs have drained. */ | ||
1032 | if (rdp->qlen == 0 && rdp->qlen_last_fqs_check != 0) { | ||
1033 | rdp->qlen_last_fqs_check = 0; | ||
1034 | rdp->n_force_qs_snap = rsp->n_force_qs; | ||
1035 | } else if (rdp->qlen < rdp->qlen_last_fqs_check - qhimark) | ||
1036 | rdp->qlen_last_fqs_check = rdp->qlen; | ||
1037 | |||
1014 | local_irq_restore(flags); | 1038 | local_irq_restore(flags); |
1015 | 1039 | ||
1016 | /* Re-raise the RCU softirq if there are callbacks remaining. */ | 1040 | /* Re-raise the RCU softirq if there are callbacks remaining. */ |
@@ -1142,9 +1166,10 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed) | |||
1142 | } | 1166 | } |
1143 | spin_unlock(&rnp->lock); | 1167 | spin_unlock(&rnp->lock); |
1144 | switch (signaled) { | 1168 | switch (signaled) { |
1169 | case RCU_GP_IDLE: | ||
1145 | case RCU_GP_INIT: | 1170 | case RCU_GP_INIT: |
1146 | 1171 | ||
1147 | break; /* grace period still initializing, ignore. */ | 1172 | break; /* grace period idle or initializing, ignore. */ |
1148 | 1173 | ||
1149 | case RCU_SAVE_DYNTICK: | 1174 | case RCU_SAVE_DYNTICK: |
1150 | 1175 | ||
@@ -1158,7 +1183,8 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed) | |||
1158 | 1183 | ||
1159 | /* Update state, record completion counter. */ | 1184 | /* Update state, record completion counter. */ |
1160 | spin_lock(&rnp->lock); | 1185 | spin_lock(&rnp->lock); |
1161 | if (lastcomp == rsp->completed) { | 1186 | if (lastcomp == rsp->completed && |
1187 | rsp->signaled == RCU_SAVE_DYNTICK) { | ||
1162 | rsp->signaled = RCU_FORCE_QS; | 1188 | rsp->signaled = RCU_FORCE_QS; |
1163 | dyntick_record_completed(rsp, lastcomp); | 1189 | dyntick_record_completed(rsp, lastcomp); |
1164 | } | 1190 | } |
@@ -1224,7 +1250,7 @@ __rcu_process_callbacks(struct rcu_state *rsp, struct rcu_data *rdp) | |||
1224 | } | 1250 | } |
1225 | 1251 | ||
1226 | /* If there are callbacks ready, invoke them. */ | 1252 | /* If there are callbacks ready, invoke them. */ |
1227 | rcu_do_batch(rdp); | 1253 | rcu_do_batch(rsp, rdp); |
1228 | } | 1254 | } |
1229 | 1255 | ||
1230 | /* | 1256 | /* |
@@ -1288,10 +1314,20 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu), | |||
1288 | rcu_start_gp(rsp, nestflag); /* releases rnp_root->lock. */ | 1314 | rcu_start_gp(rsp, nestflag); /* releases rnp_root->lock. */ |
1289 | } | 1315 | } |
1290 | 1316 | ||
1291 | /* Force the grace period if too many callbacks or too long waiting. */ | 1317 | /* |
1292 | if (unlikely(++rdp->qlen > qhimark)) { | 1318 | * Force the grace period if too many callbacks or too long waiting. |
1319 | * Enforce hysteresis, and don't invoke force_quiescent_state() | ||
1320 | * if some other CPU has recently done so. Also, don't bother | ||
1321 | * invoking force_quiescent_state() if the newly enqueued callback | ||
1322 | * is the only one waiting for a grace period to complete. | ||
1323 | */ | ||
1324 | if (unlikely(++rdp->qlen > rdp->qlen_last_fqs_check + qhimark)) { | ||
1293 | rdp->blimit = LONG_MAX; | 1325 | rdp->blimit = LONG_MAX; |
1294 | force_quiescent_state(rsp, 0); | 1326 | if (rsp->n_force_qs == rdp->n_force_qs_snap && |
1327 | *rdp->nxttail[RCU_DONE_TAIL] != head) | ||
1328 | force_quiescent_state(rsp, 0); | ||
1329 | rdp->n_force_qs_snap = rsp->n_force_qs; | ||
1330 | rdp->qlen_last_fqs_check = rdp->qlen; | ||
1295 | } else if ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0) | 1331 | } else if ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0) |
1296 | force_quiescent_state(rsp, 1); | 1332 | force_quiescent_state(rsp, 1); |
1297 | local_irq_restore(flags); | 1333 | local_irq_restore(flags); |
@@ -1523,6 +1559,8 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptable) | |||
1523 | rdp->beenonline = 1; /* We have now been online. */ | 1559 | rdp->beenonline = 1; /* We have now been online. */ |
1524 | rdp->preemptable = preemptable; | 1560 | rdp->preemptable = preemptable; |
1525 | rdp->passed_quiesc_completed = lastcomp - 1; | 1561 | rdp->passed_quiesc_completed = lastcomp - 1; |
1562 | rdp->qlen_last_fqs_check = 0; | ||
1563 | rdp->n_force_qs_snap = rsp->n_force_qs; | ||
1526 | rdp->blimit = blimit; | 1564 | rdp->blimit = blimit; |
1527 | spin_unlock(&rnp->lock); /* irqs remain disabled. */ | 1565 | spin_unlock(&rnp->lock); /* irqs remain disabled. */ |
1528 | 1566 | ||