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: 33+ 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-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 21:12 ` Paul E. McKenney 2012-07-25 21:12 ` Paul E. McKenney 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-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: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: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-05 0:10 ` Dr. David Alan Gilbert 2012-08-05 0:10 ` Dr. David Alan Gilbert 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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).