Re: spinlock help

From: Andrew Morton (andrewm@uow.edu.au)
Date: Thu Mar 08 2001 - 06:34:30 EST


"Hen, Shmulik" wrote:
>
> OK guys, you were right. The bug was in our code - sorry for trouble.
> Turns out that while I was away, the problem was solved by someone else. The
> problem is probably related to the fact that when we did
> 'spin_lock_irqsave(c,d)', 'd' was a global variable. The fix was to wrap the
> call with another function and declare 'd' as local. I can't quite explain,
> but I think that changing from a static to automatic variable made the
> difference. My best guess is that since 'd' is passed by value and not by
> reference, the macro expansion of spin_lock_irqsave() relies on the location
> of 'd' in the stack and if 'd' was on the heap instead, it might get
> trashed.
>

Yes, that makes sense.

spin_lock_irqsave() really means "save the current irq mask
on the stack, then disable interrupts". spin_lock_irqrestore()
says "restore the current interrupt mask from the stack". So they
nest, and spin_lock_irqsave() doesn't have to care whether or
not interrupts are currently enabled.

Using a global variable you could get something like:

CPU0: CPU1
         
__cli();
spin_lock_irqsave(lock, global)
                                          __sti();
                                          spin_lock_irqsave(lock2, global)
                                          spin_lock_irqrestore(lock2, global)
spin_unlock_irqrestore(lock, global)
/* interrupts should be disabled */

Here, CPU1 will set `global' to "interrupts enabled". So when
CPU0 restores its flags from `global' it will be picking up
CPU1's flags, not its own!

There are probably less subtle failure modes than this..

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



This archive was generated by hypermail 2b29 : Thu Mar 15 2001 - 21:00:07 EST