Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 11 Apr 2009 22:03:58 +0100
From:      Andrew Brampton <brampton+freebsd-hackers@gmail.com>
To:        freebsd-hackers@freebsd.org
Cc:        Robert Watson <rwatson@freebsd.org>
Subject:   Re: FreeBSD memguard + spinlocks
Message-ID:  <d41814900904111403y6732cdfeme24904e8d1ed735a@mail.gmail.com>
In-Reply-To: <alpine.BSF.2.00.0904111607410.19879@fledge.watson.org>
References:  <d41814900904101616n73c30e05t3c56a6cd8d9b6c0@mail.gmail.com> <alpine.BSF.2.00.0904111607410.19879@fledge.watson.org>

next in thread | previous in thread | raw e-mail | index | archive | help
2009/4/11 Robert Watson <rwatson@freebsd.org>:
> On Sat, 11 Apr 2009, Andrew Brampton wrote:
>
> Your understanding is mostly right. =C2=A0The missing bit is this: there =
are two
> kinds of interrupt contexts -- fast/filter interrupt handlers, which borr=
ow
> the stack and execution context of the kernel thread they preempt, and
> interrupt threads, which get their own complete thread context.
>
> Fast interrupt handlers are allowed unlock to acquire spinlocks so as to
> avoid deadlock because of the borrowed context. =C2=A0This means they can=
't
> perform any sort of sleep, or acquire any locks that might sleep, since t=
he
> thread they've preempted may hold conflicting locks, or be the one that
> would have woken up the sleep that the handler performed. =C2=A0Almost no=
 code
> will run in fast handlers -- perhaps checking some device registers, doin=
g
> work on a lockless or spinlock-protected queue, and waking up a worker
> thread.
>
> This is why, BTW, spin locks disable interrupt: they need to control
> preemption by other interrupt handlers to avoid deadlock, but they are no=
t
> intended for use except when either in the scheduler, in a few related IP=
I
> contexts, or when synchronizing between normal kernel code and a fast
> handler.
>
> Full interrupt thread contexts are permitted to perform short lock sleeps=
,
> such as those performed when contending default mutexes, rwlocks, and
> rmlocks. They are permitted to invoke kernel services such as malloc(9),
> UMA(9), the network stack, etc, as long as they use M_NOWAIT and don't
> invoke msleep(9) or similar unbounded sleeps -- again to avoid the
> possibility of deadlocks, since you don't want an interrupt thread sleepi=
ng
> waiting for an event that only it can satisfy.
>
> So the first question, really, is whether you are or mean to be using
> fast/filter interrupt handler. =C2=A0Device drivers will never call memor=
y
> allocation, free, etc, from there, but will defer it to an ithread using =
the
> filter mechanism in 8.x, or to a task queue or other worker in 7.x and
> earlier. =C2=A0If you're using a regular INTR_MPSAFE ithread, you should =
be able
> to use only default mutexes (a single atomic operation if uncontended)
> without disabling interrupts, etc.
>
> Robert N M Watson
> Computer Laboratory
> University of Cambridge
>

Thanks very much for your detailed reply. I'm slowly understanding how
everything in FreeBSD fits together, and I appreciate your help.

I've been given a project to take over, and all of the design
decisions were made before I started working on it, thus I'm playing
catch up. One of the decisions was to implement their own version of a
spin lock, which literally looks something like this:

lock_aquire() {
  critical_enter();
  while (! lockHeld ) {}
  lockHeld++;
}

This was actually the code tripping up MemGuard, as it is inside a
critical section, which MemGuard is unable to sleep within. This is
all running inside a kthread_create thread (I'm unsure of the proper
name of this type of thread).

Anyway, that is why I also asked about a lighter weight spin lock
(perhaps similar to this one). I tempted to replace this custom
spinlock with the standard MTX_DEF, however I'm unsure of its impact.
The custom spin lock seems quick and light to acquire, and it does not
concern me that a interrupt can potentially interrupt the code.

On a related note, if you change the lock in memguard to a MTX_SPIN,
it panics the kernel during boot. So that is not an option :) I was
only using memguard because I suspected memory being used after it was
freed. However, I think I will either change my locks to MTX_DEF or
live without memguard.

I realise I've not really asked any questions, but I would be grateful
for any insights anyone may have.
Andrew



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?d41814900904111403y6732cdfeme24904e8d1ed735a>