Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Sep 2009 22:58:19 +0200
From:      Attilio Rao <attilio@freebsd.org>
To:        =?UTF-8?Q?Marius_N=C3=BCnnerich?= <marius@nuenneri.ch>
Cc:        hackers@freebsd.org, Fabio Checconi <fabio@freebsd.org>
Subject:   Re: sx locks and memory barriers
Message-ID:  <3bbf2fe10909291358q3063f763md4ccba88c3b1d0be@mail.gmail.com>
In-Reply-To: <b649e5e0909291326o6faa090epd5e1d32da1d73f80@mail.gmail.com>
References:  <20090924224935.GW473@gandalf.sssup.it> <3bbf2fe10909290839w305c85c3t1532bd7733c39a6a@mail.gmail.com> <200909291425.46134.jhb@freebsd.org> <3bbf2fe10909291215i2bdd73aj13c1ac433152cab4@mail.gmail.com> <b649e5e0909291326o6faa090epd5e1d32da1d73f80@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
2009/9/29 Marius N=C3=BCnnerich <marius@nuenneri.ch>:
> On Tue, Sep 29, 2009 at 21:15, Attilio Rao <attilio@freebsd.org> wrote:
>> 2009/9/29 John Baldwin <jhb@freebsd.org>:
>>> On Tuesday 29 September 2009 11:39:37 am Attilio Rao wrote:
>>>> 2009/9/25 Fabio Checconi <fabio@freebsd.org>:
>>>> > Hi all,
>>>> >  looking at sys/sx.h I have some troubles understanding this comment=
:
>>>> >
>>>> >  * A note about memory barriers.  Exclusive locks need to use the sa=
me
>>>> >  * memory barriers as mutexes: _acq when acquiring an exclusive lock
>>>> >  * and _rel when releasing an exclusive lock.  On the other side,
>>>> >  * shared lock needs to use an _acq barrier when acquiring the lock
>>>> >  * but, since they don't update any locked data, no memory barrier i=
s
>>>> >  * needed when releasing a shared lock.
>>>> >
>>>> > In particular, I'm not understanding what prevents the following seq=
uence
>>>> > from happening:
>>>> >
>>>> > CPU A                                   CPU B
>>>> >
>>>> > sx_slock(&data->lock);
>>>> >
>>>> > sx_sunlock(&data->lock);
>>>> >
>>>> > /* reordered after the unlock
>>>> >   by the cpu */
>>>> > if (data->buffer)
>>>> >                                        sx_xlock(&data->lock);
>>>> >                                        free(data->buffer);
>>>> >                                        data->buffer =3D NULL;
>>>> >                                        sx_xunlock(&data->lock);
>>>> >
>>>> >        a =3D *data->buffer;
>>>> >
>>>> > IOW, even if readers do not modify the data protected by the lock,
>>>> > without a release barrier a memory access may leak past the unlock (=
as
>>>> > the cpu won't notice any dependency between the unlock and the fetch=
,
>>>> > feeling free to reorder them), thus potentially racing with an exclu=
sive
>>>> > writer accessing the data.
>>>> >
>>>> > On architectures where atomic ops serialize memory accesses this wou=
ld
>>>> > never happen, otherwise the sequence above seems possible; am I miss=
ing
>>>> > something?
>>>>
>>>> I think your concerns are right, possibly we need this patch:
>>>> http://www.freebsd.org/~attilio/sxrw_unlockb.diff
>>>
>>> Actually, since you are only worried about reads, I think this should b=
e
>>> an "acq" barrier rather than a "rel".  In some cases "acq" is cheaper, =
so we
>>> should prefer the cheapest barrier that provides what we need.  You wou=
ld
>>> still need to keep some language about the memory barriers since using =
"acq"
>>> for shared unlocking is different from exclusive unlocking.
>>
>> Actually, I don't think that an acq barrier ensures enough protection
>> against the reordering of 'earlier' operation thus not fixing the
>> architecture ordering problem reported by Fabio. Also, I don't think
>> we just have to care about reads (or  I don't understand what you mean
>> here).
>> However, I'm not even sure that we have faster read barriers than the
>> write one. As long as it should be true in theory I don't think that's
>> what happen in practice.
>>
>>> The memory clobber is quite heavyweight.  It actually forces gcc to for=
get any
>>> cached memory items in registers and reload everything again.  What I r=
eally
>>> want is just a barrier to tell GCC to not reorder things.  If I read a =
value
>>> in the program before acquiring a lock it is in theory fine to keep tha=
t
>>> cached across the barrier.  However, there isn't a way to do this sort =
of
>>> thing with GCC currently.
>>
>> Yes, that's the only tool we have right now with GCC. I will try to
>> look for another way, but it sounds difficult to discover.
>
> Even if we would have a mechanism to tell GCC to not reorder the
> instructions the CPU itself would still be free to reorder if there
> are no barriers. Or am I missing something?

Our code already takes care of that case in our barriers.

Attilio


--=20
Peace can only be achieved by understanding - A. Einstein



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