#include <inttypes.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
#include "crc32c.h"
/*
return crc;
}
-#endif /* ARCH_HAVE_SSE */
+static void sig_ill(int sig)
+{
+}
+
+static void crc32c_test(void)
+{
+ unsigned char buf[4] = { 1, 2, 3, 4 };
+ struct sigaction act;
+
+ /*
+ * Check if hw accelerated crc32c is available
+ */
+ memset(&act, 0, sizeof(act));
+ act.sa_handler = sig_ill;
+ act.sa_flags = SA_RESETHAND;
+ sigaction(SIGILL, &act, NULL);
+
+ (void) crc32c_intel(buf, sizeof(buf));
+}
+
+int crc32c_intel_works(void)
+{
+ if (!fork()) {
+ crc32c_test();
+ exit(0);
+ } else {
+ int status;
+ wait(&status);
+ return !WIFSIGNALED(status);
+ }
+}
+
+#endif /* ARCH_HAVE_SSE */
#ifdef ARCH_HAVE_SSE
extern uint32_t crc32c_intel(unsigned char const *, unsigned long);
+extern int crc32c_intel_works(void);
#else
#define crc32c_intel crc32c
+static inline int crc32c_intel_works(void)
+{
+ return 0;
+}
#endif
#endif
}
}
-static void sig_ill(int fio_unused sig)
-{
- if (!threads)
- return;
-
- log_err("fio: system does not support the sse4.2 instruction for crc32c-intel.\nUse crc32c instead.\n");
- terminate_threads(TERMINATE_ALL);
-}
-
static void set_sig_handlers(void)
{
struct sigaction act;
act.sa_flags = SA_RESTART;
sigaction(SIGINT, &act, NULL);
- memset(&act, 0, sizeof(act));
- act.sa_handler = sig_ill;
- act.sa_flags = SA_RESETHAND;
- sigaction(SIGILL, &act, NULL);
-
memset(&act, 0, sizeof(act));
act.sa_handler = sig_quit;
act.sa_flags = SA_RESTART;
#include "lib/fls.h"
#include "options.h"
+#include "crc/crc32c.h"
+
/*
* Check if mmap/mmaphuge has a :/foo/bar/file at the end. If so, return that.
*/
return 0;
}
+static int str_verify_cb(void *data, const char *mem)
+{
+ 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;
+ }
+
+ return 0;
+}
+
static int fio_clock_source_cb(void *data, const char *str)
{
struct thread_data *td = data;
.type = FIO_OPT_STR,
.off1 = td_var_offset(verify),
.help = "Verify data written",
+ .cb = str_verify_cb,
.def = "0",
.posval = {
{ .ival = "0",