From 90059d65bde4804e4da07401ad6902c1d956b592 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 30 Jul 2007 09:33:12 +0200 Subject: [PATCH] Add verify_pattern option Signed-off-by: Jens Axboe --- HOWTO | 8 ++++++++ fio.h | 2 ++ fls.h | 41 +++++++++++++++++++++++++++++++++++++++++ options.c | 26 ++++++++++++++++++++++++++ verify.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 fls.h diff --git a/HOWTO b/HOWTO index a07cf884..58e12819 100644 --- a/HOWTO +++ b/HOWTO @@ -612,6 +612,14 @@ verify_interval=siint Write the verification header at a finer granularity than the blocksize. It will be written for chunks the size of header_interval. blocksize should divide this evenly. + +verify_pattern=int If set, fio will fill the io buffers with this + pattern. Fio defaults to filling with totally random + bytes, but sometimes it's interesting to fill with a known + pattern for io verification purposes. Depending on the + width of the pattern, fio will fill 1/2/3/4 bytes of the + buffer at the time. The verify_pattern cannot be larger than + a 32-bit quantity. stonewall Wait for preceeding jobs in the job file to exit, before starting this one. Can be used to insert serialization diff --git a/fio.h b/fio.h index eb36d1cf..2ca800bf 100644 --- a/fio.h +++ b/fio.h @@ -397,6 +397,8 @@ struct thread_options { unsigned int verifysort; unsigned int verify_interval; unsigned int verify_offset; + unsigned int verify_pattern; + unsigned int verify_pattern_bytes; unsigned int use_thread; unsigned int unlink; unsigned int do_disk_util; diff --git a/fls.h b/fls.h new file mode 100644 index 00000000..850859bc --- /dev/null +++ b/fls.h @@ -0,0 +1,41 @@ +#ifndef _ASM_GENERIC_BITOPS_FLS_H_ +#define _ASM_GENERIC_BITOPS_FLS_H_ + +/** + * fls - find last (most-significant) bit set + * @x: the word to search + * + * This is defined the same way as ffs. + * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. + */ + +static inline int fls(int x) +{ + int r = 32; + + if (!x) + return 0; + if (!(x & 0xffff0000u)) { + x <<= 16; + r -= 16; + } + if (!(x & 0xff000000u)) { + x <<= 8; + r -= 8; + } + if (!(x & 0xf0000000u)) { + x <<= 4; + r -= 4; + } + if (!(x & 0xc0000000u)) { + x <<= 2; + r -= 2; + } + if (!(x & 0x80000000u)) { + x <<= 1; + r -= 1; + } + return r; +} + +#endif /* _ASM_GENERIC_BITOPS_FLS_H_ */ diff --git a/options.c b/options.c index 5a63f638..3112d65e 100644 --- a/options.c +++ b/options.c @@ -8,6 +8,7 @@ #include "fio.h" #include "parse.h" +#include "fls.h" #define td_var_offset(var) ((size_t) &((struct thread_options *)0)->var) @@ -216,6 +217,24 @@ static int str_verify_offset_cb(void *data, unsigned int *off) return 0; } +static int str_verify_pattern_cb(void *data, unsigned int *off) +{ + struct thread_data *td = data; + unsigned int msb; + + msb = fls(*off); + if (msb <= 8) + td->o.verify_pattern_bytes = 1; + else if (msb <= 16) + td->o.verify_pattern_bytes = 2; + else if (msb <= 24) + td->o.verify_pattern_bytes = 3; + else + td->o.verify_pattern_bytes = 4; + + td->o.verify_pattern = *off; + return 0; +} #define __stringify_1(x) #x #define __stringify(x) __stringify_1(x) @@ -630,6 +649,13 @@ static struct fio_option options[] = { .def = "0", .cb = str_verify_offset_cb, }, + { + .name = "verify_pattern", + .type = FIO_OPT_INT, + .cb = str_verify_pattern_cb, + .maxval = UINT_MAX, + .help = "Fill pattern for IO buffers", + }, { .name = "write_iolog", .type = FIO_OPT_STR_STORE, diff --git a/verify.c b/verify.c index d98dfcf4..5770b461 100644 --- a/verify.c +++ b/verify.c @@ -8,8 +8,7 @@ #include "fio.h" -static void fill_random_bytes(struct thread_data *td, - void *p, unsigned int len) +static void fill_random_bytes(struct thread_data *td, void *p, unsigned int len) { unsigned int todo; int r; @@ -32,9 +31,52 @@ static void fill_random_bytes(struct thread_data *td, } } -void memswp(void* buf1, void* buf2, unsigned int len) +static void fill_pattern(struct thread_data *td, void *p, unsigned int len) +{ + switch (td->o.verify_pattern_bytes) { + case 0: + fill_random_bytes(td, p, len); + break; + case 1: + memset(p, td->o.verify_pattern, len); + break; + case 2: + case 3: + case 4: { + unsigned int pattern = td->o.verify_pattern; + unsigned int i = 0; + unsigned char c1, c2, c3, c4; + unsigned char *b = p; + + c1 = pattern & 0xff; + pattern >>= 8; + c2 = pattern & 0xff; + pattern >>= 8; + c3 = pattern & 0xff; + pattern >>= 8; + c4 = pattern & 0xff; + + while (i < len) { + b[i++] = c1; + if (i == len) + break; + b[i++] = c2; + if (td->o.verify_pattern_bytes == 2 || i == len) + continue; + b[i++] = c3; + if (td->o.verify_pattern_bytes == 3 || i == len) + continue; + b[i++] = c4; + } + break; + } + } +} + +static void memswp(void* buf1, void* buf2, unsigned int len) { struct verify_header swap; + memcpy(&swap, buf1, len); memcpy(buf1, buf2, len); memcpy(buf2, &swap, len); @@ -254,7 +296,7 @@ void populate_verify_io_u(struct thread_data *td, struct io_u *io_u) if (td->o.verify == VERIFY_NULL) return; - fill_random_bytes(td, p, io_u->buflen); + fill_pattern(td, p, io_u->buflen); hdr_inc = io_u->buflen; if (td->o.verify_interval) -- 2.25.1