Linux 5.0 compat: Disable vector instructions on 5.0+ kernels

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
This commit is contained in:
Tony Hutter 2019-01-11 18:01:28 -08:00 committed by Brian Behlendorf
parent ed158b19b1
commit 0c593296e9
2 changed files with 144 additions and 39 deletions

View File

@ -1,18 +1,41 @@
dnl # dnl #
dnl # 4.2 API change dnl # Handle differences in kernel FPU code.
dnl # asm/i387.h is replaced by asm/fpu/api.h dnl #
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 # dnl #
AC_DEFUN([ZFS_AC_KERNEL_FPU], [ 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([ ZFS_LINUX_TRY_COMPILE([
#include <linux/kernel.h> #include <asm/i387.h>
#include <asm/fpu/api.h> #include <asm/xcr.h>
],[ ],[
__kernel_fpu_begin(); kernel_fpu_begin();
kernel_fpu_end();
],[ ],[
AC_MSG_RESULT(yes) AC_MSG_RESULT(kernel_fpu_*)
AC_DEFINE(HAVE_FPU_API_H, 1, [kernel has <asm/fpu/api.h> interface]) 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)
])
]) ])
]) ])

View File

@ -81,7 +81,7 @@
#endif #endif
#if defined(_KERNEL) #if defined(_KERNEL)
#if defined(HAVE_FPU_API_H) #if defined(HAVE_UNDERSCORE_KERNEL_FPU)
#include <asm/fpu/api.h> #include <asm/fpu/api.h>
#include <asm/fpu/internal.h> #include <asm/fpu/internal.h>
#define kfpu_begin() \ #define kfpu_begin() \
@ -94,12 +94,18 @@
__kernel_fpu_end(); \ __kernel_fpu_end(); \
preempt_enable(); \ preempt_enable(); \
} }
#else #elif defined(HAVE_KERNEL_FPU)
#include <asm/i387.h> #include <asm/i387.h>
#include <asm/xcr.h> #include <asm/xcr.h>
#define kfpu_begin() kernel_fpu_begin() #define kfpu_begin() kernel_fpu_begin()
#define kfpu_end() kernel_fpu_end() #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 #else
/* /*
* fpu dummy methods for userspace * fpu dummy methods for userspace
@ -286,11 +292,13 @@ __simd_state_enabled(const uint64_t state)
boolean_t has_osxsave; boolean_t has_osxsave;
uint64_t xcr0; 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); has_osxsave = !!boot_cpu_has(X86_FEATURE_OSXSAVE);
#elif defined(_KERNEL) && !defined(X86_FEATURE_OSXSAVE)
has_osxsave = B_FALSE;
#else #else
has_osxsave = B_FALSE;
#endif
#elif !defined(_KERNEL)
has_osxsave = __cpuid_has_osxsave(); has_osxsave = __cpuid_has_osxsave();
#endif #endif
@ -315,8 +323,12 @@ static inline boolean_t
zfs_sse_available(void) zfs_sse_available(void)
{ {
#if defined(_KERNEL) #if defined(_KERNEL)
#if defined(KERNEL_EXPORTS_X86_FPU)
return (!!boot_cpu_has(X86_FEATURE_XMM)); return (!!boot_cpu_has(X86_FEATURE_XMM));
#else #else
return (B_FALSE);
#endif
#elif !defined(_KERNEL)
return (__cpuid_has_sse()); return (__cpuid_has_sse());
#endif #endif
} }
@ -328,8 +340,12 @@ static inline boolean_t
zfs_sse2_available(void) zfs_sse2_available(void)
{ {
#if defined(_KERNEL) #if defined(_KERNEL)
#if defined(KERNEL_EXPORTS_X86_FPU)
return (!!boot_cpu_has(X86_FEATURE_XMM2)); return (!!boot_cpu_has(X86_FEATURE_XMM2));
#else #else
return (B_FALSE);
#endif
#elif !defined(_KERNEL)
return (__cpuid_has_sse2()); return (__cpuid_has_sse2());
#endif #endif
} }
@ -341,8 +357,12 @@ static inline boolean_t
zfs_sse3_available(void) zfs_sse3_available(void)
{ {
#if defined(_KERNEL) #if defined(_KERNEL)
#if defined(KERNEL_EXPORTS_X86_FPU)
return (!!boot_cpu_has(X86_FEATURE_XMM3)); return (!!boot_cpu_has(X86_FEATURE_XMM3));
#else #else
return (B_FALSE);
#endif
#elif !defined(_KERNEL)
return (__cpuid_has_sse3()); return (__cpuid_has_sse3());
#endif #endif
} }
@ -354,8 +374,12 @@ static inline boolean_t
zfs_ssse3_available(void) zfs_ssse3_available(void)
{ {
#if defined(_KERNEL) #if defined(_KERNEL)
#if defined(KERNEL_EXPORTS_X86_FPU)
return (!!boot_cpu_has(X86_FEATURE_SSSE3)); return (!!boot_cpu_has(X86_FEATURE_SSSE3));
#else #else
return (B_FALSE);
#endif
#elif !defined(_KERNEL)
return (__cpuid_has_ssse3()); return (__cpuid_has_ssse3());
#endif #endif
} }
@ -367,8 +391,12 @@ static inline boolean_t
zfs_sse4_1_available(void) zfs_sse4_1_available(void)
{ {
#if defined(_KERNEL) #if defined(_KERNEL)
#if defined(KERNEL_EXPORTS_X86_FPU)
return (!!boot_cpu_has(X86_FEATURE_XMM4_1)); return (!!boot_cpu_has(X86_FEATURE_XMM4_1));
#else #else
return (B_FALSE);
#endif
#elif !defined(_KERNEL)
return (__cpuid_has_sse4_1()); return (__cpuid_has_sse4_1());
#endif #endif
} }
@ -380,8 +408,12 @@ static inline boolean_t
zfs_sse4_2_available(void) zfs_sse4_2_available(void)
{ {
#if defined(_KERNEL) #if defined(_KERNEL)
#if defined(KERNEL_EXPORTS_X86_FPU)
return (!!boot_cpu_has(X86_FEATURE_XMM4_2)); return (!!boot_cpu_has(X86_FEATURE_XMM4_2));
#else #else
return (B_FALSE);
#endif
#elif !defined(_KERNEL)
return (__cpuid_has_sse4_2()); return (__cpuid_has_sse4_2());
#endif #endif
} }
@ -394,8 +426,12 @@ zfs_avx_available(void)
{ {
boolean_t has_avx; boolean_t has_avx;
#if defined(_KERNEL) #if defined(_KERNEL)
#if defined(KERNEL_EXPORTS_X86_FPU)
has_avx = !!boot_cpu_has(X86_FEATURE_AVX); has_avx = !!boot_cpu_has(X86_FEATURE_AVX);
#else #else
has_avx = B_FALSE;
#endif
#elif !defined(_KERNEL)
has_avx = __cpuid_has_avx(); has_avx = __cpuid_has_avx();
#endif #endif
@ -409,11 +445,13 @@ static inline boolean_t
zfs_avx2_available(void) zfs_avx2_available(void)
{ {
boolean_t has_avx2; 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); has_avx2 = !!boot_cpu_has(X86_FEATURE_AVX2);
#elif defined(_KERNEL) && !defined(X86_FEATURE_AVX2)
has_avx2 = B_FALSE;
#else #else
has_avx2 = B_FALSE;
#endif
#elif !defined(_KERNEL)
has_avx2 = __cpuid_has_avx2(); has_avx2 = __cpuid_has_avx2();
#endif #endif
@ -426,11 +464,13 @@ zfs_avx2_available(void)
static inline boolean_t static inline boolean_t
zfs_bmi1_available(void) 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)); return (!!boot_cpu_has(X86_FEATURE_BMI1));
#elif defined(_KERNEL) && !defined(X86_FEATURE_BMI1)
return (B_FALSE);
#else #else
return (B_FALSE);
#endif
#elif !defined(_KERNEL)
return (__cpuid_has_bmi1()); return (__cpuid_has_bmi1());
#endif #endif
} }
@ -441,11 +481,13 @@ zfs_bmi1_available(void)
static inline boolean_t static inline boolean_t
zfs_bmi2_available(void) 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)); return (!!boot_cpu_has(X86_FEATURE_BMI2));
#elif defined(_KERNEL) && !defined(X86_FEATURE_BMI2)
return (B_FALSE);
#else #else
return (B_FALSE);
#endif
#elif !defined(_KERNEL)
return (__cpuid_has_bmi2()); return (__cpuid_has_bmi2());
#endif #endif
} }
@ -456,11 +498,13 @@ zfs_bmi2_available(void)
static inline boolean_t static inline boolean_t
zfs_aes_available(void) 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)); return (!!boot_cpu_has(X86_FEATURE_AES));
#elif defined(_KERNEL) && !defined(X86_FEATURE_AES)
return (B_FALSE);
#else #else
return (B_FALSE);
#endif
#elif !defined(_KERNEL)
return (__cpuid_has_aes()); return (__cpuid_has_aes());
#endif #endif
} }
@ -471,11 +515,13 @@ zfs_aes_available(void)
static inline boolean_t static inline boolean_t
zfs_pclmulqdq_available(void) 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)); return (!!boot_cpu_has(X86_FEATURE_PCLMULQDQ));
#elif defined(_KERNEL) && !defined(X86_FEATURE_PCLMULQDQ)
return (B_FALSE);
#else #else
return (B_FALSE);
#endif
#elif !defined(_KERNEL)
return (__cpuid_has_pclmulqdq()); return (__cpuid_has_pclmulqdq());
#endif #endif
} }
@ -503,8 +549,12 @@ zfs_avx512f_available(void)
{ {
boolean_t has_avx512 = B_FALSE; 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); has_avx512 = !!boot_cpu_has(X86_FEATURE_AVX512F);
#else
has_avx512 = B_FALSE;
#endif
#elif !defined(_KERNEL) #elif !defined(_KERNEL)
has_avx512 = __cpuid_has_avx512f(); has_avx512 = __cpuid_has_avx512f();
#endif #endif
@ -518,9 +568,13 @@ zfs_avx512cd_available(void)
{ {
boolean_t has_avx512 = B_FALSE; 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) && has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
boot_cpu_has(X86_FEATURE_AVX512CD); boot_cpu_has(X86_FEATURE_AVX512CD);
#else
has_avx512 = B_FALSE;
#endif
#elif !defined(_KERNEL) #elif !defined(_KERNEL)
has_avx512 = __cpuid_has_avx512cd(); has_avx512 = __cpuid_has_avx512cd();
#endif #endif
@ -534,9 +588,13 @@ zfs_avx512er_available(void)
{ {
boolean_t has_avx512 = B_FALSE; 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) && has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
boot_cpu_has(X86_FEATURE_AVX512ER); boot_cpu_has(X86_FEATURE_AVX512ER);
#else
has_avx512 = B_FALSE;
#endif
#elif !defined(_KERNEL) #elif !defined(_KERNEL)
has_avx512 = __cpuid_has_avx512er(); has_avx512 = __cpuid_has_avx512er();
#endif #endif
@ -550,9 +608,13 @@ zfs_avx512pf_available(void)
{ {
boolean_t has_avx512 = B_FALSE; 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) && has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
boot_cpu_has(X86_FEATURE_AVX512PF); boot_cpu_has(X86_FEATURE_AVX512PF);
#else
has_avx512 = B_FALSE;
#endif
#elif !defined(_KERNEL) #elif !defined(_KERNEL)
has_avx512 = __cpuid_has_avx512pf(); has_avx512 = __cpuid_has_avx512pf();
#endif #endif
@ -566,9 +628,13 @@ zfs_avx512bw_available(void)
{ {
boolean_t has_avx512 = B_FALSE; 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) && has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
boot_cpu_has(X86_FEATURE_AVX512BW); boot_cpu_has(X86_FEATURE_AVX512BW);
#else
has_avx512 = B_FALSE;
#endif
#elif !defined(_KERNEL) #elif !defined(_KERNEL)
has_avx512 = __cpuid_has_avx512bw(); has_avx512 = __cpuid_has_avx512bw();
#endif #endif
@ -582,9 +648,13 @@ zfs_avx512dq_available(void)
{ {
boolean_t has_avx512 = B_FALSE; 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) && has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
boot_cpu_has(X86_FEATURE_AVX512DQ); boot_cpu_has(X86_FEATURE_AVX512DQ);
#else
has_avx512 = B_FALSE;
#endif
#elif !defined(_KERNEL) #elif !defined(_KERNEL)
has_avx512 = __cpuid_has_avx512dq(); has_avx512 = __cpuid_has_avx512dq();
#endif #endif
@ -598,9 +668,13 @@ zfs_avx512vl_available(void)
{ {
boolean_t has_avx512 = B_FALSE; 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) && has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
boot_cpu_has(X86_FEATURE_AVX512VL); boot_cpu_has(X86_FEATURE_AVX512VL);
#else
has_avx512 = B_FALSE;
#endif
#elif !defined(_KERNEL) #elif !defined(_KERNEL)
has_avx512 = __cpuid_has_avx512vl(); has_avx512 = __cpuid_has_avx512vl();
#endif #endif
@ -614,9 +688,13 @@ zfs_avx512ifma_available(void)
{ {
boolean_t has_avx512 = B_FALSE; 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) && has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
boot_cpu_has(X86_FEATURE_AVX512IFMA); boot_cpu_has(X86_FEATURE_AVX512IFMA);
#else
has_avx512 = B_FALSE;
#endif
#elif !defined(_KERNEL) #elif !defined(_KERNEL)
has_avx512 = __cpuid_has_avx512ifma(); has_avx512 = __cpuid_has_avx512ifma();
#endif #endif
@ -630,9 +708,13 @@ zfs_avx512vbmi_available(void)
{ {
boolean_t has_avx512 = B_FALSE; 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) && has_avx512 = boot_cpu_has(X86_FEATURE_AVX512F) &&
boot_cpu_has(X86_FEATURE_AVX512VBMI); boot_cpu_has(X86_FEATURE_AVX512VBMI);
#else
has_avx512 = B_FALSE;
#endif
#elif !defined(_KERNEL) #elif !defined(_KERNEL)
has_avx512 = __cpuid_has_avx512f() && has_avx512 = __cpuid_has_avx512f() &&
__cpuid_has_avx512vbmi(); __cpuid_has_avx512vbmi();