lkml.org 
[lkml]   [2021]   [Jun]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [RFC] LKMM: Add volatile_if()
    On Sun, Jun 06, 2021 at 11:04:49AM -0700, Linus Torvalds wrote:
    > 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.

    To be fair, the same argument applies even without the asm code. The
    compiler will translate

    if (READ_ONCE(a))
    WRITE_ONCE(b, 1);
    else
    WRITE_ONCE(b, 1);

    to

    LD A
    ST $1,B

    intstead of

    LD A
    BEQ over
    ST $1,B
    JMP join

    over:
    ST $1,B

    join:

    And these two are different for the same memory ordering reasons as
    above.

    Alan

    \
     
     \ /
      Last update: 2021-06-06 20:23    [W:4.192 / U:0.056 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site