Re: [RFC] LKMM: Add volatile_if()

Peter Zijlstra
2021-06-04T16:34:06Z

On Fri, Jun 04, 2021 at 11:09:55AM -0500, Segher Boessenkool wrote:
> I didn't find a description of the expected precise semantics anywhere
> in this patch. This however is the most important thing required here!

Fair enough; so a control-dependency is a LOAD->STORE memory ordering
provided by conditional branches.

The conditional branch instruction itself must have a data dependency on
a previous LOAD, while the branch itself guards a STORE. Then because
speculative STOREs result in out-of-thin-air values, the STORE must not
become visible until the branch is decided, which can only be done if
the LOAD is complete.

We make use of this, and would like the compiler to not ruin this code
pattern for us.

So we need the STORE to say inside the selection statement, we need the
LOAD not be optimized away, and we need the conditional branch to be
emitted.

Alternatively, we need the LOAD to be upgraded to a LOAD-ACQUIRE (an
option on platforms where this is sufficiently cheap). Which will also
ensure the STORE happens after.

So we can force the LOAD using READ_ONCE() (a volatile cast).

We can prohibit hoisting by adding a compiler barrier to the expression.
And then we use asm goto() to force emit a conditional branch. Combined
this leaves the compiler very little room to mess things up, but it does
produce sub-optimal code, and doesn't allow the LOAD-ACQUIRE upgrade
Will would like (but he can't always have that anyway due to our other
use of asm()).

We also have a 'CONTROL DEPENDENCIES' section in
Documentation/memory-barriers.txt for further reading.