X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=fio.c;h=fa5deabb6842ed0c527c07e76f68c9c93560e5cc;hp=ebe06d66f1ed1131e472ff2d0515acf6ed7b443c;hb=656b1393d43f9f22738404582ea14dec956aea83;hpb=581e71417760e0aa86eac0acd704253ff0eeea4f diff --git a/fio.c b/fio.c index ebe06d66..fa5deabb 100644 --- a/fio.c +++ b/fio.c @@ -42,7 +42,8 @@ unsigned long page_mask; unsigned long page_size; -#define ALIGN(buf) \ + +#define PAGE_ALIGN(buf) \ (char *) (((unsigned long) (buf) + page_mask) & ~page_mask) int groupid = 0; @@ -186,6 +187,9 @@ static int __check_min_rate(struct thread_data *td, struct timeval *now, unsigned int rate_iops = 0; unsigned int rate_iops_min = 0; + if (!td->o.ratemin[ddir] && !td->o.rate_iops_min[ddir]) + return 0; + /* * allow a 2 second settle period in the beginning */ @@ -369,6 +373,43 @@ static inline void update_tv_cache(struct thread_data *td) fio_gettime(&td->tv_cache, NULL); } +static int break_on_this_error(struct thread_data *td, int *retptr) +{ + int ret = *retptr; + + if (ret < 0 || td->error) { + int err; + + if (!td->o.continue_on_error) + return 1; + + if (ret < 0) + err = -ret; + else + err = td->error; + + update_error_count(td, err); + + if (td_non_fatal_error(err)) { + /* + * Continue with the I/Os in case of + * a non fatal error. + */ + td_clear_error(td); + *retptr = 0; + return 0; + } else { + /* + * Stop the I/O in case of a fatal + * error. + */ + return 1; + } + } + + return 0; +} + /* * The main verify engine. Runs over the writes we previously submitted, * reads the blocks back in, and checks the crc/md5 of the data. @@ -402,18 +443,17 @@ static void do_verify(struct thread_data *td) while (!td->terminate) { int ret2, full; - io_u = __get_io_u(td); - if (!io_u) - break; - update_tv_cache(td); if (runtime_exceeded(td, &td->tv_cache)) { - put_io_u(td, io_u); td->terminate = 1; break; } + io_u = __get_io_u(td); + if (!io_u) + break; + if (get_next_verify(td, io_u)) { put_io_u(td, io_u); break; @@ -429,9 +469,10 @@ static void do_verify(struct thread_data *td) ret = td_io_queue(td, io_u); switch (ret) { case FIO_Q_COMPLETED: - if (io_u->error) + if (io_u->error) { ret = -io_u->error; - else if (io_u->resid) { + clear_io_u(td, io_u); + } else if (io_u->resid) { int bytes = io_u->xfer_buflen - io_u->resid; struct fio_file *f = io_u->file; @@ -475,7 +516,7 @@ sync_done: break; } - if (ret < 0 || td->error) + if (break_on_this_error(td, &ret)) break; /* @@ -539,18 +580,17 @@ static void do_io(struct thread_data *td) if (td->terminate) break; - io_u = get_io_u(td); - if (!io_u) - break; - update_tv_cache(td); if (runtime_exceeded(td, &td->tv_cache)) { - put_io_u(td, io_u); td->terminate = 1; break; } + io_u = get_io_u(td); + if (!io_u) + break; + /* * Add verification end_io handler, if asked to verify * a previously written file. @@ -566,9 +606,10 @@ static void do_io(struct thread_data *td) ret = td_io_queue(td, io_u); switch (ret) { case FIO_Q_COMPLETED: - if (io_u->error) + if (io_u->error) { ret = -io_u->error; - else if (io_u->resid) { + clear_io_u(td, io_u); + } else if (io_u->resid) { int bytes = io_u->xfer_buflen - io_u->resid; struct fio_file *f = io_u->file; @@ -623,7 +664,7 @@ sync_done: break; } - if (ret < 0 || td->error) + if (break_on_this_error(td, &ret)) break; /* @@ -750,8 +791,8 @@ static int init_io_u(struct thread_data *td) if (allocate_io_mem(td)) return 1; - if (td->o.odirect) - p = ALIGN(td->orig_buffer); + if (td->o.mem_align) + p = PAGE_ALIGN(td->orig_buffer) + td->o.mem_align; else p = td->orig_buffer; @@ -771,9 +812,11 @@ static int init_io_u(struct thread_data *td) io_u = ptr; memset(io_u, 0, sizeof(*io_u)); INIT_FLIST_HEAD(&io_u->list); + dprint(FD_MEM, "io_u alloc %p, index %u\n", io_u, i); if (!(td->io_ops->flags & FIO_NOIO)) { io_u->buf = p + max_bs * i; + dprint(FD_MEM, "io_u %p, mem %p\n", io_u, io_u->buf); if (td_write(td) && !td->o.refill_buffers) io_u_fill_buffer(td, io_u, max_bs); @@ -1041,7 +1084,7 @@ static void *thread_main(void *data) memcpy(&td->ts.stat_sample_time, &td->start, sizeof(td->start)); memcpy(&td->tv_cache, &td->start, sizeof(td->start)); - if (td->o.ratemin) + if (td->o.ratemin[0] || td->o.ratemin[1]) memcpy(&td->lastrate, &td->ts.stat_sample_time, sizeof(td->lastrate)); @@ -1368,8 +1411,10 @@ static void run_threads(void) * its own files. so close them, if we opened them * for creation */ - for_each_file(td, f, i) - td_io_close_file(td, f); + for_each_file(td, f, i) { + if (fio_file_open(f)) + td_io_close_file(td, f); + } } init_disk_util(td); @@ -1447,7 +1492,13 @@ static void run_threads(void) *fio_debug_jobp = pid; } dprint(FD_MUTEX, "wait on startup_mutex\n"); - fio_mutex_down(startup_mutex); + if (fio_mutex_down_timeout(startup_mutex, 10)) { + log_err("fio: job startup hung? exiting.\n"); + terminate_threads(TERMINATE_ALL); + fio_abort = 1; + nr_started--; + break; + } dprint(FD_MUTEX, "done waiting on startup_mutex\n"); }