aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcupdate.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/rcupdate.c')
-rw-r--r--kernel/rcupdate.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index 20e9710fc21c..523e46483b99 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -53,13 +53,13 @@
53static struct rcu_ctrlblk rcu_ctrlblk = { 53static struct rcu_ctrlblk rcu_ctrlblk = {
54 .cur = -300, 54 .cur = -300,
55 .completed = -300, 55 .completed = -300,
56 .lock = SPIN_LOCK_UNLOCKED, 56 .lock = __SPIN_LOCK_UNLOCKED(&rcu_ctrlblk.lock),
57 .cpumask = CPU_MASK_NONE, 57 .cpumask = CPU_MASK_NONE,
58}; 58};
59static struct rcu_ctrlblk rcu_bh_ctrlblk = { 59static struct rcu_ctrlblk rcu_bh_ctrlblk = {
60 .cur = -300, 60 .cur = -300,
61 .completed = -300, 61 .completed = -300,
62 .lock = SPIN_LOCK_UNLOCKED, 62 .lock = __SPIN_LOCK_UNLOCKED(&rcu_bh_ctrlblk.lock),
63 .cpumask = CPU_MASK_NONE, 63 .cpumask = CPU_MASK_NONE,
64}; 64};
65 65
@@ -182,6 +182,15 @@ long rcu_batches_completed(void)
182 return rcu_ctrlblk.completed; 182 return rcu_ctrlblk.completed;
183} 183}
184 184
185/*
186 * Return the number of RCU batches processed thus far. Useful
187 * for debug and statistics.
188 */
189long rcu_batches_completed_bh(void)
190{
191 return rcu_bh_ctrlblk.completed;
192}
193
185static void rcu_barrier_callback(struct rcu_head *notused) 194static void rcu_barrier_callback(struct rcu_head *notused)
186{ 195{
187 if (atomic_dec_and_test(&rcu_barrier_cpu_count)) 196 if (atomic_dec_and_test(&rcu_barrier_cpu_count))
@@ -232,12 +241,16 @@ static void rcu_do_batch(struct rcu_data *rdp)
232 next = rdp->donelist = list->next; 241 next = rdp->donelist = list->next;
233 list->func(list); 242 list->func(list);
234 list = next; 243 list = next;
235 rdp->qlen--;
236 if (++count >= rdp->blimit) 244 if (++count >= rdp->blimit)
237 break; 245 break;
238 } 246 }
247
248 local_irq_disable();
249 rdp->qlen -= count;
250 local_irq_enable();
239 if (rdp->blimit == INT_MAX && rdp->qlen <= qlowmark) 251 if (rdp->blimit == INT_MAX && rdp->qlen <= qlowmark)
240 rdp->blimit = blimit; 252 rdp->blimit = blimit;
253
241 if (!rdp->donelist) 254 if (!rdp->donelist)
242 rdp->donetail = &rdp->donelist; 255 rdp->donetail = &rdp->donelist;
243 else 256 else
@@ -539,7 +552,7 @@ static void __devinit rcu_online_cpu(int cpu)
539 tasklet_init(&per_cpu(rcu_tasklet, cpu), rcu_process_callbacks, 0UL); 552 tasklet_init(&per_cpu(rcu_tasklet, cpu), rcu_process_callbacks, 0UL);
540} 553}
541 554
542static int rcu_cpu_notify(struct notifier_block *self, 555static int __cpuinit rcu_cpu_notify(struct notifier_block *self,
543 unsigned long action, void *hcpu) 556 unsigned long action, void *hcpu)
544{ 557{
545 long cpu = (long)hcpu; 558 long cpu = (long)hcpu;
@@ -556,7 +569,7 @@ static int rcu_cpu_notify(struct notifier_block *self,
556 return NOTIFY_OK; 569 return NOTIFY_OK;
557} 570}
558 571
559static struct notifier_block rcu_nb = { 572static struct notifier_block __cpuinitdata rcu_nb = {
560 .notifier_call = rcu_cpu_notify, 573 .notifier_call = rcu_cpu_notify,
561}; 574};
562 575
@@ -619,6 +632,7 @@ module_param(qlowmark, int, 0);
619module_param(rsinterval, int, 0); 632module_param(rsinterval, int, 0);
620#endif 633#endif
621EXPORT_SYMBOL_GPL(rcu_batches_completed); 634EXPORT_SYMBOL_GPL(rcu_batches_completed);
635EXPORT_SYMBOL_GPL(rcu_batches_completed_bh);
622EXPORT_SYMBOL_GPL(call_rcu); 636EXPORT_SYMBOL_GPL(call_rcu);
623EXPORT_SYMBOL_GPL(call_rcu_bh); 637EXPORT_SYMBOL_GPL(call_rcu_bh);
624EXPORT_SYMBOL_GPL(synchronize_rcu); 638EXPORT_SYMBOL_GPL(synchronize_rcu);