aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcuclassic.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/rcuclassic.c')
-rw-r--r--kernel/rcuclassic.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/kernel/rcuclassic.c b/kernel/rcuclassic.c
index a38895a5b8e2..214e1cde9812 100644
--- a/kernel/rcuclassic.c
+++ b/kernel/rcuclassic.c
@@ -516,10 +516,38 @@ void rcu_check_callbacks(int cpu, int user)
516 if (user || 516 if (user ||
517 (idle_cpu(cpu) && !in_softirq() && 517 (idle_cpu(cpu) && !in_softirq() &&
518 hardirq_count() <= (1 << HARDIRQ_SHIFT))) { 518 hardirq_count() <= (1 << HARDIRQ_SHIFT))) {
519
520 /*
521 * Get here if this CPU took its interrupt from user
522 * mode or from the idle loop, and if this is not a
523 * nested interrupt. In this case, the CPU is in
524 * a quiescent state, so count it.
525 *
526 * Also do a memory barrier. This is needed to handle
527 * the case where writes from a preempt-disable section
528 * of code get reordered into schedule() by this CPU's
529 * write buffer. The memory barrier makes sure that
530 * the rcu_qsctr_inc() and rcu_bh_qsctr_inc() are see
531 * by other CPUs to happen after any such write.
532 */
533
534 smp_mb(); /* See above block comment. */
519 rcu_qsctr_inc(cpu); 535 rcu_qsctr_inc(cpu);
520 rcu_bh_qsctr_inc(cpu); 536 rcu_bh_qsctr_inc(cpu);
521 } else if (!in_softirq()) 537
538 } else if (!in_softirq()) {
539
540 /*
541 * Get here if this CPU did not take its interrupt from
542 * softirq, in other words, if it is not interrupting
543 * a rcu_bh read-side critical section. This is an _bh
544 * critical section, so count it. The memory barrier
545 * is needed for the same reason as is the above one.
546 */
547
548 smp_mb(); /* See above block comment. */
522 rcu_bh_qsctr_inc(cpu); 549 rcu_bh_qsctr_inc(cpu);
550 }
523 raise_rcu_softirq(); 551 raise_rcu_softirq();
524} 552}
525 553