Re: Spinlocks/semaphores jeopardized by intel P6 LOCK weakness ?

Andrea Arcangeli (andrea@suse.de)
Wed, 24 Nov 1999 18:05:24 +0100 (CET)


On Tue, 23 Nov 1999, Robert Redelmeier wrote:

># define SYNC_OTHER_CORES(x) udelay(x+3) in irq.c and recompiling
>to get a couple more usec of delay. That should help "snoop latency"
>and thermal throttling expire.

I am not sure about the deadlock you are talking about. Are you sure that
somebody really lockedup in cli() because the other CPUs didn't noticed
that we released the global irq lock?

The problem you are talking about if I understand well is:

CPU0 CPU1
-------- -----------
do_IRQ()
atomic_inc(&global_irq_count);
/* entered irq , global count == 1 */
cli()
while (test_and_set_bit(0, &global_irq_lock));
/* acquired global_irq lock */
while (test_bit(0, global_irq_lock));
spinning...
atomic_read(&global_irq_count) is > 0
/* so we take the slow path and we
release the global_irq lock */
clear_bit(0, &gloabl_irq_lock);
while (atomic_read(&global_irq_count));
spinning...

At this point it _can't_ deadlock or you hardware is broken. And after
some time the CPU1 will exit the irq and will decrement global_irq_count
and the CPU0 will try to grab the global_irq_lock again.

The machine have infinite time to update the global_irq_lock read done by
CPU1 with the value written in clear_bit() by CPU0. No lock is necessary
at all to ensure that CPU1 will eventually go ahead. Some hardware timeout
must happen someday I think. So this is not a deadlock condition IMHO.

The only reason I can see for:

__sti();
udelay()
__cli();

is to make the irq latency nicer in the CPU that is spinning inside cli()
waiting other irqs to complete.

I thought the reason for udelay() was that a simple "nop" (that btw some
recent buggy gcc/egcs optimize away) was not enough to allow the irq to
happen, it's also a quite slow path and so we could make sure to handle
the irq using an udelay. But using udelay(x+cpu) made no sense to me.

I consider it obsolete not necessary code and I believe the nop is enough
to make irq latency nice inside the cli() slow path.

Could you show me a trace of how you think the deadlock happened there and
how the udelay() can save you from the deadlock?

Andrea

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/