Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Sep 2009 22:42:13 +0200
From:      Attilio Rao <attilio@freebsd.org>
To:        Max Laier <max@love2party.net>
Cc:        freebsd-hackers@freebsd.org, Fabio Checconi <fabio@freebsd.org>
Subject:   Re: sx locks and memory barriers
Message-ID:  <3bbf2fe10909291342o4d32e381ge23e446582bb2d18@mail.gmail.com>
In-Reply-To: <200909291953.36373.max@love2party.net>
References:  <20090924224935.GW473@gandalf.sssup.it> <3bbf2fe10909290839w305c85c3t1532bd7733c39a6a@mail.gmail.com> <200909291953.36373.max@love2party.net>

next in thread | previous in thread | raw e-mail | index | archive | help
2009/9/29 Max Laier <max@love2party.net>:
> On Tuesday 29 September 2009 17:39:37 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 same
>> >  * 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 is
>> >  * needed when releasing a shared lock.
>> >
>> > In particular, I'm not understanding what prevents the following sequence
>> > 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 = NULL;
>> >                                        sx_xunlock(&data->lock);
>> >
>> >        a = *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 exclusive
>> > writer accessing the data.
>> >
>> > On architectures where atomic ops serialize memory accesses this would
>> > never happen, otherwise the sequence above seems possible; am I missing
>> > something?
>>
>> I think your concerns are right, possibly we need this patch:
>> http://www.freebsd.org/~attilio/sxrw_unlockb.diff
>>
>> However speaking with John we agreed possibly there is a more serious
>>  breakage. Possibly, memory barriers would also require to ensure the
>>  compiler to not reorder the operation, while right now, in FreeBSD, they
>>  just take care of the reordering from the architecture perspective.
>> The only way I'm aware of GCC offers that is to clobber memory.
>> I will provide a patch that address this soon, hoping that GCC will be
>> smart enough to not overhead too much the memory clobbering but just
>> try to understand what's our purpose and servers it (I will try to
>> compare code generated before and after the patch at least for tier-1
>> architectures).
>
> Does GCC really reorder accesses to volatile objects? The C Standard seems to
> object:
>
> 5.1.2.3 - 2
> Accessing a volatile object, modifying an object, modifying a file, or calling
> a function that does any of those operations are all side effects,11) which
> are changes in the state of the execution environment. Evaluation of an
> expression may produce side effects. At certain specified points in the
> execution sequence called sequence points, all side effects of previous
> evaluations shall be complete and no side effects of subsequent evaluations
> shall have taken place. (A summary of the sequence points is given in annex
> C.)

Very interesting.
I was thinking about the other operating systems which basically do
'memory clobbering' for ensuring a compiler barrier, but actually they
often forsee such a barrier without the conjuction of a memory
operand.

I think I will need to speak a bit with a GCC engineer in order to see
what do they implement in regard of volatile operands.

Attilio


-- 
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?3bbf2fe10909291342o4d32e381ge23e446582bb2d18>