#include <sys/stat.h>
#include <sys/wait.h>
#include <math.h>
+#include <pthread.h>
#include "fio.h"
#include "smalloc.h"
int shm_id = 0;
int temp_stall_ts;
unsigned long done_secs = 0;
+pthread_mutex_t overlap_check = PTHREAD_MUTEX_INITIALIZER;
#define JOB_START_TIMEOUT (5 * 1000)
/*
* Check if io_u will overlap an in-flight IO in the queue
*/
-static bool in_flight_overlap(struct io_u_queue *q, struct io_u *io_u)
+bool in_flight_overlap(struct io_u_queue *q, struct io_u *io_u)
{
bool overlap;
struct io_u *check_io_u;
"perhaps try --debug=io option for details?\n",
td->o.name, td->io_ops->name);
+ if (td->o.serialize_overlap && td->o.io_submit_mode == IO_MODE_OFFLOAD)
+ pthread_mutex_lock(&overlap_check);
td_set_runstate(td, TD_FINISHING);
+ if (td->o.serialize_overlap && td->o.io_submit_mode == IO_MODE_OFFLOAD)
+ pthread_mutex_unlock(&overlap_check);
update_rusage_stat(td);
td->ts.total_run_time = mtime_since_now(&td->epoch);
extern void exec_trigger(const char *);
extern void check_trigger_file(void);
+extern bool in_flight_overlap(struct io_u_queue *q, struct io_u *io_u);
+extern pthread_mutex_t overlap_check;
+
#endif
assert((io_u->flags & IO_U_F_FLIGHT) == 0);
io_u_set(td, io_u, IO_U_F_FLIGHT);
+ if (td->o.serialize_overlap && td->o.io_submit_mode == IO_MODE_OFFLOAD)
+ pthread_mutex_unlock(&overlap_check);
assert(fio_file_open(io_u->file));
#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
+ */
+ 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)
{
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);