Subject: Locking advice when compiling the kernel with the "options MULTIPROCESSOR"
To: None <tech-kern@netbsd.org>
From: Hans Petter Selasky <hselasky@c2i.net>
List: tech-kern
Date: 12/27/2005 00:45:28
Hi,

Reference: http://mail-index.netbsd.org/tech-smp/2000/08/19/0001.html

Extract:

Locks which may be taken from interrupt code must be handled very
carefully; you must spl to the highest IPL where the lock is needed
before acquiring the lock, so that, while holding the lock, you cannot
be interrupted by code which needs to acquire the lock.


I use:

void
mtx_lock(struct mtx *mtx)
{
    u_int32_t s = splhigh();

    if(mtx_lock_held(mtx))
    {
        mtx->mtx_recurse++;
        splx(s);
        return;
    }

    simple_lock(&mtx->lock);

    mtx->s = s;
    mtx->held = 1;

    return;
}

Does this still hold true when compiling a multiprocessor enabled kernel? 
Won't the following code, found in "x86/lock.h", go into a deadlock if I hold 
"splhigh" when calling "simple_lock", because it does not release the 
interrupt level?

static __inline void
__cpu_simple_lock(__cpu_simple_lock_t *lockp)
{

        while (x86_atomic_testset_i(lockp, __SIMPLELOCK_LOCKED)
            != __SIMPLELOCK_UNLOCKED) {
                do {
                        x86_pause();
                } while (*lockp == __SIMPLELOCK_LOCKED);
        }
        __insn_barrier();
}

Yours,
--HPS