From 58828d0759642a8d438c94ee96a3e9848f89102a Mon Sep 17 00:00:00 2001 From: Sitsofe Wheeler Date: Wed, 28 Mar 2018 15:49:14 +0100 Subject: [PATCH] aarch64: refactor HW ARM CRC32c detection - Tweak how fio does the configure probe for hardware accelerated ARM CRC32c - Move the Linux specific runtime detection into os-linux.h making it cleaner to implement runtime probing for OSes other than Linux in the future - Make the ARCH_HAVE_CRC_CRYPTO define go into the config-host.* files the same way as most other configure defines - Set/use only the ARCH_HAVE_CRC_CRYPTO define rather than also creating/using ARCH_HAVE_ARM64_CRC_CRYPTO This commit should silence the "Fails to compile: error: sys/auxv.h file not found" compilation message that was seen on FreeBSD 12/arm64 (but note a future commit will be required to implement runtime probing and actually enable the accelerated path on that platform). Signed-off-by: Sitsofe Wheeler --- arch/arch-aarch64.h | 4 ---- configure | 16 ++++++++++++---- crc/crc32c-arm64.c | 21 +++++++-------------- crc/crc32c.h | 4 ++-- os/os-linux.h | 27 +++++++++++++++++++++++++++ os/os.h | 11 +++++++++++ 6 files changed, 59 insertions(+), 24 deletions(-) diff --git a/arch/arch-aarch64.h b/arch/arch-aarch64.h index 0912a86f..2a86cc5a 100644 --- a/arch/arch-aarch64.h +++ b/arch/arch-aarch64.h @@ -27,8 +27,4 @@ static inline int arch_ffz(unsigned long bitmask) #define ARCH_HAVE_FFZ -#ifdef ARCH_HAVE_CRC_CRYPTO -#define ARCH_HAVE_ARM64_CRC_CRYPTO -#endif - #endif diff --git a/configure b/configure index f6358630..1d8c7f18 100755 --- a/configure +++ b/configure @@ -2108,18 +2108,23 @@ if test "$march_armv8_a_crc_crypto" != "yes" ; then fi if test "$cpu" = "arm64" ; then cat > $TMPC < #include #include +#include int main(void) { - return 0; + /* Can we also do a runtime probe? */ +#if __linux__ + return getauxval(AT_HWCAP); +#else +# error "Don't know how to do runtime probe for ARM CRC32c" +#endif } EOF - if compile_prog "-march=armv8-a+crc+crypto" "" ""; then + if compile_prog "-march=armv8-a+crc+crypto" "" "ARM CRC32c"; then march_armv8_a_crc_crypto="yes" - CFLAGS="$CFLAGS -march=armv8-a+crc+crypto -DARCH_HAVE_CRC_CRYPTO" + CFLAGS="$CFLAGS -march=armv8-a+crc+crypto" march_set="yes" fi fi @@ -2421,6 +2426,9 @@ if test "$zlib" = "no" ; then echo "Note that some distros have separate packages for static libraries." fi fi +if test "$march_armv8_a_crc_crypto" = "yes" ; then + output_sym "ARCH_HAVE_CRC_CRYPTO" +fi if test "$cuda" = "yes" ; then output_sym "CONFIG_CUDA" fi diff --git a/crc/crc32c-arm64.c b/crc/crc32c-arm64.c index 08177ba6..11bfe5d5 100644 --- a/crc/crc32c-arm64.c +++ b/crc/crc32c-arm64.c @@ -1,4 +1,9 @@ #include "crc32c.h" +#include "../os/os.h" + +bool crc32c_arm64_available = false; + +#ifdef ARCH_HAVE_CRC_CRYPTO #define CRC32C3X8(ITR) \ crc1 = __crc32cd(crc1, *((const uint64_t *)data + 42*1 + (ITR)));\ @@ -15,15 +20,6 @@ CRC32C3X8((ITR)*7+6) \ } while(0) -#ifndef HWCAP_CRC32 -#define HWCAP_CRC32 (1 << 7) -#endif /* HWCAP_CRC32 */ - -bool crc32c_arm64_available = false; - -#ifdef ARCH_HAVE_ARM64_CRC_CRYPTO - -#include #include #include @@ -102,13 +98,10 @@ uint32_t crc32c_arm64(unsigned char const *data, unsigned long length) void crc32c_arm64_probe(void) { - unsigned long hwcap; - if (!crc32c_probed) { - hwcap = getauxval(AT_HWCAP); - crc32c_arm64_available = (hwcap & HWCAP_CRC32) != 0; + crc32c_arm64_available = os_cpu_has(CPU_ARM64_CRC32C); crc32c_probed = true; } } -#endif /* ARCH_HAVE_ARM64_CRC_CRYPTO */ +#endif /* ARCH_HAVE_CRC_CRYPTO */ diff --git a/crc/crc32c.h b/crc/crc32c.h index 60f60141..08755cc8 100644 --- a/crc/crc32c.h +++ b/crc/crc32c.h @@ -27,7 +27,7 @@ extern uint32_t crc32c_sw(unsigned char const *, unsigned long); extern bool crc32c_arm64_available; extern bool crc32c_intel_available; -#ifdef ARCH_HAVE_ARM64_CRC_CRYPTO +#ifdef ARCH_HAVE_CRC_CRYPTO extern uint32_t crc32c_arm64(unsigned char const *, unsigned long); extern void crc32c_arm64_probe(void); #else @@ -35,7 +35,7 @@ extern void crc32c_arm64_probe(void); static inline void crc32c_arm64_probe(void) { } -#endif +#endif /* ARCH_HAVE_CRC_CRYPTO */ #ifdef ARCH_HAVE_SSE4_2 extern uint32_t crc32c_intel(unsigned char const *, unsigned long); diff --git a/os/os-linux.h b/os/os-linux.h index 894dc850..1d400a0d 100644 --- a/os/os-linux.h +++ b/os/os-linux.h @@ -19,6 +19,13 @@ #include #include +#ifdef ARCH_HAVE_CRC_CRYPTO +#include +#ifndef HWCAP_CRC32 +#define HWCAP_CRC32 (1 << 7) +#endif /* HWCAP_CRC32 */ +#endif /* ARCH_HAVE_CRC_CRYPTO */ + #include "./os-linux-syscall.h" #include "binject.h" #include "../file.h" @@ -410,4 +417,24 @@ static inline bool fio_fallocate(struct fio_file *f, uint64_t offset, } #endif +#define FIO_HAVE_CPU_HAS +static inline bool os_cpu_has(cpu_features feature) +{ + bool have_feature; + unsigned long fio_unused hwcap; + + switch (feature) { +#ifdef ARCH_HAVE_CRC_CRYPTO + case CPU_ARM64_CRC32C: + hwcap = getauxval(AT_HWCAP); + have_feature = (hwcap & HWCAP_CRC32) != 0; + break; +#endif + default: + have_feature = false; + } + + return have_feature; +} + #endif diff --git a/os/os.h b/os/os.h index 95ed7cf2..becc4103 100644 --- a/os/os.h +++ b/os/os.h @@ -27,6 +27,10 @@ enum { os_nr, }; +typedef enum { + CPU_ARM64_CRC32C, +} cpu_features; + /* IWYU pragma: begin_exports */ #if defined(__ANDROID__) #include "os-android.h" @@ -387,4 +391,11 @@ static inline bool fio_fallocate(struct fio_file *f, uint64_t offset, uint64_t l # define FIO_HAVE_ANY_FALLOCATE #endif +#ifndef FIO_HAVE_CPU_HAS +static inline bool os_cpu_has(cpu_features feature) +{ + return false; +} +#endif + #endif -- 2.25.1