From patchwork Mon May 2 21:48:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 100869 Delivered-To: patch@linaro.org Received: by 10.140.92.199 with SMTP id b65csp267176qge; Mon, 2 May 2016 14:49:26 -0700 (PDT) X-Received: by 10.66.26.110 with SMTP id k14mr55090212pag.66.1462225765906; Mon, 02 May 2016 14:49:25 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 190si262250pfa.55.2016.05.02.14.49.25 for ; Mon, 02 May 2016 14:49:25 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-scsi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-scsi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-scsi-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932217AbcEBVtY (ORCPT ); Mon, 2 May 2016 17:49:24 -0400 Received: from mout.kundenserver.de ([212.227.126.133]:49739 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932148AbcEBVtX (ORCPT ); Mon, 2 May 2016 17:49:23 -0400 Received: from wuerfel.localnet ([78.42.132.4]) by mrelayeu.kundenserver.de (mreue001) with ESMTPSA (Nemesis) id 0MSUzj-1b7Teb2USx-00TYiY; Mon, 02 May 2016 23:48:26 +0200 From: Arnd Bergmann To: akpm@linux-foundation.org Cc: mm-commits@vger.kernel.org, linux-kernel@vger.kernel.org, linux-scsi@vger.kernel.org, jpoimboe@redhat.com, Martin Jambor , "Martin K. Petersen" , James Bottomley , Denys Vlasenko , Thomas Graf , Peter Zijlstra , David Rientjes , Ingo Molnar , Himanshu Madhani , Dept-Eng QLA2xxx Upstream , Jan Hubicka Subject: [PATCH v2] byteswap: try to avoid __builtin_constant_p gcc bug Date: Mon, 02 May 2016 23:48:19 +0200 Message-ID: <1780465.XdtPJpi8Tt@wuerfel> User-Agent: KMail/4.11.5 (Linux/3.16.0-10-generic; KDE/4.11.5; x86_64; ; ) MIME-Version: 1.0 X-Provags-ID: V03:K0:MLuA2DfIZSnOu6pqlAlxAXcL4ioPMCHWS8FKwz+CcBIwYxAN701 pMy6KW6ZxYYdfaSxqS/I61pz6WR4LdE2wSs9/JO5dP/4FxbbgBzCOsGppO5PBO9KHPER/F9 P7SX83QKHs2EVTBuu44WxpIx+vAdFfJiBik7mKDIOwrUgIpjR7Z5OJH0RQZxzaJEf3yHOxV nHXOzYgjkLU8rv1pWGw6Q== X-UI-Out-Filterresults: notjunk:1; V01:K0:aVN808jfnrc=:M6/TPfTljp2cXrssHv2m+5 Gn/QctXV7fCDgXRBJ4RzVhfhxGjwQ0lVr9N7hIapT/3zRvHL/JhYUDXedvdc2QCv8io+0RVKr lKo6DfYNoS43AxvA9CQSvOYNrDYCvubcgo8mXClwYfgO4UJhdH7fHOJBJY6SCLbVheDK1tnaj WTTV5/5Mo4cFpIpJOdVKsImzQ5Bem3UcARPKYdlW9eJbCPHqHGx3fmrXTFHMILplUSzoyEvnC hf2pma5ZyDfU9XdH1S5JYlokfsW7A8y5akXbeUKdwnSomGn83RukGKS5VzP8ZBSUCObaD2+7M I1KEZvPsv3IZeNSHHL0aAnxAzhuScRdQn9Z7+kjkXrkK7N/IQPPTPboWtPwaKdrVfnSuKmpHM 8oZPHg0W+KpaFYXZZVvyznk8xhVai7ipeylNyxnmCuPV05XOBs6BFskGfd50P9DKQ5+QH+3sV +xQrkEEv6m0J/0PSRFpst2DI+GjF0eBR3Mr443+238Nl+lpCLdG9nzk8nqxAm3WZoVRImZ9or vySzNCIuLkDieprjHVGurfBi381DWtgJYiORwGiOMaYy4bYE7SH9k+5db9QQ7Q4U0v47KbqOJ sfc8vO3nVGO33/tSTNZ7cxENifMtrQnW5GcbdpW9b5wtNIXqHW5M+wJRqRtR9giNZzUiB+osz tuxD+dnaVkqIdNGfsombYWswBaMnl2AaUpMgclHQfSMHW3P4XwBnMZ4+pEZ1vJBp4Z3WE25Cn Tb4TmgIg/cK192Ty Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org This is another attempt to avoid a regression in wwn_to_u64() after that started using get_unaligned_be64(), which in turn ran into a bug on gcc-4.9 through 6.1. The regression got introduced due to the combination of two separate workarounds (e3bde9568d99 and ef3fb2422ffe) that each try to sidestep distinct problems with gcc behavior (code growth and increased stack usage). Unfortunately after both have been applied, a more series gcc bug has been uncovered, leading to incorrect object code that discards part of a function and causes undefined behavior. As part of this problem is how __builtin_constant_p gets evaluated on an argument passed by reference into an inline function, this avoids the use of __builtin_constant_p() for all architectures that set CONFIG_ARCH_USE_BUILTIN_BSWAP. Most architectures do not set ARCH_SUPPORTS_OPTIMIZED_INLINING, which means they probably do not suffer from the problem in the qla2xxx driver, but they might still run into it elsewhere. Both of the original workarounds were only merged in the 4.6 kernel, and the bug that is fixed by this patch should only appear if both are there, so we probably don't need to backport the fix. On the other hand, it works by simplifying the code path and should not have any negative effects. Link: https://lkml.org/lkml/headers/2016/4/12/1103 Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66122 Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70232 Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70646 Fixes: e3bde9568d99 ("include/linux/unaligned: force inlining of byteswap operations") Fixes: ef3fb2422ffe ("scsi: fc: use get/put_unaligned64 for wwn access") Tested-by: Josh Poimboeuf # on gcc-5.3 Tested-by: Quinn Tran Reviewed-by: Josh Poimboeuf Signed-off-by: Arnd Bergmann ---- This contains the extra cast to fix up 64-bit builds, and has an expanded changelog, compared to the original version. * __swahw32 - return a word-swapped 32-bit value -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/include/uapi/linux/swab.h b/include/uapi/linux/swab.h index 3f10e5317b46..de56fd54428d 100644 --- a/include/uapi/linux/swab.h +++ b/include/uapi/linux/swab.h @@ -45,9 +45,7 @@ static inline __attribute_const__ __u16 __fswab16(__u16 val) { -#ifdef __HAVE_BUILTIN_BSWAP16__ - return __builtin_bswap16(val); -#elif defined (__arch_swab16) +#if defined (__arch_swab16) return __arch_swab16(val); #else return ___constant_swab16(val); @@ -56,9 +54,7 @@ static inline __attribute_const__ __u16 __fswab16(__u16 val) static inline __attribute_const__ __u32 __fswab32(__u32 val) { -#ifdef __HAVE_BUILTIN_BSWAP32__ - return __builtin_bswap32(val); -#elif defined(__arch_swab32) +#if defined(__arch_swab32) return __arch_swab32(val); #else return ___constant_swab32(val); @@ -67,9 +63,7 @@ static inline __attribute_const__ __u32 __fswab32(__u32 val) static inline __attribute_const__ __u64 __fswab64(__u64 val) { -#ifdef __HAVE_BUILTIN_BSWAP64__ - return __builtin_bswap64(val); -#elif defined (__arch_swab64) +#if defined (__arch_swab64) return __arch_swab64(val); #elif defined(__SWAB_64_THRU_32__) __u32 h = val >> 32; @@ -102,28 +96,40 @@ static inline __attribute_const__ __u32 __fswahb32(__u32 val) * __swab16 - return a byteswapped 16-bit value * @x: value to byteswap */ +#ifdef __HAVE_BUILTIN_BSWAP16__ +#define __swab16(x) __builtin_bswap16((__u16)(x)) +#else #define __swab16(x) \ (__builtin_constant_p((__u16)(x)) ? \ ___constant_swab16(x) : \ __fswab16(x)) +#endif /** * __swab32 - return a byteswapped 32-bit value * @x: value to byteswap */ +#ifdef __HAVE_BUILTIN_BSWAP32__ +#define __swab32(x) __builtin_bswap32((__u32)(x)) +#else #define __swab32(x) \ (__builtin_constant_p((__u32)(x)) ? \ ___constant_swab32(x) : \ __fswab32(x)) +#endif /** * __swab64 - return a byteswapped 64-bit value * @x: value to byteswap */ +#ifdef __HAVE_BUILTIN_BSWAP64__ +#define __swab64(x) (__u64)__builtin_bswap64((__u64)(x)) +#else #define __swab64(x) \ (__builtin_constant_p((__u64)(x)) ? \ ___constant_swab64(x) : \ __fswab64(x)) +#endif /**