On 31 October 2012 23:30, Peter Fordham <peter.fordham@gmail.com> wrote:
OK so if I understand you correctly your saying that the memory
barriers aren't fundamental to the correct operation of this spinlock
itself but are required to make all the memory access started inside
the critical section actually complete inside the critical section,
right?

Partially.
 
I guess what I'm saying is that isn't it up to the calling code to
decide exactly how this should be done rather than the locking code.
For example, if I'm just using a spinlock in the place of a mutex in a
time critical section of where I want to avoid a call into the
scheduler and I'm not really poking registers in a memory mapped
device, just updating some shared data structure in normal cache-able
memory, it seems inappropriate to use DMBs. I see examples of this in
the ext4 code.

In real driver code where we do access registers, shouldn't the driver
be responsible for calling smp_mb where appropriate?

Its not about registers at all. Suppose you have following code sequence:

global variable x = 0;

fn-1()
{
  while (1) {
     spin_lock()
      if (x == 1) {
           spin_unlock();
            return;
      }
     spin_unlock();
   }
}

And in an interrupt handler

handler()
{
spin_lock();
x=1;

if (some-other-event)
  x = 0;
spin_unlock();
}

Now, suppose this some-other-event is returning true for us. Then the
expected behavior of this code should be, the first function is running
an infinite loop.

But for ARMv6 and above normal memory is weakly ordered. i.e. compiler
and processor are free to move instructions doing reads writes to memory
before and after other instructions. Also, they can break one memory transaction
into two and join 2 into one... etc..

Now who will guarantee that, x is always read after taking the lock in function 1?
Because if x moves before the instruction doing the increment on spin_lock variable,
then value of x may be read when it is made 1 by the handler and so before the
lock is released by the handler.

So, it is responsibility of  lock,unlock to make sure that instructions executed within
lock/unlock must stay within these two and don't jump out. This is not guaranteed
with ARMv6 and above.

STREX and LDREX are for atomic load and store on SMP systems

Hope you understood what i am pointing at??

--
viresh