X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=rate-submit.c;h=e5c6204351db00304db32fa376837faa9c420cc9;hp=42927ffeaf4125dcefccc8fe964d2bc448197fea;hb=refs%2Fheads%2Flatency-probe;hpb=c7334fa3f3be87854354044615b0c0e473c50713 diff --git a/rate-submit.c b/rate-submit.c index 42927ffe..e5c62043 100644 --- a/rate-submit.c +++ b/rate-submit.c @@ -5,10 +5,48 @@ * */ #include "fio.h" -#include "ioengine.h" +#include "ioengines.h" #include "lib/getrusage.h" #include "rate-submit.h" +static void check_overlap(struct io_u *io_u) +{ + int i; + struct thread_data *td; + bool overlap = false; + + do { + /* + * Allow only one thread to check for overlap at a + * time to prevent two threads from thinking the coast + * is clear and then submitting IOs that overlap with + * each other + * + * If an overlap is found, release the lock and + * re-acquire it before checking again to give other + * threads a chance to make progress + * + * If an overlap is not found, release the lock when the + * io_u's IO_U_F_FLIGHT flag is set so that this io_u + * can be checked by other threads as they assess overlap + */ + pthread_mutex_lock(&overlap_check); + for_each_td(td, i) { + if (td->runstate <= TD_SETTING_UP || + td->runstate >= TD_FINISHING || + !td->o.serialize_overlap || + td->o.io_submit_mode != IO_MODE_OFFLOAD) + continue; + + overlap = in_flight_overlap(&td->io_u_all, io_u); + if (overlap) { + pthread_mutex_unlock(&overlap_check); + break; + } + } + } while (overlap); +} + static int io_workqueue_fn(struct submit_worker *sw, struct workqueue_work *work) { @@ -17,6 +55,9 @@ static int io_workqueue_fn(struct submit_worker *sw, struct thread_data *td = sw->priv; int ret; + if (td->o.serialize_overlap) + check_overlap(io_u); + dprint(FD_RATE, "io_u %p queued by %u\n", io_u, gettid()); io_u_set(td, io_u, IO_U_F_NO_FILE_PUT); @@ -50,10 +91,6 @@ static int io_workqueue_fn(struct submit_worker *sw, ret = io_u_queued_complete(td, min_evts); if (ret > 0) td->cur_depth -= ret; - } else if (ret == FIO_Q_BUSY) { - ret = io_u_queued_complete(td, td->cur_depth); - if (ret > 0) - td->cur_depth -= ret; } return 0; @@ -98,7 +135,6 @@ static int io_workqueue_init_worker_fn(struct submit_worker *sw) { struct thread_data *parent = sw->wq->td; struct thread_data *td = sw->priv; - int fio_unused ret; memcpy(&td->o, &parent->o, sizeof(td->o)); memcpy(&td->ts, &parent->ts, sizeof(td->ts)); @@ -116,7 +152,6 @@ static int io_workqueue_init_worker_fn(struct submit_worker *sw) INIT_FLIST_HEAD(&td->io_hist_list); INIT_FLIST_HEAD(&td->verify_list); INIT_FLIST_HEAD(&td->trim_list); - INIT_FLIST_HEAD(&td->next_rand_list); td->io_hist_tree = RB_ROOT; td->o.iodepth = 1; @@ -128,7 +163,7 @@ static int io_workqueue_init_worker_fn(struct submit_worker *sw) clear_io_state(td, 1); td_set_runstate(td, TD_RUNNING); - td->flags |= TD_F_CHILD; + td->flags |= TD_F_CHILD | TD_F_NEED_LOCK; td->parent = parent; return 0;