From: Denys Vlasenko <dvlasenk@redhat.com>
To: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>,
Ingo Molnar <mingo@kernel.org>, Thomas Graf <tgraf@suug.ch>,
Peter Zijlstra <peterz@infradead.org>,
David Rientjes <rientjes@google.com>,
Andrew Morton <akpm@linux-foundation.org>,
linux-kernel@vger.kernel.org, Arnd Bergmann <arnd@arndb.de>,
linux-scsi <linux-scsi@vger.kernel.org>
Subject: Re: This patch triggers a bad gcc bug (was Re: [PATCH] force inlining of some byteswap operations)
Date: Thu, 14 Apr 2016 19:09:11 +0200 [thread overview]
Message-ID: <570FCEB7.1070200@redhat.com> (raw)
In-Reply-To: <20160414155708.upka6phfvwpbp6zw@treble>
On 04/14/2016 05:57 PM, Josh Poimboeuf wrote:
> On Thu, Apr 14, 2016 at 05:29:06PM +0200, Denys Vlasenko wrote:
>> On 04/13/2016 07:10 PM, Josh Poimboeuf wrote:
>>>>>>>> From the disassembly of drivers/scsi/qla2xxx/qla_attr.o:
>>>>>>>>
>>>>>>>> 0000000000002f53 <qla2x00_get_host_fabric_name>:
>>>>>>>> 2f53: 55 push %rbp
>>>>>>>> 2f54: 48 89 e5 mov %rsp,%rbp
>>>>>>>>
>>>>>>>> 0000000000002f57 <qla2x00_get_fc_host_stats>:
>>>>>>>> 2f57: 55 push %rbp
>>>>>>>> 2f58: b9 e8 00 00 00 mov $0xe8,%ecx
>>>>>>>> 2f5d: 48 89 e5 mov %rsp,%rbp
>>>>>>>> ...
>>>>>>>>
>>>>>>>> Note that qla2x00_get_host_fabric_name() is inexplicably
>>>>>>>> truncated after
>>>>>>>> setting up the frame pointer. It falls through to the next
>>>>>>>> function, which is
>>>>>>>> very wrong.
>>>>>>>
>>>>>>> Wow, that's ... interesting.
>>>>>>>
>>>>>>>
>>>>>>>> I can recreate it with either gcc 5.3.1 or gcc 6.0 on
>>>>>>>> linus/master with
>>>>>>>> the .config from the above link.
>>>>>>>>
>>>>>>>> The call chain which appears to trigger the problem is:
>>>>>>>>
>>>>>>>> qla2x00_get_host_fabric_name()
>>>>>>>> wwn_to_u64()
>>>>>>>> get_unaligned_be64()
>>>>>>>> be64_to_cpup()
>>>>>>>> __be64_to_cpup() <- changed to __always_inline by this
>>>>>>>> patch
>>>>>>>>
>>>>>>>> It occurs with the combination of the following two recent
>>>>>>>> commits:
>>>>>>>>
>>>>>>>> - bc27fb68aaad ("include/uapi/linux/byteorder, swab: force
>>>>>>>> inlining of some byteswap operations")
>>>>>>>> - ef3fb2422ffe ("scsi: fc: use get/put_unaligned64 for wwn
>>>>>>>> access")
>>>>>>>>
>>>>>>>> I can confirm that reverting either patch makes the problem go
>>>>>>>> away.
>>>>>>>> I'm planning on opening a gcc bug tomorrow.
>>>>>>>
>>>>>>>
>>>>>>> Note that if CONFIG_OPTIMIZE_INLINING is not set, _all_ "inline"
>>>>>>> keywords are in fact __always_inline, so the bug must be
>>>>>>> triggering
>>>>>>> even without the patch.
>>>>>>
>>>>>> Makes sense in theory, but the bug doesn't actually trigger when I
>>>>>> revert the patch and set CONFIG_OPTIMIZE_INLINING=n.
>>>>>>
>>>>>> Perhaps even more surprising, it doesn't trigger *with* the patch
>>>>>> and
>>>>>> CONFIG_OPTIMIZE_INLINING=n.
>>>>>
>>>>> [ Adding James to CC since this bug affects scsi. ]
>>>>>
>>>>> Here's the gcc bug:
>>>>>
>>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70646
>>>>>
>>>>
>>>>
>>>> Actually, adding me doesn't help, I've added linux-scsi. The summary
>>>> is that there's a but in gcc-5.3.1 which is miscompiling qla_attr.c ...
>>>> this means we're going to have to ask the compiler version of reported
>>>> crashes.
>>>
>>> The bug isn't specific to a compiler version. I've seen it with gcc
>>> 5.3.1 and gcc 6.0. I haven't tried any older versions. And the gcc bug
>>> hasn't been resolved (or even investigated) yet.
>>>
>>> The bug is triggered by a combination of the above two commits from the
>>> 4.6 merge window, so presumably we'd need to revert one of them to avoid
>>> crashes in 4.6.
>>
>> The bug is indeed in the compiler. 4.9 and all later versions are affected.
>> gcc bugzilla now has a reproducer. In abridged form:
>>
>>
>> static inline __attribute__((always_inline)) u64 __swab64p(const u64 *p)
>> {
>> return (__builtin_constant_p((u64)(*p)) ? ((u64)( (((u64)(*p) & (u64)0x00000000000000ffULL) << 56) | (((u64)(*p) & (u64)0x000000000000ff00ULL) << 40) | (((u64)(*p) & (u64)0x0000000000ff0000ULL) << 24) | (((u64)(*p) & (u64)0x00000000ff000000ULL) << 8) | (((u64)(*p) & (u64)0x000000ff00000000ULL) >> 8) | (((u64)(*p) & (u64)0x0000ff0000000000ULL) >> 24) | (((u64)(*p) & (u64)0x00ff000000000000ULL) >> 40) | (((u64)(*p) & (u64)0xff00000000000000ULL) >> 56))) : __builtin_bswap64(*p));
>> }
>> static inline u64 wwn_to_u64(void *wwn)
>> {
>> return __swab64p(wwn);
>> }
>> static void qla2x00_get_host_fabric_name(struct Scsi_Host *shost)
>> {
>> scsi_qla_host_t *vha = shost_priv(shost);
>> u8 node_name[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
>> u64 fabric_name = wwn_to_u64(node_name);
>> if (vha->device_flags & 0x1)
>> fabric_name = wwn_to_u64(vha->fabric_node_name);
>> (((struct fc_host_attrs *)(shost)->shost_data)->fabric_name) = fabric_name;
>> }
>
> Nice work with the reproducer!
>
>> Two (or more, there were more before simplification) levels of inlining
>> are necessary for bug to trigger in this example (folding to one level
>> makes it go away). "__attribute__((always_inline))" is necessary too.
>>
>>
>> Since we have lots of __always_inline anyway, this bug has a potential
>> to miscompile kernels regardless of CONFIG_OPTIMIZE_INLINING setting,
>> and with or without the patches mentioned above (they just happen
>> to create a reliable reproducer).
>
> Well, but setting !CONFIG_OPTIMIZE_INLINING makes the problem go away
> for some reason. It seems like the bug requires wwn_to_u64() being
> out-of-line and __swab64p() being in-line.
By my reading of what gcc gurus are talking there,
gcc has some new-ish machinery for discarding unreachable code.
Akin to not continuing code generation after a call to never-returning
function like exit(), but smarter (it can detect much less obvious
cases when some code path is not possible).
And it has a subtle bug. In this case, it decided that both branches
of ternary op ?: in __swab64p() are impossible, and therefore
__swab64p() is impossible.
(Which is, of course, bogus, that's why it's a bug).
Then this bogus decision was propagated through inlining
and gcc decided that entire qla2x00_get_host_fabric_name()
function is an impossible (unreachable) code path, and...
eliminated it all. Good boy :D
> In fact, the following patch seems to fix it:
>
> diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
> index bf66ea6..56b9e81 100644
> --- a/include/scsi/scsi_transport_fc.h
> +++ b/include/scsi/scsi_transport_fc.h
> @@ -796,7 +796,7 @@ fc_remote_port_chkready(struct fc_rport *rport)
> return result;
> }
>
> -static inline u64 wwn_to_u64(u8 *wwn)
> +static __always_inline u64 wwn_to_u64(u8 *wwn)
> {
> return get_unaligned_be64(wwn);
> }
It is not a guarantee.
next prev parent reply other threads:[~2016-04-14 17:09 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-04 19:45 [PATCH] asm-generic: force inlining of some atomic_long operations Denys Vlasenko
2016-02-04 19:45 ` [PATCH] force inlining of some byteswap operations Denys Vlasenko
2016-02-05 7:28 ` Ingo Molnar
2016-04-13 3:36 ` This patch triggers a bad gcc bug (was Re: [PATCH] force inlining of some byteswap operations) Josh Poimboeuf
2016-04-13 12:12 ` Denys Vlasenko
2016-04-13 12:36 ` Josh Poimboeuf
2016-04-13 15:15 ` Josh Poimboeuf
2016-04-13 16:55 ` James Bottomley
2016-04-13 17:10 ` Josh Poimboeuf
2016-04-14 15:29 ` Denys Vlasenko
2016-04-14 15:57 ` Josh Poimboeuf
2016-04-14 17:09 ` Denys Vlasenko [this message]
2016-04-15 5:45 ` Ingo Molnar
2016-04-15 13:47 ` Josh Poimboeuf
2016-04-15 22:20 ` Josh Poimboeuf
2016-04-16 9:03 ` Ingo Molnar
2016-04-18 13:39 ` Josh Poimboeuf
2016-04-18 14:07 ` Arnd Bergmann
2016-04-18 14:12 ` Josh Poimboeuf
2016-04-18 14:21 ` Arnd Bergmann
2016-04-19 8:52 ` Ingo Molnar
2016-04-19 13:56 ` [PATCH] scsi: fc: force inlining of wwn conversion functions Josh Poimboeuf
2016-04-22 23:17 ` Quinn Tran
2016-04-25 16:07 ` Josh Poimboeuf
2016-04-26 2:40 ` Martin K. Petersen
2016-04-26 3:37 ` James Bottomley
2016-04-26 7:22 ` Arnd Bergmann
2016-04-26 8:35 ` Christoph Hellwig
2016-04-26 10:05 ` Arnd Bergmann
2016-04-26 13:06 ` Martin K. Petersen
2016-04-26 15:58 ` Arnd Bergmann
2016-04-26 22:36 ` James Bottomley
2016-04-27 0:44 ` Martin K. Petersen
2016-04-27 11:05 ` Martin Jambor
2016-04-27 21:34 ` Arnd Bergmann
2016-04-28 14:58 ` Chris Metcalf
2016-04-28 14:58 ` Chris Metcalf
2016-04-28 15:23 ` Arnd Bergmann
2016-04-28 15:48 ` Chris Metcalf
2016-04-28 15:48 ` Chris Metcalf
2016-04-27 22:00 ` [PATCH, RFT] byteswap: try to avoid __builtin_constant_p gcc bug Arnd Bergmann
2016-04-27 22:11 ` Josh Poimboeuf
2016-04-28 16:27 ` Quinn Tran
2016-04-16 7:42 ` This patch triggers a bad gcc bug (was Re: [PATCH] force inlining of some byteswap operations) Arnd Bergmann
2016-04-18 13:22 ` Josh Poimboeuf
2016-02-04 19:45 ` [PATCH] force inlining of unaligned byteswap operations Denys Vlasenko
2016-02-05 7:28 ` 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=570FCEB7.1070200@redhat.com \
--to=dvlasenk@redhat.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=akpm@linux-foundation.org \
--cc=arnd@arndb.de \
--cc=jpoimboe@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=peterz@infradead.org \
--cc=rientjes@google.com \
--cc=tgraf@suug.ch \
/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.