Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 13 Apr 2009 12:53:36 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        freebsd-hackers@freebsd.org
Cc:        Robert Watson <rwatson@freebsd.org>, Andrew Brampton <brampton+freebsd-hackers@gmail.com>
Subject:   Re: FreeBSD memguard + spinlocks
Message-ID:  <200904131253.37019.jhb@freebsd.org>
In-Reply-To: <d41814900904111403y6732cdfeme24904e8d1ed735a@mail.gmail.com>
References:  <d41814900904101616n73c30e05t3c56a6cd8d9b6c0@mail.gmail.com> <alpine.BSF.2.00.0904111607410.19879@fledge.watson.org> <d41814900904111403y6732cdfeme24904e8d1ed735a@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Saturday 11 April 2009 5:03:58 pm Andrew Brampton wrote:
> 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: ther=
e are=20
two
> > kinds of interrupt contexts -- fast/filter interrupt handlers, which=20
borrow
> > 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 c=
an't
> > perform any sort of sleep, or acquire any locks that might sleep, since=
=20
the
> > 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, do=
ing
> > 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 =
not
> > intended for use except when either in the scheduler, in a few related =
IPI
> > contexts, or when synchronizing between normal kernel code and a fast
> > handler.
> >
> > Full interrupt thread contexts are permitted to perform short lock slee=
ps,
> > 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=20
sleeping
> > 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 mem=
ory
> > allocation, free, etc, from there, but will defer it to an ithread usin=
g=20
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 shoul=
d be=20
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
> >
>=20
> 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.

You should just use a MTX_DEF mutex.  Also, if you use M_NOWAIT, you will n=
eed=20
to handle malloc() returning NULL.  In general I try to allocate things whi=
le=20
not holding any locks when possible and only acquire the lock to initialize=
=20
the memory returned from malloc().

=2D-=20
John Baldwin



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