From: Linus Torvalds <torvalds@linux-foundation.org>
To: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>,
"Rafael J. Wysocki" <rjw@sisk.pl>,
LKML <linux-kernel@vger.kernel.org>, Ingo Molnar <mingo@elte.hu>,
Andrew Morton <akpm@linux-foundation.org>,
linux-ext4@vger.kernel.org
Subject: Re: 2.6.25-git2: BUG: unable to handle kernel paging request at ffffffffffffffff
Date: Mon, 21 Apr 2008 08:49:58 -0700 (PDT) [thread overview]
Message-ID: <alpine.LFD.1.10.0804210810180.2779@woody.linux-foundation.org> (raw)
In-Reply-To: <20080421020806.GL20138@linux.vnet.ibm.com>
On Sun, 20 Apr 2008, Paul E. McKenney wrote:
> >
> > But I do concede that your version looks clearer, and has the
> > benefit that should prefetch ever be optimised out with no side-
> > effects, yours would still be correct while the current one will
> > lose the barrier completely.
>
> Agreed as well -- compilers would also be within their right to bypass
> the rcu_dereference() around the test/prefetch, which would allow
> them to refetch.
That is *not* the main problem.
If you use "rcu_dereference()" on the wrong access, it not only loses the
"smp_read_barrier_depends()" (which is a no-op on all sane architectures
anyway), but it loses the ACCESS_ONCE() thing *entirely*.
Accessign a local automatic variable through a volatile pointer has
absolutely no effect - it's a total no-op apart from possibly generating
slightly worse code (although if I were a compiler, I'd just ignore it),
since the compiler is totally free to spill and reload the local variable
to its memory location - the stack - anyway!
So the important part (for sane architectures) of rcu_dereference() is
that ACCESS_ONCE() hack, and it _only_ works if you actually do it on the
value as it gets loaded from the RCU-protected data structure, not later.
So forget about the prefetch, and forget about the barrier. They had
nothing to do with the bug. The bug existed even without the prefetch,
even in the versions that didn't have it at all. For example, look at the
"__list_for_each_rcu()" thing - the bug is there too, because it did just
pos = (head)->next ... pos = pos->next
where both of those assignments to pos were done without rcu_derefence, so
the compiler could happily decide to use the value once, forget it, and
then re-load it later (when it might have changed).
In other words, the thing I objected to was something much more
fundamental than any barriers. It was the fact that "rcu_dereference()"
simply *fundamentally* doesn't make sense when done on a local variable,
it can only make sense when actually loading the value from the data
structure.
In short:
pos = ..
rcu_dereference(pos)
is crazy and senseless, but
pos = rcu_dereference(pos->next)
actually has some logical meaning.
Now, all this said, I seriously doubt this was the source of the bug
itself. I do not actually really believe that the compiler had much room
for reloading things with or without any rcu_dereference(), and I doubt
the code generation really changes all that much in practice.
(In fact, from a quick look, it seems that the only thing that
the incorrect use of "rcu_derference()" did was to force the "node"
variable onto the stack, since it did that volatime memory access through
its pointer - and fixing the use of rcu_dereference() just means that
"node" is kept in a register over the whole loop on x86-64, but the
compiler still needs a stack slot, it just picks "str" instead. Which is a
much better choice anyway.
So what the incorrect use of rcu_dereference() really resulted in was just
this insane code (which is also seen in the BUG code):
14: 48 8b 45 d0 mov -0x30(%rbp),%rax
18: 48 8b 00 mov (%rax),%rax
1b: 48 89 45 d0 mov %rax,-0x30(%rbp)
1f: 48 8b 45 d0 mov -0x30(%rbp),%rax
23: 48 85 c0 test %rax,%rax
26: 74 18 je 0x40
and notice how insane that is, and how pointless?
First it loads %rax (node) from the ->next pointer of the previous value
of 'node' (which is a stack variable at -48(rbp)):
# node = node->next
mov -0x30(%rbp),%rax
mov (%rax),%rax
then it saves that to the stack and immediately reloads it (because of the
volatile access on "pos" in "rcu_dereference(pos)"):
# rcu_dereference(node)
mov %rax,-0x30(%rbp)
mov -0x30(%rbp),%rax
and then it tests it for being NULL:
test %rax,%rax
je 0x40
and notice how the only thing that rcu_dereference() did was a totally
unnecessary store and load to the stack? But also notice how gcc could
have done the accesses to "node" *before* this entry as multiple loads
from the original because there was nothing really holding this back.
(But also notice how there really isn't much room for that in practice,
since the code that actually uses "node->next" isn't going to do a whole
lot of exciting stuff with it).
With the corrected version, the insane "store and immediately reload from
stack" goes away" and diffstat on the assembly language actually shows
that there are two less instructions (most of the changes are just
compiler labels moving around, but there are a few real changes that
actually makes the assembler code look a bit more natural too).
So to recap: I don't think this mattered in practice. But the code was
buggy in theory, even though in practice I don't think it would ever
generate any reloads on that "next" variable simply because nothing else
than the loop logic really used it.
Linus
next prev parent reply other threads:[~2008-04-21 15:57 UTC|newest]
Thread overview: 183+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-19 13:22 2.6.25-git1: Solid hang on HP nx6325 (64-bit) Rafael J. Wysocki
2008-04-20 19:04 ` 2.6.25-git2: BUG: unable to handle kernel paging request at ffffffffffffffff Rafael J. Wysocki
2008-04-20 19:14 ` Rafael J. Wysocki
2008-04-20 21:31 ` Linus Torvalds
2008-04-21 1:18 ` Herbert Xu
2008-04-21 2:08 ` Paul E. McKenney
2008-04-21 4:59 ` Paul E. McKenney
2008-04-21 5:47 ` Paul E. McKenney
2008-04-21 13:00 ` Ingo Molnar
2008-04-21 16:06 ` Linus Torvalds
2008-04-21 16:24 ` Rafael J. Wysocki
2008-04-21 15:49 ` Linus Torvalds [this message]
2008-04-21 17:05 ` Paul E. McKenney
2008-04-21 17:30 ` Linus Torvalds
2008-04-21 17:43 ` Paul E. McKenney
2008-04-22 1:03 ` Herbert Xu
2008-04-22 13:36 ` Paul E. McKenney
2008-04-21 16:12 ` Rafael J. Wysocki
2008-04-21 16:54 ` Linus Torvalds
2008-04-21 17:06 ` Jiri Slaby
2008-04-21 17:19 ` Rafael J. Wysocki
2008-04-21 17:48 ` Linus Torvalds
2008-04-21 18:22 ` Rafael J. Wysocki
2008-04-21 19:38 ` Jiri Slaby
2008-04-21 20:39 ` David Miller
2008-04-21 21:18 ` Jiri Slaby
2008-04-21 21:58 ` Jiri Slaby
2008-04-21 22:26 ` Jiri Slaby
2008-04-21 22:54 ` Paul E. McKenney
2008-04-21 23:02 ` Jiri Slaby
2008-04-21 23:11 ` Zdenek Kabelac
2008-04-21 23:17 ` Jiri Slaby
2008-04-22 0:54 ` Rafael J. Wysocki
2008-04-22 1:14 ` Linus Torvalds
2008-04-22 1:30 ` Rafael J. Wysocki
2008-04-22 9:49 ` Jiri Slaby
2008-04-22 9:53 ` Ingo Molnar
2008-04-22 18:35 ` Zdenek Kabelac
2008-04-22 18:48 ` Linus Torvalds
2008-04-22 20:34 ` device_pm_add (was: Re: 2.6.25-git2: BUG: unable to handle kernel paging request at ffffffffffffffff) Rafael J. Wysocki
2008-04-22 20:57 ` Rafael J. Wysocki
2008-04-22 22:11 ` Greg KH
2008-04-22 20:58 ` Linus Torvalds
2008-04-22 22:12 ` Greg KH
2008-04-22 22:48 ` Rafael J. Wysocki
2008-04-23 0:50 ` Rafael J. Wysocki
2008-04-23 14:56 ` Alan Stern
2008-04-23 8:50 ` 2.6.25-git2: BUG: unable to handle kernel paging request at ffffffffffffffff Zdenek Kabelac
2008-04-23 15:53 ` Linus Torvalds
2008-04-23 16:58 ` Pekka Enberg
2008-04-23 17:28 ` Zdenek Kabelac
2008-04-23 17:40 ` Ingo Molnar
2008-04-23 18:52 ` Pekka Enberg
2008-04-23 19:05 ` Christoph Lameter
2008-04-23 19:19 ` Pekka J Enberg
2008-04-23 19:28 ` Christoph Lameter
2008-04-23 20:27 ` Zdenek Kabelac
2008-04-24 22:26 ` Jiri Slaby
2008-04-24 22:41 ` Linus Torvalds
2008-04-25 0:57 ` Jiri Slaby
2008-04-24 23:45 ` Linus Torvalds
2008-04-25 7:36 ` Jiri Slaby
2008-04-25 14:09 ` Pavel Machek
2008-04-25 15:30 ` Rafael J. Wysocki
2008-04-25 17:10 ` Jiri Slaby
2008-04-25 9:13 ` David Miller
2008-04-25 12:15 ` Zdenek Kabelac
2008-04-25 12:27 ` Zdenek Kabelac
2008-04-28 0:51 ` [PATCH 1/1] x86: fix text_poke Jiri Slaby
2008-04-25 15:03 ` Linus Torvalds
2008-04-25 15:17 ` Andi Kleen
2008-04-25 19:36 ` Christoph Lameter
2008-04-26 9:59 ` Andi Kleen
2008-04-26 11:16 ` Jiri Slaby
2008-04-26 11:34 ` Andi Kleen
2008-04-28 20:24 ` VIRTUAL_BUG_ON() Christoph Lameter
2008-05-01 19:22 ` [RFC 1/1] mm: add virt to phys debug Jiri Slaby
2008-05-01 20:18 ` Christoph Lameter
2008-05-06 21:54 ` Jiri Slaby
2008-05-07 17:30 ` Christoph Lameter
2008-05-13 14:38 ` Jiri Slaby
2008-04-25 15:19 ` [PATCH 1/1] x86: fix text_poke Ingo Molnar
2008-04-25 15:26 ` Ingo Molnar
2008-04-25 15:32 ` Ingo Molnar
2008-04-25 15:33 ` Linus Torvalds
2008-04-25 15:48 ` Andi Kleen
2008-04-25 16:06 ` Linus Torvalds
2008-04-25 16:19 ` Andi Kleen
2008-04-25 16:24 ` Linus Torvalds
2008-04-25 16:33 ` Ingo Molnar
2008-04-25 18:13 ` Jeremy Fitzhardinge
2008-05-05 2:36 ` Nick Piggin
2008-04-25 16:30 ` Mathieu Desnoyers
2008-04-25 16:42 ` H. Peter Anvin
2008-04-25 17:09 ` Mathieu Desnoyers
2008-04-25 18:37 ` Mathieu Desnoyers
2008-04-25 18:47 ` H. Peter Anvin
2008-04-25 19:19 ` H. Peter Anvin
2008-04-25 20:04 ` Mathieu Desnoyers
2008-04-25 20:09 ` H. Peter Anvin
2008-04-25 20:18 ` H. Peter Anvin
2008-04-25 20:37 ` Mathieu Desnoyers
2008-04-25 20:41 ` H. Peter Anvin
2008-04-25 20:51 ` Linus Torvalds
2008-04-25 21:12 ` Mathieu Desnoyers
2008-04-25 21:15 ` H. Peter Anvin
2008-04-25 21:47 ` Mathieu Desnoyers
2008-04-25 22:07 ` H. Peter Anvin
2008-04-25 22:30 ` Mathieu Desnoyers
2008-04-25 22:36 ` Linus Torvalds
2008-04-28 20:21 ` Ingo Molnar
2008-04-28 20:55 ` Jeremy Fitzhardinge
2008-04-28 21:01 ` H. Peter Anvin
2008-04-28 22:42 ` Mathieu Desnoyers
2008-04-28 20:43 ` Mathieu Desnoyers
2008-04-28 21:02 ` Jeremy Fitzhardinge
2008-05-04 15:03 ` Mathieu Desnoyers
2008-05-04 16:18 ` H. Peter Anvin
2008-04-25 22:38 ` H. Peter Anvin
2008-04-25 22:04 ` Linus Torvalds
2008-04-25 23:00 ` Mathieu Desnoyers
2008-04-25 23:13 ` Jeremy Fitzhardinge
2008-04-25 23:34 ` Masami Hiramatsu
2008-04-26 6:21 ` Jeremy Fitzhardinge
2008-04-26 11:56 ` Arnaldo Carvalho de Melo
2008-04-26 23:38 ` Jeremy Fitzhardinge
2008-04-27 1:00 ` Arnaldo Carvalho de Melo
2008-04-26 2:12 ` Frank Ch. Eigler
2008-06-05 17:44 ` Frank Ch. Eigler
2008-04-26 6:50 ` Jeremy Fitzhardinge
2008-04-28 0:49 ` Masami Hiramatsu
2008-04-25 21:02 ` David Miller
2008-04-25 21:11 ` H. Peter Anvin
2008-04-25 16:22 ` Ingo Molnar
2008-04-25 16:37 ` Linus Torvalds
2008-04-25 16:43 ` Ingo Molnar
2008-04-25 16:45 ` Ingo Molnar
2008-04-25 16:51 ` Linus Torvalds
2008-04-25 17:02 ` Ingo Molnar
2008-04-25 17:13 ` Linus Torvalds
2008-04-25 17:26 ` Andi Kleen
2008-04-25 17:29 ` Linus Torvalds
2008-04-25 17:53 ` Ingo Molnar
2008-04-25 18:04 ` Ingo Molnar
2008-04-25 18:09 ` Linus Torvalds
2008-04-25 18:19 ` Ingo Molnar
2008-04-25 18:56 ` Ingo Molnar
2008-04-25 18:13 ` Ingo Molnar
2008-04-25 16:52 ` Ingo Molnar
2008-04-25 16:56 ` Andi Kleen
2008-04-25 15:50 ` Ingo Molnar
2008-04-25 15:57 ` H. Peter Anvin
2008-04-25 18:53 ` Pavel Machek
2008-04-25 16:11 ` Linus Torvalds
2008-04-25 15:54 ` Mathieu Desnoyers
2008-04-25 15:59 ` Ingo Molnar
2008-04-25 16:11 ` Mathieu Desnoyers
2008-04-25 15:27 ` Andi Kleen
2008-04-25 20:18 ` David Miller
2008-04-25 1:35 ` 2.6.25-git2: BUG: unable to handle kernel paging request at ffffffffffffffff David Miller
2008-04-25 1:48 ` Linus Torvalds
2008-04-25 1:57 ` David Miller
2008-04-25 7:41 ` Jiri Slaby
2008-04-25 7:45 ` David Miller
2008-04-25 8:02 ` Jiri Slaby
2008-04-25 8:18 ` pci commands resume order [Was: 2.6.25-git2: BUG: unable to handle kernel paging request at ffffffffffffffff] Jiri Slaby
2008-04-25 17:11 ` Jesse Barnes
2008-04-25 10:53 ` 2.6.25-git2: BUG: unable to handle kernel paging request at ffffffffffffffff Craig Schlenter
2008-04-25 7:42 ` Jiri Slaby
2008-04-25 7:49 ` David Miller
2008-04-25 7:56 ` Jiri Slaby
2008-04-25 7:58 ` David Miller
2008-04-25 8:00 ` Jiri Slaby
2008-04-25 15:47 ` Randy Dunlap
2008-04-22 21:46 ` Rafael J. Wysocki
2008-04-22 19:09 ` Ingo Molnar
2008-04-22 1:15 ` Rafael J. Wysocki
2008-04-22 1:25 ` [ProbableSpam]Re: " Paul E. McKenney
2008-04-21 21:19 ` Linus Torvalds
2008-04-21 21:54 ` David Miller
2008-04-21 13:17 ` Ingo Molnar
2008-04-21 13:35 ` Rafael J. Wysocki
2008-04-21 18:56 ` Ingo Molnar
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=alpine.LFD.1.10.0804210810180.2779@woody.linux-foundation.org \
--to=torvalds@linux-foundation.org \
--cc=akpm@linux-foundation.org \
--cc=herbert@gondor.apana.org.au \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=paulmck@linux.vnet.ibm.com \
--cc=rjw@sisk.pl \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®