* Patch to write patterns > 4 bytes @ 2009-10-27 0:10 Radha Ramachandran 2009-10-27 7:55 ` Jens Axboe 0 siblings, 1 reply; 4+ messages in thread From: Radha Ramachandran @ 2009-10-27 0:10 UTC (permalink / raw) To: Jens Axboe, fio Hi, This is the patch I have to write/read/verify hex patterns of size > 4 bytes. I have tested these on hard drives and did not see any performance change. Iam assuming the performance drop if any might show up in the read phase for probably solid state drives and maybe it can be worked around using the asynchronous verify flag. Thanks -radha diff --git a/HOWTO b/HOWTO index aa10dbc..cdd6473 100644 --- a/HOWTO +++ b/HOWTO @@ -846,13 +846,14 @@ verify_interval=int Write the verification header at a finer granularity size of header_interval. blocksize should divide this evenly. -verify_pattern=int If set, fio will fill the io buffers with this +verify_pattern=str 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. + buffer at the time(it can be either a decimal or a hex number). + The verify_pattern if larger than a 32-bit quantity has to + be a hex number that starts with either "0x" or "0X". verify_fatal=bool Normally fio will keep checking the entire contents before quitting on a block verification failure. If this diff --git a/fio.h b/fio.h index 049692d..e4ed76f 100644 --- a/fio.h +++ b/fio.h @@ -63,6 +63,8 @@ enum fio_memtype { #define FIO_IO_U_LAT_U_NR 10 #define FIO_IO_U_LAT_M_NR 12 +#define MAX_PATTERN_SIZE 512 + struct thread_stat { char *name; char *verror; @@ -175,7 +177,7 @@ struct thread_options { unsigned int verifysort; unsigned int verify_interval; unsigned int verify_offset; - unsigned int verify_pattern; + char verify_pattern[MAX_PATTERN_SIZE]; unsigned int verify_pattern_bytes; unsigned int verify_fatal; unsigned int verify_async; diff --git a/options.c b/options.c index b5abd74..5b88255 100644 --- a/options.c +++ b/options.c @@ -33,6 +33,26 @@ static char *get_opt_postfix(const char *str) return strdup(p); } +static int converthexchartoint(char a) +{ + int base; + + switch(a) { + case '0'...'9': + base = '0'; + break; + case 'A'...'F': + base = 'A' - 10; + break; + case 'a'...'f': + base = 'a' - 10; + break; + default: + base = 0; + } + return (a - base); +} + static int bs_cmp(const void *p1, const void *p2) { const struct bssplit *bsp1 = p1; @@ -566,22 +586,45 @@ static int str_verify_offset_cb(void *data, unsigned int *off) return 0; } -static int str_verify_pattern_cb(void *data, unsigned int *off) +static int str_verify_pattern_cb(void *data, const char *input) { 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; + long off; + int i = 0, j = 0, len, k, base = 10; + char* loc1, * loc2; + + loc1 = strstr(input, "0x"); + loc2 = strstr(input, "0X"); + if (loc1 || loc2) + base = 16; + off = strtol(input, NULL, base); + if (off != LONG_MAX || errno != ERANGE) { + while (off) { + td->o.verify_pattern[i] = off & 0xff; + off >>= 8; + i++; + } + } else { + len = strlen(input); + k = len - 1; + if (base == 16) { + if (loc1) + j = loc1 - input + 2; + else + j = loc2 - input + 2; + } else + return 1; + if (len - j < MAX_PATTERN_SIZE * 2) { + while (k >= j) { + off = converthexchartoint(input[k--]); + if (k >= j) + off += (converthexchartoint(input[k--]) + * 16); + td->o.verify_pattern[i++] = (char) off; + } + } + } + td->o.verify_pattern_bytes = i; return 0; } @@ -1263,7 +1306,7 @@ static struct fio_option options[] = { }, { .name = "verify_pattern", - .type = FIO_OPT_INT, + .type = FIO_OPT_STR, .cb = str_verify_pattern_cb, .help = "Fill pattern for IO buffers", .parent = "verify", diff --git a/verify.c b/verify.c index 193e171..faa5684 100644 --- a/verify.c +++ b/verify.c @@ -53,38 +53,21 @@ static void fill_pattern(struct thread_data *td, void *p, unsigned int len) break; case 1: dprint(FD_VERIFY, "fill verify pattern b=0 len=%u\n", len); - memset(p, td->o.verify_pattern, len); + memset(p, td->o.verify_pattern[0], 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; + default: { + unsigned int i = 0, size = 0; unsigned char *b = p; dprint(FD_VERIFY, "fill verify pattern b=%d len=%u\n", td->o.verify_pattern_bytes, len); - 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; + size = td->o.verify_pattern_bytes; + if (size > (len - i)) + size = len - i; + memcpy(b+i, td->o.verify_pattern, size); + i += size; } break; } @@ -420,24 +403,18 @@ static unsigned int hweight8(unsigned int w) return (res + (res >> 4)) & 0x0F; } -int verify_io_u_pattern(unsigned long pattern, unsigned long pattern_size, +int verify_io_u_pattern(char *pattern, unsigned long pattern_size, char *buf, unsigned int len, unsigned int mod) { unsigned int i; - char split_pattern[4]; - - for (i = 0; i < 4; i++) { - split_pattern[i] = pattern & 0xff; - pattern >>= 8; - } for (i = 0; i < len; i++) { - if (buf[i] != split_pattern[mod]) { + if (buf[i] != pattern[mod]) { unsigned int bits; - bits = hweight8(buf[i] ^ split_pattern[mod]); + bits = hweight8(buf[i] ^ pattern[mod]); log_err("fio: got pattern %x, wanted %x. Bad bits %d\n", - buf[i], split_pattern[mod], bits); + buf[i], pattern[mod], bits); log_err("fio: bad pattern block offset %u\n", i); return EILSEQ; } @@ -504,10 +481,10 @@ int verify_io_u(struct thread_data *td, struct io_u *io_u) dprint(FD_VERIFY, "pattern verify io_u %p, len %u\n", io_u, hdr->len); ret = verify_io_u_pattern(td->o.verify_pattern, - td->o.verify_pattern_bytes, - p + hdr_size, - hdr_inc - hdr_size, - hdr_size % 4); + td->o.verify_pattern_bytes, + p + hdr_size, + hdr_inc - hdr_size, + hdr_size % td->o.verify_pattern_bytes); /* * Also verify the meta data, if applicable */ ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: Patch to write patterns > 4 bytes 2009-10-27 0:10 Patch to write patterns > 4 bytes Radha Ramachandran @ 2009-10-27 7:55 ` Jens Axboe 2009-10-27 18:19 ` Radha Ramachandran 0 siblings, 1 reply; 4+ messages in thread From: Jens Axboe @ 2009-10-27 7:55 UTC (permalink / raw) To: Radha Ramachandran; +Cc: fio On Mon, Oct 26 2009, Radha Ramachandran wrote: > Hi, > This is the patch I have to write/read/verify hex patterns of size > 4 bytes. > I have tested these on hard drives and did not see any performance > change. Iam assuming the performance drop if any might show up in the > read phase for probably solid state drives and maybe it can be worked > around using the asynchronous verify flag. Unfortunately, this patch is white space damaged so doesn't apply. Perhaps send it as an attachment instead? And for extra brownie points, updating the fio.1 man page as well would be good :-) -- Jens Axboe ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Patch to write patterns > 4 bytes 2009-10-27 7:55 ` Jens Axboe @ 2009-10-27 18:19 ` Radha Ramachandran 2009-10-27 19:15 ` Jens Axboe 0 siblings, 1 reply; 4+ messages in thread From: Radha Ramachandran @ 2009-10-27 18:19 UTC (permalink / raw) To: Jens Axboe; +Cc: fio [-- Attachment #1: Type: text/plain, Size: 998 bytes --] Hi Jens, Here is the git diff file. Also I fixed the fio.1 man page. -radha On Tue, Oct 27, 2009 at 12:55 AM, Jens Axboe <jens.axboe@oracle.com> wrote: > On Mon, Oct 26 2009, Radha Ramachandran wrote: >> Hi, >> This is the patch I have to write/read/verify hex patterns of size > 4 bytes. >> I have tested these on hard drives and did not see any performance >> change. Iam assuming the performance drop if any might show up in the >> read phase for probably solid state drives and maybe it can be worked >> around using the asynchronous verify flag. > > Unfortunately, this patch is white space damaged so doesn't apply. > Perhaps send it as an attachment instead? And for extra brownie points, > updating the fio.1 man page as well would be good :-) > > -- > Jens Axboe > > -- > To unsubscribe from this list: send the line "unsubscribe fio" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > [-- Attachment #2: diff.file --] [-- Type: application/octet-stream, Size: 7097 bytes --] diff --git a/HOWTO b/HOWTO index aa10dbc..cdd6473 100644 --- a/HOWTO +++ b/HOWTO @@ -846,13 +846,14 @@ verify_interval=int Write the verification header at a finer granularity size of header_interval. blocksize should divide this evenly. -verify_pattern=int If set, fio will fill the io buffers with this +verify_pattern=str 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. + buffer at the time(it can be either a decimal or a hex number). + The verify_pattern if larger than a 32-bit quantity has to + be a hex number that starts with either "0x" or "0X". verify_fatal=bool Normally fio will keep checking the entire contents before quitting on a block verification failure. If this diff --git a/fio.1 b/fio.1 index f216b4c..4445d0a 100644 --- a/fio.1 +++ b/fio.1 @@ -583,9 +583,10 @@ Write extra information about each I/O (timestamp, block number, etc.). The block number is verified. .TP .B pattern -Fill I/O buffers with a specific pattern that is used to verify. The pattern is -specified by appending `:\fIint\fR' to the parameter. \fIint\fR cannot be larger -than 32-bits. +Fill I/O buffers with a specific pattern that is used to verify. If the pattern +is < 4bytes, it can either be a decimal or a hexadecimal number. If the pattern +is > 4bytes, currently, it can only be a hexadecimal pattern starting with +either "0x" or "0X". .TP .B null Pretend to verify. Used for testing internals. diff --git a/fio.h b/fio.h index 049692d..e4ed76f 100644 --- a/fio.h +++ b/fio.h @@ -63,6 +63,8 @@ enum fio_memtype { #define FIO_IO_U_LAT_U_NR 10 #define FIO_IO_U_LAT_M_NR 12 +#define MAX_PATTERN_SIZE 512 + struct thread_stat { char *name; char *verror; @@ -175,7 +177,7 @@ struct thread_options { unsigned int verifysort; unsigned int verify_interval; unsigned int verify_offset; - unsigned int verify_pattern; + char verify_pattern[MAX_PATTERN_SIZE]; unsigned int verify_pattern_bytes; unsigned int verify_fatal; unsigned int verify_async; diff --git a/options.c b/options.c index b5abd74..5b88255 100644 --- a/options.c +++ b/options.c @@ -33,6 +33,26 @@ static char *get_opt_postfix(const char *str) return strdup(p); } +static int converthexchartoint(char a) +{ + int base; + + switch(a) { + case '0'...'9': + base = '0'; + break; + case 'A'...'F': + base = 'A' - 10; + break; + case 'a'...'f': + base = 'a' - 10; + break; + default: + base = 0; + } + return (a - base); +} + static int bs_cmp(const void *p1, const void *p2) { const struct bssplit *bsp1 = p1; @@ -566,22 +586,45 @@ static int str_verify_offset_cb(void *data, unsigned int *off) return 0; } -static int str_verify_pattern_cb(void *data, unsigned int *off) +static int str_verify_pattern_cb(void *data, const char *input) { 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; + long off; + int i = 0, j = 0, len, k, base = 10; + char* loc1, * loc2; + + loc1 = strstr(input, "0x"); + loc2 = strstr(input, "0X"); + if (loc1 || loc2) + base = 16; + off = strtol(input, NULL, base); + if (off != LONG_MAX || errno != ERANGE) { + while (off) { + td->o.verify_pattern[i] = off & 0xff; + off >>= 8; + i++; + } + } else { + len = strlen(input); + k = len - 1; + if (base == 16) { + if (loc1) + j = loc1 - input + 2; + else + j = loc2 - input + 2; + } else + return 1; + if (len - j < MAX_PATTERN_SIZE * 2) { + while (k >= j) { + off = converthexchartoint(input[k--]); + if (k >= j) + off += (converthexchartoint(input[k--]) + * 16); + td->o.verify_pattern[i++] = (char) off; + } + } + } + td->o.verify_pattern_bytes = i; return 0; } @@ -1263,7 +1306,7 @@ static struct fio_option options[] = { }, { .name = "verify_pattern", - .type = FIO_OPT_INT, + .type = FIO_OPT_STR, .cb = str_verify_pattern_cb, .help = "Fill pattern for IO buffers", .parent = "verify", diff --git a/verify.c b/verify.c index 193e171..faa5684 100644 --- a/verify.c +++ b/verify.c @@ -53,38 +53,21 @@ static void fill_pattern(struct thread_data *td, void *p, unsigned int len) break; case 1: dprint(FD_VERIFY, "fill verify pattern b=0 len=%u\n", len); - memset(p, td->o.verify_pattern, len); + memset(p, td->o.verify_pattern[0], 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; + default: { + unsigned int i = 0, size = 0; unsigned char *b = p; dprint(FD_VERIFY, "fill verify pattern b=%d len=%u\n", td->o.verify_pattern_bytes, len); - 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; + size = td->o.verify_pattern_bytes; + if (size > (len - i)) + size = len - i; + memcpy(b+i, td->o.verify_pattern, size); + i += size; } break; } @@ -420,24 +403,18 @@ static unsigned int hweight8(unsigned int w) return (res + (res >> 4)) & 0x0F; } -int verify_io_u_pattern(unsigned long pattern, unsigned long pattern_size, +int verify_io_u_pattern(char *pattern, unsigned long pattern_size, char *buf, unsigned int len, unsigned int mod) { unsigned int i; - char split_pattern[4]; - - for (i = 0; i < 4; i++) { - split_pattern[i] = pattern & 0xff; - pattern >>= 8; - } for (i = 0; i < len; i++) { - if (buf[i] != split_pattern[mod]) { + if (buf[i] != pattern[mod]) { unsigned int bits; - bits = hweight8(buf[i] ^ split_pattern[mod]); + bits = hweight8(buf[i] ^ pattern[mod]); log_err("fio: got pattern %x, wanted %x. Bad bits %d\n", - buf[i], split_pattern[mod], bits); + buf[i], pattern[mod], bits); log_err("fio: bad pattern block offset %u\n", i); return EILSEQ; } @@ -504,10 +481,10 @@ int verify_io_u(struct thread_data *td, struct io_u *io_u) dprint(FD_VERIFY, "pattern verify io_u %p, len %u\n", io_u, hdr->len); ret = verify_io_u_pattern(td->o.verify_pattern, - td->o.verify_pattern_bytes, - p + hdr_size, - hdr_inc - hdr_size, - hdr_size % 4); + td->o.verify_pattern_bytes, + p + hdr_size, + hdr_inc - hdr_size, + hdr_size % td->o.verify_pattern_bytes); /* * Also verify the meta data, if applicable */ ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: Patch to write patterns > 4 bytes 2009-10-27 18:19 ` Radha Ramachandran @ 2009-10-27 19:15 ` Jens Axboe 0 siblings, 0 replies; 4+ messages in thread From: Jens Axboe @ 2009-10-27 19:15 UTC (permalink / raw) To: Radha Ramachandran; +Cc: fio On Tue, Oct 27 2009, Radha Ramachandran wrote: > Hi Jens, > Here is the git diff file. > Also I fixed the fio.1 man page. Thanks, applied! -- Jens Axboe ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2009-10-27 19:15 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-10-27 0:10 Patch to write patterns > 4 bytes Radha Ramachandran 2009-10-27 7:55 ` Jens Axboe 2009-10-27 18:19 ` Radha Ramachandran 2009-10-27 19:15 ` Jens Axboe
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox