From 44cbc6daaae3674ea5d0a113b66596ca24f372e0 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 21 Jan 2013 09:47:03 -0700 Subject: [PATCH 1/1] verify: add new experimental mode that requires no meta data Should work fine, but we need to account and track trims to know which blocks NOT to verify (or verify as zero). Signed-off-by: Jens Axboe --- backend.c | 46 +++++++++++++++++++++++++++++++++------------- fio.h | 1 + io_u.c | 12 ++++++++++-- libfio.c | 2 +- 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/backend.c b/backend.c index 7cebf4d3..507faa99 100644 --- a/backend.c +++ b/backend.c @@ -393,11 +393,12 @@ static int break_on_this_error(struct thread_data *td, enum fio_ddir ddir, * The main verify engine. Runs over the writes we previously submitted, * reads the blocks back in, and checks the crc/md5 of the data. */ -static void do_verify(struct thread_data *td) +static void do_verify(struct thread_data *td, uint64_t verify_bytes) { struct fio_file *f; struct io_u *io_u; int ret, min_events; + uint64_t io_bytes; unsigned int i; dprint(FD_VERIFY, "starting loop\n"); @@ -421,6 +422,7 @@ static void do_verify(struct thread_data *td) td_set_runstate(td, TD_VERIFYING); io_u = NULL; + io_bytes = 0; while (!td->terminate) { enum fio_ddir ddir; int ret2, full; @@ -438,18 +440,27 @@ static void do_verify(struct thread_data *td) if (flow_threshold_exceeded(td)) continue; - io_u = __get_io_u(td); - if (!io_u) - break; + if (!td->o.experimental_verify) { + io_u = __get_io_u(td); + if (!io_u) + break; - if (get_next_verify(td, io_u)) { - put_io_u(td, io_u); - break; - } + if (get_next_verify(td, io_u)) { + put_io_u(td, io_u); + break; + } - if (td_io_prep(td, io_u)) { - put_io_u(td, io_u); - break; + if (td_io_prep(td, io_u)) { + put_io_u(td, io_u); + break; + } + } else { + io_u = get_io_u(td); + if (!io_u) + break; + + if (io_u->buflen + io_bytes > verify_bytes) + break; } if (td->o.verify_async) @@ -480,6 +491,7 @@ static void do_verify(struct thread_data *td) io_u->xfer_buflen = io_u->resid; io_u->xfer_buf += bytes; io_u->offset += bytes; + io_bytes += bytes; if (ddir_rw(io_u->ddir)) td->ts.short_io_u[io_u->ddir]++; @@ -495,6 +507,7 @@ sync_done: if (ret < 0) break; } + io_bytes += io_u->xfer_buflen; continue; case FIO_Q_QUEUED: break; @@ -529,15 +542,18 @@ sync_done: min_events = 1; do { + unsigned long bytes = 0; + /* * Reap required number of io units, if any, * and do the verification on them through * the callback handler */ - if (io_u_queued_complete(td, min_events, NULL) < 0) { + if (io_u_queued_complete(td, min_events, &bytes) < 0) { ret = -1; break; } + io_bytes += bytes; } while (full && (td->cur_depth > td->o.iodepth_low)); } if (ret < 0) @@ -1174,6 +1190,8 @@ static void *thread_main(void *data) clear_state = 0; while (keep_running(td)) { + uint64_t write_bytes; + fio_gettime(&td->start, NULL); memcpy(&td->bw_sample_time, &td->start, sizeof(td->start)); memcpy(&td->iops_sample_time, &td->start, sizeof(td->start)); @@ -1194,7 +1212,9 @@ static void *thread_main(void *data) prune_io_piece_log(td); + write_bytes = td->io_bytes[DDIR_WRITE]; do_io(td); + write_bytes = td->io_bytes[DDIR_WRITE] - write_bytes; clear_state = 1; @@ -1223,7 +1243,7 @@ static void *thread_main(void *data) fio_gettime(&td->start, NULL); - do_verify(td); + do_verify(td, write_bytes); td->ts.runtime[DDIR_READ] += utime_since_now(&td->start); diff --git a/fio.h b/fio.h index c5e2bf13..ed793ae5 100644 --- a/fio.h +++ b/fio.h @@ -159,6 +159,7 @@ struct thread_options { unsigned int verify_async; unsigned long long verify_backlog; unsigned int verify_batch; + unsigned int experimental_verify; unsigned int use_thread; unsigned int unlink; unsigned int do_disk_util; diff --git a/io_u.c b/io_u.c index 1658fb20..f020cac3 100644 --- a/io_u.c +++ b/io_u.c @@ -183,7 +183,8 @@ static int get_next_rand_offset(struct thread_data *td, struct fio_file *f, * any stored write metadata, just return a random offset */ if (!td->o.verifysort_nr || !(ddir == DDIR_READ && td->o.do_verify && - td->o.verify != VERIFY_NONE && td_random(td))) + td->o.verify != VERIFY_NONE && td_random(td)) || + td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE) return get_off_from_method(td, f, ddir, b); if (!flist_empty(&td->next_rand_list)) { @@ -544,6 +545,12 @@ static enum fio_ddir get_rw_ddir(struct thread_data *td) { enum fio_ddir ddir; + /* + * If verify phase started, it's always a READ + */ + if (td->runstate == TD_VERIFYING) + return DDIR_READ; + /* * see if it's time to fsync */ @@ -1418,7 +1425,8 @@ static void io_completed(struct thread_data *td, struct io_u *io_u, if (td_write(td) && idx == DDIR_WRITE && td->o.do_verify && - td->o.verify != VERIFY_NONE) + td->o.verify != VERIFY_NONE && + !td->o.experimental_verify) log_io_piece(td, io_u); icd->bytes_done[idx] += bytes; diff --git a/libfio.c b/libfio.c index 96ae8146..8255072e 100644 --- a/libfio.c +++ b/libfio.c @@ -82,7 +82,7 @@ static void reset_io_counters(struct thread_data *td) /* * reset file done count if we are to start over */ - if (td->o.time_based || td->o.loops) + if (td->o.time_based || td->o.loops || td->o.do_verify) td->nr_done_files = 0; } -- 2.25.1