From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
To: Will Deacon <will.deacon@arm.com>
Cc: linux-kernel@vger.kernel.org,
Catalin Marinas <Catalin.Marinas@arm.com>,
Peter Zijlstra <peterz@infradead.org>,
lttng-dev@lists.lttng.org, Nathan Lynch <Nathan_Lynch@mentor.com>,
"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
Linus Torvalds <torvalds@linux-foundation.org>,
Andrew Morton <akpm@linux-foundation.org>
Subject: Re: current_thread_info() not respecting program order with gcc 4.8.x
Date: Tue, 19 Nov 2013 17:02:20 +0000 (UTC) [thread overview]
Message-ID: <1656507422.70913.1384880540574.JavaMail.zimbra@efficios.com> (raw)
In-Reply-To: <20131119160502.GG11778@mudshark.cambridge.arm.com>
----- Original Message -----
> From: "Will Deacon" <will.deacon@arm.com>
> To: "Mathieu Desnoyers" <mathieu.desnoyers@efficios.com>
> Cc: linux-kernel@vger.kernel.org, "Catalin Marinas" <Catalin.Marinas@arm.com>, "Peter Zijlstra"
> <peterz@infradead.org>, lttng-dev@lists.lttng.org, "Nathan Lynch" <Nathan_Lynch@mentor.com>, "Paul E. McKenney"
> <paulmck@linux.vnet.ibm.com>, "Linus Torvalds" <torvalds@linux-foundation.org>, "Andrew Morton"
> <akpm@linux-foundation.org>
> Sent: Tuesday, November 19, 2013 11:05:02 AM
> Subject: Re: current_thread_info() not respecting program order with gcc 4.8.x
>
> On Tue, Nov 19, 2013 at 03:29:12PM +0000, Mathieu Desnoyers wrote:
> > Hi,
>
> Hi Mathieu,
Hi Will,
>
> > I got a bug report on ARM which appears to be caused by an aggressive gcc
> > optimisation starting from gcc 4.8.x due to lack of constraints on the
> > current_thread_info() inline assembly. The only logical explanation for
> > his issue I see so far is that read of the preempt_count within
> > might_sleep() is reordered with preempt_enable() or preempt_disable().
> > AFAIU, this kind of issue also applies to other architectures.
> >
> > First thing, preempt enable/disable only contains barrier() between the
> > inc/dec and the inside of the critical section, not the outside.
> > Therefore, we are relying on program order to ensure that the
> > preempt_count() read in might_sleep() is not reordered with the preempt
> > count inc/dec.
>
> This sounds almost identical to an issue I experienced with our optimised
> per-cpu code (more below).
>
> > However, looking at ARM arch/arm/include/asm/thread_info.h:
> >
> > static inline struct thread_info *current_thread_info(void)
> > {
> > register unsigned long sp asm ("sp");
> > return (struct thread_info *)(sp & ~(THREAD_SIZE - 1));
> > }
> >
> > The inline assembly has no clobber and is not volatile. (this is also true
> > for all other architectures I've looked at so far, which includes x86 and
> > powerpc)
> >
> > As long as someone does:
> >
> > struct thread_info *myinfo = current_thread_info();
> >
> > load from myinfo->preempt_count;
> > store to myinfo->preempt_count;
> >
> > The program order should be preserved, because the read and the write are
> > done wrt same base. However, what we have here in the case of
> > might_sleep() followed by preempt_enable() is:
> >
> > load from current_thread_info()->preempt_count;
> > store to current_thread_info()->preempt_count;
> >
> > Since each current_thread_info() is a different asm ("sp") without clobber
> > nor volatile, AFAIU, the compiler is within its right to reorder them.
> >
> > One possible solution to this might be to add "memory" clobber and volatile
> > to this inline asm, but I fear it would put way too much constraints on
> > the compiler optimizations (too heavyweight).
>
> Yup, that sucks, because you end up unable to cache the value when you know
> it hasn't changed.
>
> > Have any of you experienced this issue ? Any thoughts on the matter ?
>
> The way I got around this for the per-cpu code is to include a dummy memory
> constraint for the stack. This has a couple of advantages:
>
> (1) It hazards against a "memory" clobber, so doesn't require use of
> `volatile'
>
> (2) It doesn't require GCC to emit any address generation code,
> since dereferencing the sp is valid in ARM assembly
>
> so adding something like:
>
> asm("" :: "Q" (*sp));
>
> immediately after the declaration of sp in current_therad_info might do the
> trick. Do you have a way to test that?
Unfortunately I don't have a ARM cross-compiler setup ready. Nathan could test
it for us though.
It might shuffle things around enough to work around the issue, but with the
approach you propose, I would be concerned about the compiler being within
its rights to reorder the code into the following sequence:
struct thread_info *ptra, *ptrb;
ptra = current_thread_info();
/*
* each current_thread_info() would have a clobber on *sp, which orders
* those two wrt each other.
*/
ptrb = current_thread_info();
load from ptra->preempt_count;
/*
* however, the following accesses that depend on ptra and ptrb could be
* reordered if the compiler has no way to know that ptra and ptrb are
* aliased.
*/
store to ptrb->preempt_count;
One question that might be worth asking: with the local register variable
extension (http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Local-Reg-Vars.html#Local-Reg-Vars)
(thanks to Jakub for the pointer), should the compiler consider two variables
bound to the same register as being aliased or not ? AFAIU, local reg vars appear
to be architecture-specific, so maybe there is something fishy on ARM ?
Thanks,
Mathieu
>
> Cheers,
>
> Will
>
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
next prev parent reply other threads:[~2013-11-19 17:02 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <52803E5D.3050109@mentor.com>
2013-11-11 15:47 ` might_sleep warnings in overwrite mode Nathan Lynch
2013-11-14 18:16 ` Nathan Lynch
[not found] ` <52851395.3010306@mentor.com>
2013-11-15 2:34 ` Mathieu Desnoyers
[not found] ` <67652521.68027.1384482849638.JavaMail.zimbra@efficios.com>
2013-11-18 19:30 ` Nathan Lynch
2013-11-19 15:29 ` current_thread_info() not respecting program order with gcc 4.8.x Mathieu Desnoyers
2013-11-19 15:57 ` Peter Zijlstra
2013-11-19 16:13 ` Jakub Jelinek
2013-11-19 16:21 ` Peter Zijlstra
2013-11-19 16:05 ` Will Deacon
2013-11-19 17:02 ` Mathieu Desnoyers [this message]
2013-11-19 17:33 ` Peter Zijlstra
2013-11-19 21:56 ` Multiple local register variables w/ same register Richard Henderson
2013-11-19 22:08 ` Jakub Jelinek
2013-11-19 22:13 ` Måns Rullgård
2013-11-19 22:13 ` Måns Rullgård
2013-11-19 22:25 ` Mathieu Desnoyers
2013-11-19 22:34 ` [lttng-dev] " Mathieu Desnoyers
2013-11-20 0:41 ` current_thread_info() not respecting program order with gcc 4.8.x Linus Torvalds
2013-11-20 15:10 ` Mathieu Desnoyers
2013-11-21 16:02 ` Alexander Holler
2013-11-21 22:12 ` Luis Lozano
2013-11-21 22:12 ` Luis Lozano
2013-11-21 22:32 ` Linus Torvalds
2013-11-21 23:03 ` Bhaskar Janakiraman
2013-11-21 23:18 ` Alexander Holler
2013-11-21 23:45 ` Luis Lozano
2013-11-22 0:39 ` Jakub Jelinek
2013-11-22 1:57 ` Mathieu Desnoyers
2013-11-22 2:36 ` Luis Lozano
2013-11-22 3:38 ` Mathieu Desnoyers
2013-11-22 8:16 ` Luis Lozano
2013-11-22 8:18 ` Luis Lozano
2013-11-22 8:33 ` Luis Lozano
2013-11-22 13:06 ` Mathieu Desnoyers
2013-11-22 20:33 ` [lttng-dev] " Mathieu Desnoyers
[not found] ` <CANxoKduwK=9__0WFXFcTWjQn3Rbn+HgSWZyL0FN_VuJ2Q_2TPQ@mail.gmail.com>
2013-11-22 13:02 ` Mathieu Desnoyers
2013-11-22 0:17 ` Linus Torvalds
2013-11-22 0:34 ` Alexander Holler
2013-11-21 1:52 Luis Lozano
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=1656507422.70913.1384880540574.JavaMail.zimbra@efficios.com \
--to=mathieu.desnoyers@efficios.com \
--cc=Catalin.Marinas@arm.com \
--cc=Nathan_Lynch@mentor.com \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lttng-dev@lists.lttng.org \
--cc=paulmck@linux.vnet.ibm.com \
--cc=peterz@infradead.org \
--cc=torvalds@linux-foundation.org \
--cc=will.deacon@arm.com \
/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.