From: Jens Axboe Date: Mon, 21 Jun 2010 13:08:17 +0000 (+0200) Subject: Auto-detect missing hw support for crc32c and fallback to software X-Git-Tag: fio-1.41.3~3 X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=5d7c5d348d66794fd5e8aa3090f582358e6c5017;p=fio.git Auto-detect missing hw support for crc32c and fallback to software Signed-off-by: Jens Axboe --- diff --git a/crc/crc32c-intel.c b/crc/crc32c-intel.c index cec5ad5d..fc106fa5 100644 --- a/crc/crc32c-intel.c +++ b/crc/crc32c-intel.c @@ -1,4 +1,10 @@ #include +#include +#include +#include +#include +#include +#include #include "crc32c.h" /* @@ -68,5 +74,37 @@ uint32_t crc32c_intel(unsigned char const *data, unsigned long length) 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 */ diff --git a/crc/crc32c.h b/crc/crc32c.h index 0976261a..50f3665f 100644 --- a/crc/crc32c.h +++ b/crc/crc32c.h @@ -24,8 +24,13 @@ extern uint32_t crc32c(unsigned char const *, unsigned long); #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 diff --git a/fio.c b/fio.c index 4d260600..b2a08bf0 100644 --- a/fio.c +++ b/fio.c @@ -142,15 +142,6 @@ static void sig_int(int sig) } } -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; @@ -165,11 +156,6 @@ static void set_sig_handlers(void) 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; diff --git a/options.c b/options.c index f470b453..fb187489 100644 --- a/options.c +++ b/options.c @@ -16,6 +16,8 @@ #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. */ @@ -225,6 +227,21 @@ static int str_mem_cb(void *data, const char *mem) 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; @@ -1298,6 +1315,7 @@ static struct fio_option options[FIO_MAX_OPTS] = { .type = FIO_OPT_STR, .off1 = td_var_offset(verify), .help = "Verify data written", + .cb = str_verify_cb, .def = "0", .posval = { { .ival = "0",