]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Linux 5.0 compat: Disable vector instructions on 5.0+ kernels
authorTony Hutter <hutter2@llnl.gov>
Sat, 12 Jan 2019 02:01:28 +0000 (18:01 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 28 Jan 2019 18:11:45 +0000 (10:11 -0800)
The 5.0 kernel no longer exports the functions we need to do vector
(SSE/SSE2/SSE3/AVX...) instructions.  Disable vector-based checksum
algorithms when building against those kernels.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tony Hutter <hutter2@llnl.gov>
Closes #8259

config/kernel-fpu.m4
include/linux/simd_x86.h

index 1c5690969d4801e81d0979f2a3a29992a4db53ce..671fe7ea54e8c2bd45476616690add3194a4a8e6 100644 (file)
@@ -1,18 +1,41 @@
+dnl # 
+dnl # Handle differences in kernel FPU code.
 dnl #
-dnl # 4.2 API change
-dnl # asm/i387.h is replaced by asm/fpu/api.h
+dnl # Kernel
+dnl # 5.0:     All kernel fpu functions are GPL only, so we can't use them.
+dnl #          (nothing defined)
+dnl #
+dnl # 4.2:     Use __kernel_fpu_{begin,end}()
+dnl #          HAVE_UNDERSCORE_KERNEL_FPU & KERNEL_EXPORTS_X86_FPU
+dnl #
+dnl # Pre-4.2: Use kernel_fpu_{begin,end}()
+dnl #          HAVE_KERNEL_FPU & KERNEL_EXPORTS_X86_FPU
 dnl #
 AC_DEFUN([ZFS_AC_KERNEL_FPU], [
-       AC_MSG_CHECKING([whether asm/fpu/api.h exists])
+       AC_MSG_CHECKING([which kernel_fpu function to use])
        ZFS_LINUX_TRY_COMPILE([
-               #include <linux/kernel.h>
-               #include <asm/fpu/api.h>
+               #include <asm/i387.h>
+               #include <asm/xcr.h>
        ],[
-               __kernel_fpu_begin();
+               kernel_fpu_begin();
+               kernel_fpu_end();
        ],[
-               AC_MSG_RESULT(yes)
-               AC_DEFINE(HAVE_FPU_API_H, 1, [kernel has <asm/fpu/api.h> interface])
+               AC_MSG_RESULT(kernel_fpu_*)
+               AC_DEFINE(HAVE_KERNEL_FPU, 1, [kernel has kernel_fpu_* functions])
+               AC_DEFINE(KERNEL_EXPORTS_X86_FPU, 1, [kernel exports FPU functions])
        ],[
-               AC_MSG_RESULT(no)
+               ZFS_LINUX_TRY_COMPILE([
+                       #include <linux/kernel.h>
+                       #include <asm/fpu/api.h>
+               ],[
+                       __kernel_fpu_begin();
+                       __kernel_fpu_end();
+               ],[
+                       AC_MSG_RESULT(__kernel_fpu_*)
+                       AC_DEFINE(HAVE_UNDERSCORE_KERNEL_FPU, 1, [kernel has __kernel_fpu_* functions])
+                       AC_DEFINE(KERNEL_EXPORTS_X86_FPU, 1, [kernel exports FPU functions])
+               ],[
+                       AC_MSG_RESULT(not exported)
+               ])
        ])
 ])
index 10ce02e3746f72e59acee97438214e2a7c35fdc8..5d6fbed35b9fd110d16a8c62c0efb8f762c54857 100644 (file)
@@ -81,7 +81,7 @@
 #endif
 
 #if defined(_KERNEL)
-#if defined(HAVE_FPU_API_H)
+#if defined(HAVE_UNDERSCORE_KERNEL_FPU)
 #include <asm/fpu/api.h>
 #include <asm/fpu/internal.h>
 #define        kfpu_begin()            \
        __kernel_fpu_end();             \
        preempt_enable();               \
 }
-#else
+#elif defined(HAVE_KERNEL_FPU)
 #include <asm/i387.h>
 #include <asm/xcr.h>
 #define        kfpu_begin()    kernel_fpu_begin()
 #define        kfpu_end()              kernel_fpu_end()
-#endif /* defined(HAVE_FPU_API_H) */
+#else
+/* Kernel doesn't export any kernel_fpu_* functions */
+#include <asm/fpu/internal.h>  /* For kernel xgetbv() */
+#define        kfpu_begin()    panic("This code should never run")
+#define        kfpu_end()      panic("This code should never run")
+#endif /* defined(HAVE_KERNEL_FPU) */
+
 #else
 /*
  * fpu dummy methods for userspace
@@ -286,11 +292,13 @@ __simd_state_enabled(const uint64_t state)
        boolean_t has_osxsave;
        uint64_t xcr0;
 
-#if defined(_KERNEL) && defined(X86_FEATURE_OSXSAVE)
+#if defined(_KERNEL)
+#if defined(X86_FEATURE_OSXSAVE) && defined(KERNEL_EXPORTS_X86_FPU)
        has_osxsave = !!boot_cpu_has(X86_FEATURE_OSXSAVE);
-#elif defined(_KERNEL) && !defined(X86_FEATURE_OSXSAVE)
-       has_osxsave = B_FALSE;
 #else
+       has_osxsave = B_FALSE;
+#endif
+#elif !defined(_KERNEL)
        has_osxsave = __cpuid_has_osxsave();
 #endif
 
@@ -315,8 +323,12 @@ static inline boolean_t
 zfs_sse_available(void)
 {
 #if defined(_KERNEL)
+#if defined(KERNEL_EXPORTS_X86_FPU)
        return (!!boot_cpu_has(X86_FEATURE_XMM));
 #else
+       return (B_FALSE);
+#endif
+#elif !defined(_KERNEL)
        return (__cpuid_has_sse());
 #endif
 }
@@ -328,8 +340,12 @@ static inline boolean_t
 zfs_sse2_available(void)
 {
 #if defined(_KERNEL)
+#if defined(KERNEL_EXPORTS_X86_FPU)
        return (!!boot_cpu_has(X86_FEATURE_XMM2));
 #else
+       return (B_FALSE);
+#endif
+#elif !defined(_KERNEL)
        return (__cpuid_has_sse2());
 #endif
 }
@@ -341,8 +357,12 @@ static inline boolean_t
 zfs_sse3_available(void)
 {
 #if defined(_KERNEL)
+#if defined(KERNEL_EXPORTS_X86_FPU)
        return (!!boot_cpu_has(X86_FEATURE_XMM3));
 #else
+       return (B_FALSE);
+#endif
+#elif !defined(_KERNEL)
        return (__cpuid_has_sse3());
 #endif
 }
@@ -354,8 +374,12 @@ static inline boolean_t
 zfs_ssse3_available(void)
 {
 #if defined(_KERNEL)
+#if defined(KERNEL_EXPORTS_X86_FPU)
        return (!!boot_cpu_has(X86_FEATURE_SSSE3));
 #else
+       return (B_FALSE);
+#endif
+#elif !defined(_KERNEL)
        return (__cpuid_has_ssse3());
 #endif
 }
@@ -367,8 +391,12 @@ static inline boolean_t
 zfs_sse4_1_available(void)
 {
 #if defined(_KERNEL)
+#if defined(KERNEL_EXPORTS_X86_FPU)
        return (!!boot_cpu_has(X86_FEATURE_XMM4_1));
 #else
+       return (B_FALSE);
+#endif
+#elif !defined(_KERNEL)
        return (__cpuid_has_sse4_1());
 #endif
 }
@@ -380,8 +408,12 @@ static inline boolean_t
 zfs_sse4_2_available(void)
 {
 #if defined(_KERNEL)
+#if defined(KERNEL_EXPORTS_X86_FPU)
        return (!!boot_cpu_has(X86_FEATURE_XMM4_2));
 #else
+       return (B_FALSE);
+#endif
+#elif !defined(_KERNEL)
        return (__cpuid_has_sse4_2());
 #endif
 }
@@ -394,8 +426,12 @@ zfs_avx_available(void)
 {
        boolean_t has_avx;
 #if defined(_KERNEL)
+#if defined(KERNEL_EXPORTS_X86_FPU)
        has_avx = !!boot_cpu_has(X86_FEATURE_AVX);
 #else
+       has_avx = B_FALSE;
+#endif
+#elif !defined(_KERNEL)
        has_avx = __cpuid_has_avx();
 #endif
 
@@ -409,11 +445,13 @@ static inline boolean_t
 zfs_avx2_available(void)
 {
        boolean_t has_avx2;
-#if defined(_KERNEL) && defined(X86_FEATURE_AVX2)
+#if defined(_KERNEL)
+#if defined(X86_FEATURE_AVX2) && defined(KERNEL_EXPORTS_X86_FPU)
        has_avx2 = !!boot_cpu_has(X86_FEATURE_AVX2);
-#elif defined(_KERNEL) && !defined(X86_FEATURE_AVX2)
-       has_avx2 = B_FALSE;
 #else
+       has_avx2 = B_FALSE;
+#endif
+#elif !defined(_KERNEL)
        has_avx2 = __cpuid_has_avx2();
 #endif
 
@@ -426,11 +464,13 @@ zfs_avx2_available(void)
 static inline boolean_t
 zfs_bmi1_available(void)
 {
-#if defined(_KERNEL) && defined(X86_FEATURE_BMI1)
+#if defined(_KERNEL)
+#if defined(X86_FEATURE_BMI1) && defined(KERNEL_EXPORTS_X86_FPU)
        return (!!boot_cpu_has(X86_FEATURE_BMI1));
-#elif defined(_KERNEL) && !defined(X86_FEATURE_BMI1)
-       return (B_FALSE);
 #else
+       return (B_FALSE);
+#endif
+#elif !defined(_KERNEL)
        return (__cpuid_has_bmi1());
 #endif
 }
@@ -441,11 +481,13 @@ zfs_bmi1_available(void)
 static inline boolean_t
 zfs_bmi2_available(void)
 {
-#if defined(_KERNEL) && defined(X86_FEATURE_BMI2)
+#if defined(_KERNEL)
+#if defined(X86_FEATURE_BMI2) && defined(KERNEL_EXPORTS_X86_FPU)
        return (!!boot_cpu_has(X86_FEATURE_BMI2));
-#elif defined(_KERNEL) && !defined(X86_FEATURE_BMI2)
-       return (B_FALSE);
 #else
+       return (B_FALSE);
+#endif
+#elif !defined(_KERNEL)
        return (__cpuid_has_bmi2());
 #endif
 }
@@ -456,11 +498,13 @@ zfs_bmi2_available(void)
 static inline boolean_t
 zfs_aes_available(void)
 {
-#if defined(_KERNEL) && defined(X86_FEATURE_AES)
+#if defined(_KERNEL)
+#if defined(X86_FEATURE_AES) && defined(KERNEL_EXPORTS_X86_FPU)
        return (!!boot_cpu_has(X86_FEATURE_AES));
-#elif defined(_KERNEL) && !defined(X86_FEATURE_AES)
-       return (B_FALSE);
 #else
+       return (B_FALSE);
+#endif
+#elif !defined(_KERNEL)
        return (__cpuid_has_aes());
 #endif
 }
@@ -471,11 +515,13 @@ zfs_aes_available(void)
 static inline boolean_t
 zfs_pclmulqdq_available(void)
 {
-#if defined(_KERNEL) && defined(X86_FEATURE_PCLMULQDQ)
+#if defined(_KERNEL)
+#if defined(X86_FEATURE_PCLMULQDQ) && defined(KERNEL_EXPORTS_X86_FPU)
        return (!!boot_cpu_has(X86_FEATURE_PCLMULQDQ));
-#elif defined(_KERNEL) && !defined(X86_FEATURE_PCLMULQDQ)
-       return (B_FALSE);
 #else
+       return (B_FALSE);
+#endif
+#elif !defined(_KERNEL)
        return (__cpuid_has_pclmulqdq());
 #endif
 }
@@ -503,8 +549,12 @@ zfs_avx512f_available(void)
 {
        boolean_t has_avx512 = B_FALSE;
 
-#if defined(_KERNEL) && defined(X86_FEATURE_AVX512F)
+#if defined(_KERNEL)
+#if defined(X86_FEATURE_AVX512F) && defined(KERNEL_EXPORTS_X86_FPU)
        has_avx512 = !!boot_cpu_has(X86_FEATURE_AVX512F);
+#else
+       has_avx512 = B_FALSE;
+#endif
 #elif !defined(_KERNEL)
        has_avx512 = __cpuid_has_avx512f();
 #endif
@@ -518,9 +568,13 @@ zfs_avx512cd_available(void)
 {
        boolean_t has_avx512 = B_FALSE;
 
-#if defined(_KERNEL) && defined(X86_FEATURE_AVX512CD)
+#if defined(_KERNEL)
+#if defined(X86_FEATURE_AVX512CD) && defined(KERNEL_EXPORTS_X86_FPU)
        has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
            boot_cpu_has(X86_FEATURE_AVX512CD);
+#else
+       has_avx512 = B_FALSE;
+#endif
 #elif !defined(_KERNEL)
        has_avx512 = __cpuid_has_avx512cd();
 #endif
@@ -534,9 +588,13 @@ zfs_avx512er_available(void)
 {
        boolean_t has_avx512 = B_FALSE;
 
-#if defined(_KERNEL) && defined(X86_FEATURE_AVX512ER)
+#if defined(_KERNEL)
+#if defined(X86_FEATURE_AVX512ER) && defined(KERNEL_EXPORTS_X86_FPU)
        has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
            boot_cpu_has(X86_FEATURE_AVX512ER);
+#else
+       has_avx512 = B_FALSE;
+#endif
 #elif !defined(_KERNEL)
        has_avx512 = __cpuid_has_avx512er();
 #endif
@@ -550,9 +608,13 @@ zfs_avx512pf_available(void)
 {
        boolean_t has_avx512 = B_FALSE;
 
-#if defined(_KERNEL) && defined(X86_FEATURE_AVX512PF)
+#if defined(_KERNEL)
+#if defined(X86_FEATURE_AVX512PF) && defined(KERNEL_EXPORTS_X86_FPU)
        has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
            boot_cpu_has(X86_FEATURE_AVX512PF);
+#else
+       has_avx512 = B_FALSE;
+#endif
 #elif !defined(_KERNEL)
        has_avx512 = __cpuid_has_avx512pf();
 #endif
@@ -566,9 +628,13 @@ zfs_avx512bw_available(void)
 {
        boolean_t has_avx512 = B_FALSE;
 
-#if defined(_KERNEL) && defined(X86_FEATURE_AVX512BW)
+#if defined(_KERNEL)
+#if defined(X86_FEATURE_AVX512BW) && defined(KERNEL_EXPORTS_X86_FPU)
        has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
            boot_cpu_has(X86_FEATURE_AVX512BW);
+#else
+       has_avx512 = B_FALSE;
+#endif
 #elif !defined(_KERNEL)
        has_avx512 = __cpuid_has_avx512bw();
 #endif
@@ -582,9 +648,13 @@ zfs_avx512dq_available(void)
 {
        boolean_t has_avx512 = B_FALSE;
 
-#if defined(_KERNEL) && defined(X86_FEATURE_AVX512DQ)
+#if defined(_KERNEL)
+#if defined(X86_FEATURE_AVX512DQ) && defined(KERNEL_EXPORTS_X86_FPU)
        has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
            boot_cpu_has(X86_FEATURE_AVX512DQ);
+#else
+       has_avx512 = B_FALSE;
+#endif
 #elif !defined(_KERNEL)
        has_avx512 = __cpuid_has_avx512dq();
 #endif
@@ -598,9 +668,13 @@ zfs_avx512vl_available(void)
 {
        boolean_t has_avx512 = B_FALSE;
 
-#if defined(_KERNEL) && defined(X86_FEATURE_AVX512VL)
+#if defined(_KERNEL)
+#if defined(X86_FEATURE_AVX512VL) && defined(KERNEL_EXPORTS_X86_FPU)
        has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
            boot_cpu_has(X86_FEATURE_AVX512VL);
+#else
+       has_avx512 = B_FALSE;
+#endif
 #elif !defined(_KERNEL)
        has_avx512 = __cpuid_has_avx512vl();
 #endif
@@ -614,9 +688,13 @@ zfs_avx512ifma_available(void)
 {
        boolean_t has_avx512 = B_FALSE;
 
-#if defined(_KERNEL) && defined(X86_FEATURE_AVX512IFMA)
+#if defined(_KERNEL)
+#if defined(X86_FEATURE_AVX512IFMA) && defined(KERNEL_EXPORTS_X86_FPU)
        has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
            boot_cpu_has(X86_FEATURE_AVX512IFMA);
+#else
+       has_avx512 = B_FALSE;
+#endif
 #elif !defined(_KERNEL)
        has_avx512 = __cpuid_has_avx512ifma();
 #endif
@@ -630,9 +708,13 @@ zfs_avx512vbmi_available(void)
 {
        boolean_t has_avx512 = B_FALSE;
 
-#if defined(_KERNEL) && defined(X86_FEATURE_AVX512VBMI)
+#if defined(_KERNEL)
+#if defined(X86_FEATURE_AVX512VBMI) && defined(KERNEL_EXPORTS_X86_FPU)
        has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
            boot_cpu_has(X86_FEATURE_AVX512VBMI);
+#else
+       has_avx512 = B_FALSE;
+#endif
 #elif !defined(_KERNEL)
        has_avx512 = __cpuid_has_avx512f() &&
            __cpuid_has_avx512vbmi();