Commit c000131c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'core-fixes-for-linus' of...

Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  rcu: fix hotplug vs rcu race
parents 041924ec 8558f8f8
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -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);