]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - kernel/rcuclassic.c
xen64: implement 64-bit update_descriptor
[linux-2.6-omap-h63xx.git] / kernel / rcuclassic.c
index d8348792f9f59c915bc7df71951229b248b8dd5b..16eeeaa9d618c7ef4c7ef4f31499fb1195a396b3 100644 (file)
@@ -89,8 +89,22 @@ static void force_quiescent_state(struct rcu_data *rdp,
                /*
                 * Don't send IPI to itself. With irqs disabled,
                 * rdp->cpu is the current cpu.
+                *
+                * cpu_online_map is updated by the _cpu_down()
+                * using stop_machine_run(). Since we're in irqs disabled
+                * section, stop_machine_run() is not exectuting, hence
+                * the cpu_online_map is stable.
+                *
+                * However,  a cpu might have been offlined _just_ before
+                * we disabled irqs while entering here.
+                * And rcu subsystem might not yet have handled the CPU_DEAD
+                * notification, leading to the offlined cpu's bit
+                * being set in the rcp->cpumask.
+                *
+                * Hence cpumask = (rcp->cpumask & cpu_online_map) to prevent
+                * sending smp_reschedule() to an offlined CPU.
                 */
-               cpumask = rcp->cpumask;
+               cpus_and(cpumask, rcp->cpumask, cpu_online_map);
                cpu_clear(rdp->cpu, cpumask);
                for_each_cpu_mask(cpu, cpumask)
                        smp_send_reschedule(cpu);
@@ -373,6 +387,10 @@ static void __rcu_offline_cpu(struct rcu_data *this_rdp,
        rcu_move_batch(this_rdp, rdp->donelist, rdp->donetail);
        rcu_move_batch(this_rdp, rdp->curlist, rdp->curtail);
        rcu_move_batch(this_rdp, rdp->nxtlist, rdp->nxttail);
+
+       local_irq_disable();
+       this_rdp->qlen += rdp->qlen;
+       local_irq_enable();
 }
 
 static void rcu_offline_cpu(int cpu)
@@ -557,7 +575,7 @@ static void __cpuinit rcu_online_cpu(int cpu)
 
        rcu_init_percpu_data(cpu, &rcu_ctrlblk, rdp);
        rcu_init_percpu_data(cpu, &rcu_bh_ctrlblk, bh_rdp);
-       open_softirq(RCU_SOFTIRQ, rcu_process_callbacks, NULL);
+       open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
 }
 
 static int __cpuinit rcu_cpu_notify(struct notifier_block *self,