aarch64: refactor HW ARM CRC32c detection
authorSitsofe Wheeler <sitsofe@yahoo.com>
Wed, 28 Mar 2018 14:49:14 +0000 (15:49 +0100)
committerSitsofe Wheeler <sitsofe@yahoo.com>
Fri, 30 Mar 2018 15:16:48 +0000 (16:16 +0100)
- 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 <sitsofe@yahoo.com>
arch/arch-aarch64.h
configure
crc/crc32c-arm64.c
crc/crc32c.h
os/os-linux.h
os/os.h

index 0912a86f63c4598ee9d673fe3a80da9f2d9d5065..2a86cc5ab4d9b9cb1bef2dcf5d0aab24bfc38fb8 100644 (file)
@@ -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
index f6358630562229029bb409ee98fbe94df939f7d1..1d8c7f18bb0bbb2ad35b30735693519679a2cb6f 100755 (executable)
--- 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 <<EOF
-#include <sys/auxv.h>
 #include <arm_acle.h>
 #include <arm_neon.h>
+#include <sys/auxv.h>
 
 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
index 08177ba6cff66e78884eaed9148c6909a67097b8..11bfe5d5c0b212ee6548a4a473eaf00720fdf11b 100644 (file)
@@ -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)));\
        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 <sys/auxv.h>
 #include <arm_acle.h>
 #include <arm_neon.h>
 
@@ -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 */
index 60f60141966e90211f277fc5ab6dec563145f83e..08755cc8cfafc37f565b65de2a4677c8a5938a87 100644 (file)
@@ -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);
index 894dc850904f0717d745ac61ce2805e349aff210..1d400a0d3aed1d10a31e564513ff19a1d92669f3 100644 (file)
 #include <linux/fs.h>
 #include <scsi/sg.h>
 
+#ifdef ARCH_HAVE_CRC_CRYPTO
+#include <sys/auxv.h>
+#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 95ed7cf2d7cd169c173d9dd971db01ac6b9d734b..becc41033e4a8c8db674abf78b2c9ed42f003c69 100644 (file)
--- 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