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
This commit is contained in:
commit
c000131c71
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user