Re: [RFC] LKMM: Add volatile_if()

Linus Torvalds
2021-06-06T18:11:23Z

On Sun, Jun 6, 2021 at 4:56 AM Segher Boessenkool
<segher@kernel.crashing.org> wrote:
>
> And that is a simple fact, since the same assembler code (at the same
> spot in the program) will do the same thing no matter how that ended up
> there.

The thing is, that's exactl;y what gcc violates.

The example - you may not have been cc'd personally on that one - was
something like

if (READ_ONCE(a)) {
barrier();
WRITE_ONCE(b,1);
} else {
barrier();
WRITE_ONCE(b, 1);
}

and currently because gcc thinks "same exact code", it will actually
optimize this to (pseudo-asm):

LD A
"empty asm"
ST $1,B

which is very much NOT equivalent to

LD A
BEQ over
"empty asm"
ST $1,B
JMP join

over:
"empty asm"
ST $1,B

join:

and that's the whole point of the barriers.

It's not equivalent exactly because of memory ordering. In the first
case, there is no ordering on weak architectures. In the second case,
there is always an ordering, because of CPU consistency guarantees.

And no, gcc doesn't understand about memory ordering. But that's
exactly why we use inline asms.

> And the compiler always is allowed to duplicate, join, delete, you name
> it, inline assembler code. The only thing that it cares about is
> semantics of the code, just like for any other code.

See, but it VIOLATES the semantics of the code.

You can't join those two empty asm's (and then remove the branch),
because the semantics of the code really aren't the same any more if
you do. Truly.

Linus