tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: __{read,write}_once



On Wed, 6 Nov 2019 at 16:51, Kamil Rytarowski <n54%gmx.com@localhost> wrote:
>
> On 06.11.2019 16:44, Kamil Rytarowski wrote:
> > On 06.11.2019 15:57, Jason Thorpe wrote:
> >>
> >>
> >>> On Nov 6, 2019, at 5:41 AM, Kamil Rytarowski <n54%gmx.com@localhost> wrote:
> >>>
> >>> On 06.11.2019 14:37, Jason Thorpe wrote:
> >>>>
> >>>>
> >>>>> On Nov 6, 2019, at 4:45 AM, Kamil Rytarowski <n54%gmx.com@localhost> wrote:
> >>>>>
> >>>>> I propose __write_relaxed() / __read_relaxed().
> >>>>
> >>>> ...except that seems to imply the opposite of what these do.
> >>>>
> >>>> -- thorpej
> >>>>
> >>>
> >>> Rationale?
> >>>
> >>> This matches atomic_load_relaxed() / atomic_write_relaxed(), but we do
> >>> not deal with atomics here.
> >>
> >> Fair enough.  To me, the names suggest "compiler is allowed to apply relaxed constraints and tear the access if it wants".... But apparently the common meaning is "relax, bro, I know what I'm doing".  If that's the case, I can roll with it.

See below.

> >> -- thorpej
> >>
> >
> > Unless I mean something this is exactly about relaxed constraints.
>
> miss*
>
> >
> > "Relaxed operation: there are no synchronization or ordering constraints
> > imposed on other reads or writes" and without "operation's atomicity is
> > guaranteed".

In the memory consistency model world, "relaxed" has a very specific
meaning for loads/stores. It simply means that the compiler and
architecture is free to reorder the memory operation with respect to
previous or following memory operations in program order. But the
load/store still happens as one atomic operation.

For programming-language memory models, "relaxed" appears in the
context of atomic memory operations, to define their ordering w.r.t.
other operations in program order. There is a distinction between
"relaxed atomic" and plain (unannotated) memory operations at the
programming language level.

For plain operations, the compiler, in addition to the target
architecture, is free to reorder operations or even apply
optimizations that turn single plain operations into multiple
loads/stores [1, 2].
[1] https://lwn.net/Articles/793253/
[2] https://lwn.net/Articles/799218/

In the Linux kernel READ_ONCE/WRITE_ONCE are one way to specify
"relaxed atomic read/write" for accesses that fit in a word (_ONCE
also works on things larger than a word, but probably aren't atomic
anymore). For most architectures the implementation is the same, and
merely avoids compiler optimizations; the exception is Alpha, where
READ_ONCE adds a memory barrier [3].
[3] https://www.kernel.org/doc/Documentation/memory-barriers.txt

> > This is also similar to what suggested Google to apply to NetBSD in our
> > internal thread, but with a bit different naming.

What you call the ops is entirely up to you. I would not use
'{read,write}_relaxed', since as you pointed out above, is probably
more confusing. This is why I suggested 'atomic_{read,write}_relaxed'.
If you do not like the 'atomic' in there, the next best thing is
probably '{read,write}_once'.

Just note that you're now defining your own memory consistency model.
This is a complex topic that spans decades of work. The safest thing
is to stick as closely to the C11/C++11 memory model as possible [4].
The Linux kernel also has a memory model [5], but is significantly
more complex since it was defined after various primitives had been
introduced.
[4] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1479.htm
[5] https://github.com/torvalds/linux/blob/master/tools/memory-model/Documentation/explanation.txt

Best Wishes,
-- Marco

> Adding Marco to this thread.
>



Home | Main Index | Thread Index | Old Index