Subject: Kernel Semaphores

From: "Kevin D. Kissell" <[email-masked]>
Date: Mon, 6 Dec 1999 17:02:06 +0100

This is for Ralf and any other MIPS/Linux kernel
hackers who may be on the list.

Some time ago, I fixed the assembler macros
for waking_non_zero_interruptable and down_trylock
to be correct(ish) for MIPSEL and MIPSEB, but
there remained the issue of their requiring the use
of 64-bit instructions to work - they "cheat" by using
the same ll/sc pair to update both the count and the
waking field of the semaphore.

To make it work on 32-bit CPUs, I looked at using
the x386 model, but that one uses interrupt disables
and is intrinsically SMP-unsafe.  Now, looking at 
the comments and studying the code a bit,
it *seems* that the issue is not so much a race
condition between updates of the waking and
count fields, but a race with other functions that
may be updating the waking field.   CAN ANYONE
CONFIRM OR DENY THAT?

If it's true, it looks to me that by inventing one
new primitive in atomic.h, atomic_sub_and_return_if_gtz(),
one can:

    a) Eliminate the need for an assembly macro dedicated
        to waking_non_zero, which maps directly to the new macro.
    b) Make it possible to do waking_non_zero_interruptible in
        C, as all the examinations/updates of sem->waking can
        be made atomic
    c) Likewise simplify down_trylock() and
    d) Make waking_non_zero_trylock() SMP safe.

I've coded this up for experimentation, and will provide
the sources (at least relative to 2.2.12) to any interested
parties, but I'd really like someone who has worked
intimately with the kernel semaphores to tell me if
there really are races between updates of sem->waking
and sem->count, and if they exist, what they are!
__

Kevin D. Kissell
MIPS Technologies European Architecture Lab
[email-masked]
Tel. +33.4.78.38.70.67
FAX. +33.4.78.38.70.68

---

From: Ralf Baechle <[email-masked]>
Date: Mon, 6 Dec 1999 17:08:32 -0200

> waking field of the semaphore.

Btw, we have two variants for all the semaphore code as you know.  We
can eleminate the little endian variant by just swapping the order of
the two atomic_t members in struct semaphore which will eleminate the
maintenance problems.

> and is intrinsically SMP-unsafe.

semaphore-helper.h uses spin_lock_irqsave which is smp-safe.  The way
we do things for 64-bit MIPS is just more performant.

  Ralf