Auto-detect whether to use hw assisted crc32c
Little point in separating the two. If the hardware assisted
crypto is available, always use it.
Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/crc/crc32c-intel.c b/crc/crc32c-intel.c
index 5040efe..8a6e6dc 100644
--- a/crc/crc32c-intel.c
+++ b/crc/crc32c-intel.c
@@ -18,6 +18,8 @@
* Volume 2A: Instruction Set Reference, A-M
*/
+int crc32c_intel_available = 0;
+
#ifdef ARCH_HAVE_SSE4_2
#if BITS_PER_LONG == 64
@@ -28,6 +30,8 @@
#define SCALE_F 4
#endif
+static int crc32c_probed;
+
static uint32_t crc32c_intel_le_hw_byte(uint32_t crc, unsigned char const *data,
unsigned long length)
{
@@ -90,14 +94,17 @@
: "eax", "ebx", "ecx", "edx");
}
-int crc32c_intel_works(void)
+void crc32c_intel_probe(void)
{
- unsigned int eax, ebx, ecx, edx;
+ if (!crc32c_probed) {
+ unsigned int eax, ebx, ecx, edx;
- eax = 1;
+ eax = 1;
- do_cpuid(&eax, &ebx, &ecx, &edx);
- return (ecx & (1 << 20)) != 0;
+ do_cpuid(&eax, &ebx, &ecx, &edx);
+ crc32c_intel_available = (ecx & (1 << 20)) != 0;
+ crc32c_probed = 1;
+ }
}
#endif /* ARCH_HAVE_SSE */
diff --git a/crc/crc32c.c b/crc/crc32c.c
index 8bbea68..b830b9f 100644
--- a/crc/crc32c.c
+++ b/crc/crc32c.c
@@ -113,7 +113,7 @@
* crc using table.
*/
-uint32_t crc32c(unsigned char const *data, unsigned long length)
+uint32_t crc32c_sw(unsigned char const *data, unsigned long length)
{
uint32_t crc = ~0;
diff --git a/crc/crc32c.h b/crc/crc32c.h
index 596fd6c..46c1063 100644
--- a/crc/crc32c.h
+++ b/crc/crc32c.h
@@ -20,17 +20,25 @@
#include "../arch/arch.h"
-extern uint32_t crc32c(unsigned char const *, unsigned long);
+extern uint32_t crc32c_sw(unsigned char const *, unsigned long);
+extern int crc32c_intel_available;
#ifdef ARCH_HAVE_SSE4_2
extern uint32_t crc32c_intel(unsigned char const *, unsigned long);
-extern int crc32c_intel_works(void);
+extern void crc32c_intel_probe(void);
#else
-#define crc32c_intel crc32c
-static inline int crc32c_intel_works(void)
+#define crc32c_intel crc32c_sw
+static inline void crc32c_intel_probe(void)
{
- return 0;
}
#endif
+static inline uint32_t crc32c(unsigned char const *buf, unsigned long len)
+{
+ if (crc32c_intel_available)
+ return crc32c_intel(buf, len);
+
+ return crc32c_sw(buf, len);
+}
+
#endif
diff --git a/options.c b/options.c
index bd8141a..d777efc 100644
--- a/options.c
+++ b/options.c
@@ -245,12 +245,9 @@
{
struct thread_data *td = data;
- if (td->o.verify != VERIFY_CRC32C_INTEL)
- return 0;
-
- if (!crc32c_intel_works()) {
- log_info("fio: System does not support hw accelerated crc32c. Falling back to sw crc32c.\n");
- td->o.verify = VERIFY_CRC32C;
+ if (td->o.verify == VERIFY_CRC32C_INTEL ||
+ td->o.verify == VERIFY_CRC32C) {
+ crc32c_intel_probe();
}
return 0;
@@ -1482,12 +1479,12 @@
.help = "Use crc32 checksums for verification",
},
{ .ival = "crc32c-intel",
- .oval = VERIFY_CRC32C_INTEL,
- .help = "Use hw crc32c checksums for verification",
+ .oval = VERIFY_CRC32C,
+ .help = "Use crc32c checksums for verification (hw assisted, if available)",
},
{ .ival = "crc32c",
.oval = VERIFY_CRC32C,
- .help = "Use crc32c checksums for verification",
+ .help = "Use crc32c checksums for verification (hw assisted, if available)",
},
{ .ival = "crc16",
.oval = VERIFY_CRC16,
diff --git a/verify.c b/verify.c
index 8bf14ae..d6abb98 100644
--- a/verify.c
+++ b/verify.c
@@ -551,10 +551,7 @@
dprint(FD_VERIFY, "crc32c verify io_u %p, len %u\n", vc->io_u, hdr->len);
- if (hdr->verify_type == VERIFY_CRC32C_INTEL)
- c = crc32c_intel(p, hdr->len - hdr_size(hdr));
- else
- c = crc32c(p, hdr->len - hdr_size(hdr));
+ c = crc32c(p, hdr->len - hdr_size(hdr));
if (c == vh->crc32)
return 0;
@@ -833,10 +830,7 @@
{
struct vhdr_crc32 *vh = hdr_priv(hdr);
- if (hdr->verify_type == VERIFY_CRC32C_INTEL)
- vh->crc32 = crc32c_intel(p, len);
- else
- vh->crc32 = crc32c(p, len);
+ vh->crc32 = crc32c(p, len);
}
static void fill_crc64(struct verify_header *hdr, void *p, unsigned int len)