On Wed, 2008-04-23 at 08:07 +0200, Jens Axboe wrote:
CPU0 CPU1
local_irq_disable() local_irq_disable()
smp_call_function_single(0,..,0)
test_and_set_bit_lock()
send IPI
smp_call_function_single(1,..,0)
while(test_and_set_bit_lock())
cpu_relax();
This will spin forever, because it needs to handle the IPI in order to
free the cfd_fallback thingy, but can't for its waiting for it.
That particular deadlock can indeed be solved by making cfd_fallback
per-cpu.
But if you were to use multiple smp_call_function*() calls under a
single IRQ disabled, then that would not be sufficient. Now I can't
directly come up with a good reason to need to do that, but still.
You'd need somethine like:
local_irq_disable()
smp_call_function_single(n, func_a,..,0)
smp_call_function_single(m, func_b,..,0)
local_irq_enable()
And invite 3 cpus to the party while under memory pressure and you get
deadlock potential.
[ if it were both the same function, you'd want to use
smp_call_function() and provide a mask; if it were the same cpu you'd
want to call a function doing both ]
--