The following changes since commit fc0b830f419bf64fff6fee91d1d3b9e94da11091: Fix tabbing and comment characters in Windows code. (2012-02-20 21:03:48 +0100) are available in the git repository at: git://git.kernel.dk/fio.git master Bruce Cran (2): stat() doesn't work with devices on Windows, so move check for '\\.\' earlier. Implement sigaction for Windows. Daniel Ehrenberg (1): flow: Fixing uninitialized variable Jens Axboe (3): Add checksum to verify_header Auto-detect whether to use hw assisted crc32c Use crc32c for the verify_header checksum crc/crc32c-intel.c | 17 ++++++++++++----- crc/crc32c.c | 2 +- crc/crc32c.h | 18 +++++++++++++----- filesetup.c | 9 ++++++--- flow.c | 2 +- options.c | 15 ++++++--------- os/windows/posix.c | 13 +++++++++++-- verify.c | 42 +++++++++++++++++++++++++++++++----------- verify.h | 12 ++++++++---- 9 files changed, 89 insertions(+), 41 deletions(-) --- Diff of recent changes: 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 @@ static void do_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, : "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 @@ static const uint32_t crc32c_table[256] = { * 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/filesetup.c b/filesetup.c index cf5ec8e..446eeaf 100644 --- a/filesetup.c +++ b/filesetup.c @@ -926,10 +926,13 @@ static void get_file_type(struct fio_file *f) else f->filetype = FIO_TYPE_FILE; + /* \\.\ is the device namespace in Windows, where every file is + * a block device */ + if (strncmp(f->file_name, "\\\\.\\", 4) == 0) + f->filetype = FIO_TYPE_BD; + if (!stat(f->file_name, &sb)) { - /* \\.\ is the device namespace in Windows, where every file is - * a block device */ - if (S_ISBLK(sb.st_mode) || strncmp(f->file_name, "\\\\.\\", 4) == 0) + if (S_ISBLK(sb.st_mode)) f->filetype = FIO_TYPE_BD; else if (S_ISCHR(sb.st_mode)) f->filetype = FIO_TYPE_CHAR; diff --git a/flow.c b/flow.c index e5c4a40..bf5eeec 100644 --- a/flow.c +++ b/flow.c @@ -36,7 +36,7 @@ int flow_threshold_exceeded(struct thread_data *td) static struct fio_flow *flow_get(unsigned int id) { - struct fio_flow *flow; + struct fio_flow *flow = NULL; struct flist_head *n; fio_mutex_down(flow_lock); diff --git a/options.c b/options.c index bd8141a..d777efc 100644 --- a/options.c +++ b/options.c @@ -245,12 +245,9 @@ 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; + if (td->o.verify == VERIFY_CRC32C_INTEL || + td->o.verify == VERIFY_CRC32C) { + crc32c_intel_probe(); } return 0; @@ -1482,12 +1479,12 @@ static struct fio_option options[FIO_MAX_OPTS] = { .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/os/windows/posix.c b/os/windows/posix.c index ea3736d..ba7abb5 100755 --- a/os/windows/posix.c +++ b/os/windows/posix.c @@ -124,8 +124,17 @@ void syslog(int priority, const char *message, ... /* argument */) int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { - errno = ENOSYS; - return (-1); + int rc = 0; + void (*prev_handler)(int); + + prev_handler = signal(sig, act->sa_handler); + if (oact != NULL) + oact->sa_handler = prev_handler; + + if (prev_handler == SIG_ERR) + rc = -1; + + return rc; } int lstat(const char * path, struct stat * buf) diff --git a/verify.c b/verify.c index eb8eddc..f40d7e1 100644 --- a/verify.c +++ b/verify.c @@ -551,10 +551,7 @@ static int verify_io_u_crc32c(struct verify_header *hdr, struct vcont *vc) 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; @@ -649,6 +646,19 @@ static int verify_trimmed_io_u(struct thread_data *td, struct io_u *io_u) return ret; } +static int verify_hdr_crc(struct verify_header *hdr) +{ + void *p = hdr; + uint32_t crc; + + crc = crc32c(p, sizeof(*hdr) - sizeof(hdr->crc32)); + if (crc == hdr->crc32) + return 1; + + log_err("fio: verify header crc %x, calculated %x\n", hdr->crc32, crc); + return 0; +} + int verify_io_u(struct thread_data *td, struct io_u *io_u) { struct verify_header *hdr; @@ -682,9 +692,18 @@ int verify_io_u(struct thread_data *td, struct io_u *io_u) memswp(p, p + td->o.verify_offset, header_size); hdr = p; - if (hdr->fio_magic != FIO_HDR_MAGIC) { + if (hdr->fio_magic == FIO_HDR_MAGIC2) { + if (!verify_hdr_crc(hdr)) { + log_err("fio: bad crc on verify header.\n"); + return EILSEQ; + } + } else if (hdr->fio_magic == FIO_HDR_MAGIC) { + log_err("fio: v1 headers no longer supported.\n"); + log_err("fio: re-run the write workload.\n"); + return EILSEQ; + } else { log_err("verify: bad magic header %x, wanted %x at file %s offset %llu, length %u\n", - hdr->fio_magic, FIO_HDR_MAGIC, + hdr->fio_magic, FIO_HDR_MAGIC2, io_u->file->file_name, io_u->offset + hdr_num * hdr->len, hdr->len); return EILSEQ; @@ -811,10 +830,7 @@ static void fill_crc32c(struct verify_header *hdr, void *p, unsigned int len) { 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) @@ -844,10 +860,14 @@ static void populate_hdr(struct thread_data *td, struct io_u *io_u, p = (void *) hdr; - hdr->fio_magic = FIO_HDR_MAGIC; + hdr->fio_magic = FIO_HDR_MAGIC2; hdr->len = header_len; hdr->verify_type = td->o.verify; + hdr->pad1 = 0; hdr->rand_seed = io_u->rand_seed; + hdr->pad2 = 0; + hdr->crc32 = crc32c(p, sizeof(*hdr) - sizeof(hdr->crc32)); + data_len = header_len - hdr_size(hdr); data = p + hdr_size(hdr); diff --git a/verify.h b/verify.h index 49ce417..ec7365c 100644 --- a/verify.h +++ b/verify.h @@ -4,6 +4,7 @@ #include <stdint.h> #define FIO_HDR_MAGIC 0xf00baaef +#define FIO_HDR_MAGIC2 0xf00dbeef enum { VERIFY_NONE = 0, /* no verification */ @@ -28,10 +29,13 @@ enum { * data. */ struct verify_header { - unsigned int fio_magic; - unsigned int len; - unsigned int verify_type; - unsigned long rand_seed; + uint32_t fio_magic; + uint32_t len; + uint32_t verify_type; + uint32_t pad1; + uint64_t rand_seed; + uint32_t pad2; + uint32_t crc32; }; struct vhdr_md5 { -- To unsubscribe from this list: send the line "unsubscribe fio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html