|
@@ -89,8 +89,22 @@ static void force_quiescent_state(struct rcu_data *rdp,
|
|
/*
|
|
/*
|
|
* Don't send IPI to itself. With irqs disabled,
|
|
* Don't send IPI to itself. With irqs disabled,
|
|
* rdp->cpu is the current cpu.
|
|
* 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);
|
|
cpu_clear(rdp->cpu, cpumask);
|
|
for_each_cpu_mask(cpu, cpumask)
|
|
for_each_cpu_mask(cpu, cpumask)
|
|
smp_send_reschedule(cpu);
|
|
smp_send_reschedule(cpu);
|