diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-04-14 05:32:23 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-14 05:32:30 -0400 |
commit | 05cfbd66d07c44865983c8b65ae9d0037d874206 (patch) | |
tree | 084b665cc97b47d1592fe76ea0a39a7753288a02 /kernel/rcutree.c | |
parent | 31c9a24ec82926fcae49483e53566d231e705057 (diff) | |
parent | ef631b0ca01655d24e9ca7e199262c4a46416a26 (diff) |
Merge branch 'core/urgent' into core/rcu
Merge reason: new patches to be queued up depend on:
ef631b0: rcu: Make hierarchical RCU less IPI-happy
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/rcutree.c')
-rw-r--r-- | kernel/rcutree.c | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 97ce31579ec0..d2a372fb0b9b 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
@@ -78,6 +78,26 @@ DEFINE_PER_CPU(struct rcu_data, rcu_data); | |||
78 | struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh_state); | 78 | struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh_state); |
79 | DEFINE_PER_CPU(struct rcu_data, rcu_bh_data); | 79 | DEFINE_PER_CPU(struct rcu_data, rcu_bh_data); |
80 | 80 | ||
81 | /* | ||
82 | * Increment the quiescent state counter. | ||
83 | * The counter is a bit degenerated: We do not need to know | ||
84 | * how many quiescent states passed, just if there was at least | ||
85 | * one since the start of the grace period. Thus just a flag. | ||
86 | */ | ||
87 | void rcu_qsctr_inc(int cpu) | ||
88 | { | ||
89 | struct rcu_data *rdp = &per_cpu(rcu_data, cpu); | ||
90 | rdp->passed_quiesc = 1; | ||
91 | rdp->passed_quiesc_completed = rdp->completed; | ||
92 | } | ||
93 | |||
94 | void rcu_bh_qsctr_inc(int cpu) | ||
95 | { | ||
96 | struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu); | ||
97 | rdp->passed_quiesc = 1; | ||
98 | rdp->passed_quiesc_completed = rdp->completed; | ||
99 | } | ||
100 | |||
81 | #ifdef CONFIG_NO_HZ | 101 | #ifdef CONFIG_NO_HZ |
82 | DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = { | 102 | DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = { |
83 | .dynticks_nesting = 1, | 103 | .dynticks_nesting = 1, |
@@ -510,8 +530,6 @@ static void note_new_gpnum(struct rcu_state *rsp, struct rcu_data *rdp) | |||
510 | rdp->qs_pending = 1; | 530 | rdp->qs_pending = 1; |
511 | rdp->passed_quiesc = 0; | 531 | rdp->passed_quiesc = 0; |
512 | rdp->gpnum = rsp->gpnum; | 532 | rdp->gpnum = rsp->gpnum; |
513 | rdp->n_rcu_pending_force_qs = rdp->n_rcu_pending + | ||
514 | RCU_JIFFIES_TILL_FORCE_QS; | ||
515 | } | 533 | } |
516 | 534 | ||
517 | /* | 535 | /* |
@@ -558,8 +576,6 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags) | |||
558 | rsp->gpnum++; | 576 | rsp->gpnum++; |
559 | rsp->signaled = RCU_GP_INIT; /* Hold off force_quiescent_state. */ | 577 | rsp->signaled = RCU_GP_INIT; /* Hold off force_quiescent_state. */ |
560 | rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS; | 578 | rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS; |
561 | rdp->n_rcu_pending_force_qs = rdp->n_rcu_pending + | ||
562 | RCU_JIFFIES_TILL_FORCE_QS; | ||
563 | record_gp_stall_check_time(rsp); | 579 | record_gp_stall_check_time(rsp); |
564 | dyntick_record_completed(rsp, rsp->completed - 1); | 580 | dyntick_record_completed(rsp, rsp->completed - 1); |
565 | note_new_gpnum(rsp, rdp); | 581 | note_new_gpnum(rsp, rdp); |
@@ -1035,7 +1051,6 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed) | |||
1035 | { | 1051 | { |
1036 | unsigned long flags; | 1052 | unsigned long flags; |
1037 | long lastcomp; | 1053 | long lastcomp; |
1038 | struct rcu_data *rdp = rsp->rda[smp_processor_id()]; | ||
1039 | struct rcu_node *rnp = rcu_get_root(rsp); | 1054 | struct rcu_node *rnp = rcu_get_root(rsp); |
1040 | u8 signaled; | 1055 | u8 signaled; |
1041 | 1056 | ||
@@ -1046,16 +1061,13 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed) | |||
1046 | return; /* Someone else is already on the job. */ | 1061 | return; /* Someone else is already on the job. */ |
1047 | } | 1062 | } |
1048 | if (relaxed && | 1063 | if (relaxed && |
1049 | (long)(rsp->jiffies_force_qs - jiffies) >= 0 && | 1064 | (long)(rsp->jiffies_force_qs - jiffies) >= 0) |
1050 | (rdp->n_rcu_pending_force_qs - rdp->n_rcu_pending) >= 0) | ||
1051 | goto unlock_ret; /* no emergency and done recently. */ | 1065 | goto unlock_ret; /* no emergency and done recently. */ |
1052 | rsp->n_force_qs++; | 1066 | rsp->n_force_qs++; |
1053 | spin_lock(&rnp->lock); | 1067 | spin_lock(&rnp->lock); |
1054 | lastcomp = rsp->completed; | 1068 | lastcomp = rsp->completed; |
1055 | signaled = rsp->signaled; | 1069 | signaled = rsp->signaled; |
1056 | rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS; | 1070 | rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS; |
1057 | rdp->n_rcu_pending_force_qs = rdp->n_rcu_pending + | ||
1058 | RCU_JIFFIES_TILL_FORCE_QS; | ||
1059 | if (lastcomp == rsp->gpnum) { | 1071 | if (lastcomp == rsp->gpnum) { |
1060 | rsp->n_force_qs_ngp++; | 1072 | rsp->n_force_qs_ngp++; |
1061 | spin_unlock(&rnp->lock); | 1073 | spin_unlock(&rnp->lock); |
@@ -1124,8 +1136,7 @@ __rcu_process_callbacks(struct rcu_state *rsp, struct rcu_data *rdp) | |||
1124 | * If an RCU GP has gone long enough, go check for dyntick | 1136 | * If an RCU GP has gone long enough, go check for dyntick |
1125 | * idle CPUs and, if needed, send resched IPIs. | 1137 | * idle CPUs and, if needed, send resched IPIs. |
1126 | */ | 1138 | */ |
1127 | if ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0 || | 1139 | if ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0) |
1128 | (rdp->n_rcu_pending_force_qs - rdp->n_rcu_pending) < 0) | ||
1129 | force_quiescent_state(rsp, 1); | 1140 | force_quiescent_state(rsp, 1); |
1130 | 1141 | ||
1131 | /* | 1142 | /* |
@@ -1210,8 +1221,7 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu), | |||
1210 | if (unlikely(++rdp->qlen > qhimark)) { | 1221 | if (unlikely(++rdp->qlen > qhimark)) { |
1211 | rdp->blimit = LONG_MAX; | 1222 | rdp->blimit = LONG_MAX; |
1212 | force_quiescent_state(rsp, 0); | 1223 | force_quiescent_state(rsp, 0); |
1213 | } else if ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0 || | 1224 | } else if ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0) |
1214 | (rdp->n_rcu_pending_force_qs - rdp->n_rcu_pending) < 0) | ||
1215 | force_quiescent_state(rsp, 1); | 1225 | force_quiescent_state(rsp, 1); |
1216 | local_irq_restore(flags); | 1226 | local_irq_restore(flags); |
1217 | } | 1227 | } |
@@ -1270,8 +1280,7 @@ static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp) | |||
1270 | 1280 | ||
1271 | /* Has an RCU GP gone long enough to send resched IPIs &c? */ | 1281 | /* Has an RCU GP gone long enough to send resched IPIs &c? */ |
1272 | if (ACCESS_ONCE(rsp->completed) != ACCESS_ONCE(rsp->gpnum) && | 1282 | if (ACCESS_ONCE(rsp->completed) != ACCESS_ONCE(rsp->gpnum) && |
1273 | ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0 || | 1283 | ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0)) |
1274 | (rdp->n_rcu_pending_force_qs - rdp->n_rcu_pending) < 0)) | ||
1275 | return 1; | 1284 | return 1; |
1276 | 1285 | ||
1277 | /* nothing to do */ | 1286 | /* nothing to do */ |