X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=backend.c;h=60cea3c682a8dc8c5c95a40f2a438ff06a054fbd;hb=4e795a3e0940509bd991682ec029000b6aa8881b;hp=d98658606d772ed7d31b1355571ee2566b53a213;hpb=4d384589772a50924c68261086feae594020395e;p=fio.git diff --git a/backend.c b/backend.c index d9865860..60cea3c6 100644 --- a/backend.c +++ b/backend.c @@ -771,18 +771,18 @@ static bool exceeds_number_ios(struct thread_data *td) return number_ios >= (td->o.number_ios * td->loops); } -static bool io_issue_bytes_exceeded(struct thread_data *td) +static bool io_bytes_exceeded(struct thread_data *td, uint64_t *this_bytes) { unsigned long long bytes, limit; if (td_rw(td)) - bytes = td->io_issue_bytes[DDIR_READ] + td->io_issue_bytes[DDIR_WRITE]; + bytes = this_bytes[DDIR_READ] + this_bytes[DDIR_WRITE]; else if (td_write(td)) - bytes = td->io_issue_bytes[DDIR_WRITE]; + bytes = this_bytes[DDIR_WRITE]; else if (td_read(td)) - bytes = td->io_issue_bytes[DDIR_READ]; + bytes = this_bytes[DDIR_READ]; else - bytes = td->io_issue_bytes[DDIR_TRIM]; + bytes = this_bytes[DDIR_TRIM]; if (td->o.io_limit) limit = td->o.io_limit; @@ -793,26 +793,14 @@ static bool io_issue_bytes_exceeded(struct thread_data *td) return bytes >= limit || exceeds_number_ios(td); } -static bool io_complete_bytes_exceeded(struct thread_data *td) +static bool io_issue_bytes_exceeded(struct thread_data *td) { - unsigned long long bytes, limit; - - if (td_rw(td)) - bytes = td->this_io_bytes[DDIR_READ] + td->this_io_bytes[DDIR_WRITE]; - else if (td_write(td)) - bytes = td->this_io_bytes[DDIR_WRITE]; - else if (td_read(td)) - bytes = td->this_io_bytes[DDIR_READ]; - else - bytes = td->this_io_bytes[DDIR_TRIM]; - - if (td->o.io_limit) - limit = td->o.io_limit; - else - limit = td->o.size; + return io_bytes_exceeded(td, td->io_issue_bytes); +} - limit *= td->loops; - return bytes >= limit || exceeds_number_ios(td); +static bool io_complete_bytes_exceeded(struct thread_data *td) +{ + return io_bytes_exceeded(td, td->this_io_bytes); } /* @@ -1471,6 +1459,7 @@ static void *thread_main(void *data) struct thread_data *td = fd->td; struct thread_options *o = &td->o; struct sk_out *sk_out = fd->sk_out; + int deadlock_loop_cnt; int clear_state; int ret; @@ -1722,6 +1711,14 @@ static void *thread_main(void *data) } } + /* + * If we took too long to shut down, the main thread could + * already consider us reaped/exited. If that happens, break + * out and clean up. + */ + if (td->runstate >= TD_EXITED) + break; + clear_state = 1; /* @@ -1731,9 +1728,19 @@ static void *thread_main(void *data) * the rusage_sem, which would never get upped because * this thread is waiting for the stat mutex. */ - check_update_rusage(td); + deadlock_loop_cnt = 0; + do { + check_update_rusage(td); + if (!fio_mutex_down_trylock(stat_mutex)) + break; + usleep(1000); + if (deadlock_loop_cnt++ > 5000) { + log_err("fio seems to be stuck grabbing stat_mutex, forcibly exiting\n"); + td->error = EDEADLK; + goto err; + } + } while (1); - fio_mutex_down(stat_mutex); if (td_read(td) && td->io_bytes[DDIR_READ]) update_runtime(td, elapsed_us, DDIR_READ); if (td_write(td) && td->io_bytes[DDIR_WRITE])