From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
To: Hugh Dickins <hughd@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Rik van Riel <riel@redhat.com>,
Andrew Morton <akpm@linux-foundation.org>,
Nick Piggin <npiggin@kernel.dk>,
Andrea Arcangeli <aarcange@redhat.com>,
linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
linux-mm@kvack.org
Subject: Re: [RFC] page-table walkers vs memory order
Date: Wed, 25 Jul 2012 15:37:13 -0700 [thread overview]
Message-ID: <20120725223713.GV2378@linux.vnet.ibm.com> (raw)
In-Reply-To: <alpine.LSU.2.00.1207251452160.2084@eggly.anvils>
On Wed, Jul 25, 2012 at 03:09:48PM -0700, Hugh Dickins wrote:
> On Wed, 25 Jul 2012, Paul E. McKenney wrote:
> > On Wed, Jul 25, 2012 at 01:26:43PM -0700, Hugh Dickins wrote:
> > > On Wed, 25 Jul 2012, Paul E. McKenney wrote:
> > > > On Tue, Jul 24, 2012 at 02:51:05PM -0700, Hugh Dickins wrote:
> > > > >
> > > > > I'm totally unclear whether the kernel ever gets built with these
> > > > > 'creative' compilers that you refer to. Is ACCESS_ONCE() a warning
> > > > > of where some future compiler would be permitted to mess with our
> > > > > assumptions? Or is it actually saving us already today? Would we
> > > > > know? Could there be a boottime test that would tell us? Is it
> > > > > likely that a future compiler would have an "--access_once"
> > > > > option that the kernel build would want to turn on?
> > > >
> > > > The problem is that, unless you tell it otherwise, the compiler is
> > > > permitted to assume that the code that it is generating is the only thing
> > > > active in that address space at that time. So the compiler might know
> > > > that it already has a perfectly good copy of that value somewhere in
> > > > its registers, or it might decide to fetch the value twice rather than
> > > > once due to register pressure, either of which can be fatal in SMP code.
> > > > And then there are more aggressive optimizations as well.
> > > >
> > > > ACCESS_ONCE() is a way of telling the compiler to access the value
> > > > once, regardless of what cute single-threaded optimizations that it
> > > > otherwise might want to apply.
> > >
> > > Right, but you say "might": I have never heard it asserted, that we do
> > > build the kernel with a compiler which actually makes such optimizations.
> >
> > The compiler we use today can and has hurt us with double-fetching
> > and old-value-reuse optimizations. There have been several that have
> > "optimized" things like "while (foo)" into "tmp = foo; while (tmp)"
> > in the Linux kernel, which have been dealt with by recoding.
>
> Ah yes, those: I think we need ACCESS_EVERY_TIME() for those ones ;)
;-) ;-) ;-)
> I consider the double-fetching ones more insidious,
> less obviously in need of the volatile cast.
Agreed!
> > You might argue that the compiler cannot reasonably apply such an
> > optimization in some given case, but the compiler does much more detailed
> > analysis of the code than most people are willing to do (certainly more
> > than I am usually willing to do!), so I believe that a little paranoia is
> > quite worthwhile.
> >
> > > There's a lot of other surprising things which a compiler is permitted
> > > to do, but we would simply not use such a compiler to build the kernel.
> >
> > Unless we get the gcc folks to build and boot the Linux kernel as part
> > of their test suite (maybe they already do, but not that I know of),
> > how would either they or we know that they had deployed a destructive
> > optimization?
>
> We find out after it hits us, and someone studies the disassembly -
> if we're lucky enough to crash near the origin of the problem.
Color me unreassured. ;-)
> > > Does some version of gcc, under the options which we insist upon,
> > > make such optimizations on any of the architectures which we support?
> >
> > Pretty much any production-quality compiler will do double-fetch
> > and old-value-reuse optimizations, the former especially on 32-bit
> > x86.
>
> That makes good sense, yes: so, under register pressure, they may
> refetch from global memory, instead of using a temporary on local stack.
>
> > I don't know of any production-quality compilers that do value
> > speculation, which would make the compiler act like DEC Alpha hardware,
> > and I would hope that if this does appear, (1) we would have warning
> > and (2) it could be turned off. But there has been a lot of work on
> > this topic, so we would be foolish to rule it out.
>
> I think you're justified in expecting both (1) and (2) there.
Here is hoping!
> > But the currently deployed optimizations can already cause enough trouble.
> >
> > > Or is there some other compiler in use on the kernel, which makes
> > > such optimizations? It seems a long time since I heard of building
> > > the kernel with icc. clang?
> > >
> > > I don't mind the answer "Yes, you idiot" - preferably with an example
> > > or two of which compiler and which piece of code it has bitten us on.
> > > I don't mind the answer "We just don't know" if that's the case.
> > >
> > > But I'd like a better idea of how much to worry: is ACCESS_ONCE
> > > demonstrably needed today, or rather future-proofing and documentation?
> >
> > Both. If you are coding "while (foo)" where "foo" can be changed by an
> > interrupt handler, you had better instead write "while (ACCESS_ONCE(foo))"
> > or something similar, because most compilers are happy to optimize your
> > loop into an infinite loop in that case. There are places in the Linux
> > kernel that would have problems if the compiler decided to refetch a
> > value -- if a pointer was changed in the meantime, part of your code
> > might be working on the old structure, and part on the new structure.
> > This really can happen today, and this is why rcu_dereference() contains
> > an ACCESS_ONCE().
> >
> > If you are making lockless non-atomic access to a variable, I strongly
> > suggest ACCESS_ONCE() or something similar even if you cannot see how
> > the compiler can mess you up, especially in cases involving a lot of
> > inline functions. In this case, the compiler can be looking at quite
> > a bit of code and optimizing across the entire mess.
>
> Thank you for your fuller reply, Paul: I should be able to hold that
> i386 register pressure example in mind in future (not, of course,
> that it would be limited to i386 at all).
Good point -- given a large enough pile of inline functions, the
compiler might want to use a surprisingly large number of registers.
> > /me wonders what he stepped into with this email thread. ;-)
> >
> > Thanx, Paul
>
> Come on, it wasn't that painful, was it?
> Just a quick extraction of info ;-)
It didn't hurt a bit, and it was over before I knew it. ;-)
Thanx, Paul
> Thanks,
> Hugh
>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
WARNING: multiple messages have this Message-ID (diff)
From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
To: Hugh Dickins <hughd@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Rik van Riel <riel@redhat.com>,
Andrew Morton <akpm@linux-foundation.org>,
Nick Piggin <npiggin@kernel.dk>,
Andrea Arcangeli <aarcange@redhat.com>,
linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
linux-mm@kvack.org
Subject: Re: [RFC] page-table walkers vs memory order
Date: Wed, 25 Jul 2012 15:37:13 -0700 [thread overview]
Message-ID: <20120725223713.GV2378@linux.vnet.ibm.com> (raw)
Message-ID: <20120725223713.Q5Si5vwGJQsG8OlPtX69nD-CvQ0NpCa8OL6vhBdCLXM@z> (raw)
In-Reply-To: <alpine.LSU.2.00.1207251452160.2084@eggly.anvils>
On Wed, Jul 25, 2012 at 03:09:48PM -0700, Hugh Dickins wrote:
> On Wed, 25 Jul 2012, Paul E. McKenney wrote:
> > On Wed, Jul 25, 2012 at 01:26:43PM -0700, Hugh Dickins wrote:
> > > On Wed, 25 Jul 2012, Paul E. McKenney wrote:
> > > > On Tue, Jul 24, 2012 at 02:51:05PM -0700, Hugh Dickins wrote:
> > > > >
> > > > > I'm totally unclear whether the kernel ever gets built with these
> > > > > 'creative' compilers that you refer to. Is ACCESS_ONCE() a warning
> > > > > of where some future compiler would be permitted to mess with our
> > > > > assumptions? Or is it actually saving us already today? Would we
> > > > > know? Could there be a boottime test that would tell us? Is it
> > > > > likely that a future compiler would have an "--access_once"
> > > > > option that the kernel build would want to turn on?
> > > >
> > > > The problem is that, unless you tell it otherwise, the compiler is
> > > > permitted to assume that the code that it is generating is the only thing
> > > > active in that address space at that time. So the compiler might know
> > > > that it already has a perfectly good copy of that value somewhere in
> > > > its registers, or it might decide to fetch the value twice rather than
> > > > once due to register pressure, either of which can be fatal in SMP code.
> > > > And then there are more aggressive optimizations as well.
> > > >
> > > > ACCESS_ONCE() is a way of telling the compiler to access the value
> > > > once, regardless of what cute single-threaded optimizations that it
> > > > otherwise might want to apply.
> > >
> > > Right, but you say "might": I have never heard it asserted, that we do
> > > build the kernel with a compiler which actually makes such optimizations.
> >
> > The compiler we use today can and has hurt us with double-fetching
> > and old-value-reuse optimizations. There have been several that have
> > "optimized" things like "while (foo)" into "tmp = foo; while (tmp)"
> > in the Linux kernel, which have been dealt with by recoding.
>
> Ah yes, those: I think we need ACCESS_EVERY_TIME() for those ones ;)
;-) ;-) ;-)
> I consider the double-fetching ones more insidious,
> less obviously in need of the volatile cast.
Agreed!
> > You might argue that the compiler cannot reasonably apply such an
> > optimization in some given case, but the compiler does much more detailed
> > analysis of the code than most people are willing to do (certainly more
> > than I am usually willing to do!), so I believe that a little paranoia is
> > quite worthwhile.
> >
> > > There's a lot of other surprising things which a compiler is permitted
> > > to do, but we would simply not use such a compiler to build the kernel.
> >
> > Unless we get the gcc folks to build and boot the Linux kernel as part
> > of their test suite (maybe they already do, but not that I know of),
> > how would either they or we know that they had deployed a destructive
> > optimization?
>
> We find out after it hits us, and someone studies the disassembly -
> if we're lucky enough to crash near the origin of the problem.
Color me unreassured. ;-)
> > > Does some version of gcc, under the options which we insist upon,
> > > make such optimizations on any of the architectures which we support?
> >
> > Pretty much any production-quality compiler will do double-fetch
> > and old-value-reuse optimizations, the former especially on 32-bit
> > x86.
>
> That makes good sense, yes: so, under register pressure, they may
> refetch from global memory, instead of using a temporary on local stack.
>
> > I don't know of any production-quality compilers that do value
> > speculation, which would make the compiler act like DEC Alpha hardware,
> > and I would hope that if this does appear, (1) we would have warning
> > and (2) it could be turned off. But there has been a lot of work on
> > this topic, so we would be foolish to rule it out.
>
> I think you're justified in expecting both (1) and (2) there.
Here is hoping!
> > But the currently deployed optimizations can already cause enough trouble.
> >
> > > Or is there some other compiler in use on the kernel, which makes
> > > such optimizations? It seems a long time since I heard of building
> > > the kernel with icc. clang?
> > >
> > > I don't mind the answer "Yes, you idiot" - preferably with an example
> > > or two of which compiler and which piece of code it has bitten us on.
> > > I don't mind the answer "We just don't know" if that's the case.
> > >
> > > But I'd like a better idea of how much to worry: is ACCESS_ONCE
> > > demonstrably needed today, or rather future-proofing and documentation?
> >
> > Both. If you are coding "while (foo)" where "foo" can be changed by an
> > interrupt handler, you had better instead write "while (ACCESS_ONCE(foo))"
> > or something similar, because most compilers are happy to optimize your
> > loop into an infinite loop in that case. There are places in the Linux
> > kernel that would have problems if the compiler decided to refetch a
> > value -- if a pointer was changed in the meantime, part of your code
> > might be working on the old structure, and part on the new structure.
> > This really can happen today, and this is why rcu_dereference() contains
> > an ACCESS_ONCE().
> >
> > If you are making lockless non-atomic access to a variable, I strongly
> > suggest ACCESS_ONCE() or something similar even if you cannot see how
> > the compiler can mess you up, especially in cases involving a lot of
> > inline functions. In this case, the compiler can be looking at quite
> > a bit of code and optimizing across the entire mess.
>
> Thank you for your fuller reply, Paul: I should be able to hold that
> i386 register pressure example in mind in future (not, of course,
> that it would be limited to i386 at all).
Good point -- given a large enough pile of inline functions, the
compiler might want to use a surprisingly large number of registers.
> > /me wonders what he stepped into with this email thread. ;-)
> >
> > Thanx, Paul
>
> Come on, it wasn't that painful, was it?
> Just a quick extraction of info ;-)
It didn't hurt a bit, and it was over before I knew it. ;-)
Thanx, Paul
> Thanks,
> Hugh
>
next prev parent reply other threads:[~2012-07-25 22:37 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-23 17:34 [RFC] page-table walkers vs memory order Peter Zijlstra
2012-07-23 17:34 ` Peter Zijlstra
2012-07-23 19:27 ` Paul E. McKenney
2012-07-23 19:27 ` Paul E. McKenney
2012-07-24 21:51 ` Hugh Dickins
2012-07-24 21:51 ` Hugh Dickins
2012-07-25 17:56 ` Paul E. McKenney
2012-07-25 17:56 ` Paul E. McKenney
2012-07-25 20:26 ` Hugh Dickins
2012-07-25 20:26 ` Hugh Dickins
2012-07-25 21:12 ` Paul E. McKenney
2012-07-25 21:12 ` Paul E. McKenney
2012-07-25 22:09 ` Hugh Dickins
2012-07-25 22:09 ` Hugh Dickins
2012-07-25 22:37 ` Paul E. McKenney [this message]
2012-07-25 22:37 ` Paul E. McKenney
2012-07-26 8:11 ` Peter Zijlstra
2012-07-26 8:11 ` Peter Zijlstra
2012-07-30 19:21 ` Jamie Lokier
2012-07-30 19:21 ` Jamie Lokier
2012-07-30 20:28 ` Paul E. McKenney
2012-07-30 20:28 ` Paul E. McKenney
2012-07-26 20:39 ` Peter Zijlstra
2012-07-26 20:39 ` Peter Zijlstra
2012-07-27 19:22 ` Hugh Dickins
2012-07-27 19:22 ` Hugh Dickins
2012-07-27 19:39 ` Paul E. McKenney
2012-07-27 19:39 ` Paul E. McKenney
2012-08-04 14:37 ` Andrea Arcangeli
2012-08-04 14:37 ` Andrea Arcangeli
2012-08-04 22:02 ` Paul E. McKenney
2012-08-04 22:02 ` Paul E. McKenney
2012-08-04 22:47 ` Andrea Arcangeli
2012-08-04 22:47 ` Andrea Arcangeli
2012-08-04 22:59 ` Dr. David Alan Gilbert
2012-08-04 22:59 ` Dr. David Alan Gilbert
2012-08-04 23:11 ` Paul E. McKenney
2012-08-04 23:11 ` Paul E. McKenney
2012-08-05 0:10 ` Dr. David Alan Gilbert
2012-08-05 0:10 ` Dr. David Alan Gilbert
2012-08-04 23:06 ` Paul E. McKenney
2012-08-04 23:06 ` Paul E. McKenney
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120725223713.GV2378@linux.vnet.ibm.com \
--to=paulmck@linux.vnet.ibm.com \
--cc=aarcange@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=hughd@google.com \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=npiggin@kernel.dk \
--cc=peterz@infradead.org \
--cc=riel@redhat.com \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.