Initial support for explicit write barriers
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
diff --git a/engines/binject.c b/engines/binject.c
index 65894c2..44a3796 100644
--- a/engines/binject.c
+++ b/engines/binject.c
@@ -191,7 +191,10 @@
buc->type = B_TYPE_READ;
} else if (io_u->ddir == DDIR_WRITE) {
binject_buc_init(bd, io_u);
- buc->type = B_TYPE_WRITE;
+ if (io_u->flags & IO_U_F_BARRIER)
+ buc->type = B_TYPE_WRITEBARRIER;
+ else
+ buc->type = B_TYPE_WRITE;
} else if (io_u->ddir == DDIR_TRIM) {
binject_buc_init(bd, io_u);
buc->type = B_TYPE_DISCARD;
@@ -407,7 +410,7 @@
.open_file = fio_binject_open_file,
.close_file = fio_binject_close_file,
.get_file_size = generic_get_file_size,
- .flags = FIO_RAWIO,
+ .flags = FIO_RAWIO | FIO_BARRIER,
};
#else /* FIO_HAVE_BINJECT */
diff --git a/fio.h b/fio.h
index c2a0d4d..4ed8cb1 100644
--- a/fio.h
+++ b/fio.h
@@ -217,6 +217,7 @@
unsigned int thinktime_blocks;
unsigned int fsync_blocks;
unsigned int fdatasync_blocks;
+ unsigned int barrier_blocks;
unsigned long start_delay;
unsigned long long timeout;
unsigned long long ramp_time;
diff --git a/io_u.c b/io_u.c
index baa961b..6d539a0 100644
--- a/io_u.c
+++ b/io_u.c
@@ -501,6 +501,17 @@
return td->rwmix_ddir;
}
+static void set_rw_ddir(struct thread_data *td, struct io_u *io_u)
+{
+ io_u->ddir = get_rw_ddir(td);
+
+ if (io_u->ddir == DDIR_WRITE && (td->io_ops->flags & FIO_BARRIER) &&
+ td->o.barrier_blocks &&
+ !(td->io_issues[DDIR_WRITE] % td->o.barrier_blocks) &&
+ td->io_issues[DDIR_WRITE])
+ io_u->flags |= IO_U_F_BARRIER;
+}
+
void put_file_log(struct thread_data *td, struct fio_file *f)
{
int ret = put_file(td, f);
@@ -560,7 +571,7 @@
if (td->io_ops->flags & FIO_NOIO)
goto out;
- io_u->ddir = get_rw_ddir(td);
+ set_rw_ddir(td, io_u);
/*
* fsync() or fdatasync() or trim etc, we are done
@@ -963,7 +974,7 @@
if (io_u) {
assert(io_u->flags & IO_U_F_FREE);
io_u->flags &= ~(IO_U_F_FREE | IO_U_F_FREE_DEF);
- io_u->flags &= ~IO_U_F_TRIMMED;
+ io_u->flags &= ~(IO_U_F_TRIMMED | IO_U_F_BARRIER);
io_u->error = 0;
flist_del(&io_u->list);
diff --git a/ioengine.h b/ioengine.h
index 344cdbf..7a3c08f 100644
--- a/ioengine.h
+++ b/ioengine.h
@@ -10,6 +10,7 @@
IO_U_F_IN_CUR_DEPTH = 1 << 3,
IO_U_F_BUSY_OK = 1 << 4,
IO_U_F_TRIMMED = 1 << 5,
+ IO_U_F_BARRIER = 1 << 6,
};
/*
@@ -126,6 +127,7 @@
FIO_NOIO = 1 << 6, /* thread does only pseudo IO */
FIO_SIGQUIT = 1 << 7, /* needs SIGQUIT to exit */
FIO_PIPEIO = 1 << 8, /* input/output no seekable */
+ FIO_BARRIER = 1 << 9, /* engine supports barriers */
};
/*
diff --git a/options.c b/options.c
index bdf3582..d111018 100644
--- a/options.c
+++ b/options.c
@@ -1185,6 +1185,13 @@
.help = "Issue fdatasync for writes every given number of blocks",
.def = "0",
},
+ {
+ .name = "write_barrier",
+ .type = FIO_OPT_INT,
+ .off1 = td_var_offset(barrier_blocks),
+ .help = "Make every Nth write a barrier write",
+ .def = "0",
+ },
#ifdef FIO_HAVE_SYNC_FILE_RANGE
{
.name = "sync_file_range",