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 | ||
