Skip to content

Commit

Permalink
Merge branch 'io-uring-cmd/nvme/add-flush' of https://github.com/minw…
Browse files Browse the repository at this point in the history
…ooim/fio

* 'io-uring-cmd/nvme/add-flush' of https://github.com/minwooim/fio:
  t/nvmept.py: Add test cases for FLUSH
  io_u: Support fsync for --rw=trimwrite
  io_u: Ensure fsync only after write(s)
  td: Replace last_was_sync with last_ddir_issued
  td: Rename last_ddir to last_ddir_completed
  io_uring: Add support FLUSH command
  • Loading branch information
vincentkfu committed Jul 11, 2024
2 parents 6eaa642 + e84adcf commit 89fc401
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 11 deletions.
5 changes: 5 additions & 0 deletions engines/nvme.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,11 @@ int fio_nvme_uring_cmd_prep(struct nvme_uring_cmd *cmd, struct io_u *io_u,
case DDIR_TRIM:
fio_nvme_uring_cmd_trim_prep(cmd, io_u, dsm);
return 0;
case DDIR_SYNC:
case DDIR_DATASYNC:
cmd->opcode = nvme_cmd_flush;
cmd->nsid = data->nsid;
return 0;
default:
return -ENOTSUP;
}
Expand Down
1 change: 1 addition & 0 deletions engines/nvme.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ enum nvme_admin_opcode {
};

enum nvme_io_opcode {
nvme_cmd_flush = 0x00,
nvme_cmd_write = 0x01,
nvme_cmd_read = 0x02,
nvme_cmd_write_uncor = 0x04,
Expand Down
7 changes: 4 additions & 3 deletions fio.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,9 @@ struct thread_data {
size_t orig_buffer_size;
volatile int runstate;
volatile bool terminate;
bool last_was_sync;
enum fio_ddir last_ddir;

enum fio_ddir last_ddir_completed;
enum fio_ddir last_ddir_issued;

int mmapfd;

Expand Down Expand Up @@ -629,7 +630,7 @@ static inline bool multi_range_trim(struct thread_data *td, struct io_u *io_u)

static inline bool should_fsync(struct thread_data *td)
{
if (td->last_was_sync)
if (ddir_sync(td->last_ddir_issued))
return false;
if (td_write(td) || td->o.override_sync)
return true;
Expand Down
10 changes: 5 additions & 5 deletions io_u.c
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,7 @@ static enum fio_ddir get_rw_ddir(struct thread_data *td)
* See if it's time to fsync/fdatasync/sync_file_range first,
* and if not then move on to check regular I/Os.
*/
if (should_fsync(td)) {
if (should_fsync(td) && td->last_ddir_issued == DDIR_WRITE) {
if (td->o.fsync_blocks && td->io_issues[DDIR_WRITE] &&
!(td->io_issues[DDIR_WRITE] % td->o.fsync_blocks))
return DDIR_SYNC;
Expand Down Expand Up @@ -815,7 +815,7 @@ static void set_rw_ddir(struct thread_data *td, struct io_u *io_u)
if (td->o.zone_mode == ZONE_MODE_ZBD)
ddir = zbd_adjust_ddir(td, io_u, ddir);

if (td_trimwrite(td)) {
if (td_trimwrite(td) && !ddir_sync(ddir)) {
struct fio_file *f = io_u->file;
if (f->last_start[DDIR_WRITE] == f->last_start[DDIR_TRIM])
ddir = DDIR_TRIM;
Expand Down Expand Up @@ -1757,7 +1757,7 @@ static bool check_get_trim(struct thread_data *td, struct io_u *io_u)
if (get_next_trim(td, io_u))
return true;
} else if (!(td->io_hist_len % td->o.trim_backlog) &&
td->last_ddir != DDIR_READ) {
td->last_ddir_completed != DDIR_READ) {
td->trim_batch = td->o.trim_batch;
if (!td->trim_batch)
td->trim_batch = td->o.trim_backlog;
Expand All @@ -1779,7 +1779,7 @@ static bool check_get_verify(struct thread_data *td, struct io_u *io_u)
if (td->verify_batch)
get_verify = 1;
else if (!(td->io_hist_len % td->o.verify_backlog) &&
td->last_ddir != DDIR_READ) {
td->last_ddir_completed != DDIR_READ) {
td->verify_batch = td->o.verify_batch;
if (!td->verify_batch)
td->verify_batch = td->o.verify_backlog;
Expand Down Expand Up @@ -2122,7 +2122,7 @@ static void io_completed(struct thread_data *td, struct io_u **io_u_ptr,
return;
}

td->last_ddir = ddir;
td->last_ddir_completed = ddir;

if (!io_u->error && ddir_rw(ddir)) {
unsigned long long bytes = io_u->xfer_buflen - io_u->resid;
Expand Down
4 changes: 2 additions & 2 deletions ioengines.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ enum fio_q_status td_io_queue(struct thread_data *td, struct io_u *io_u)
td->ts.total_io_u[io_u->ddir]++;
}

td->last_was_sync = ddir_sync(io_u->ddir);
td->last_ddir_issued = ddir;
} else if (ret == FIO_Q_QUEUED) {
td->io_u_queued++;

Expand All @@ -448,7 +448,7 @@ enum fio_q_status td_io_queue(struct thread_data *td, struct io_u *io_u)
if (td->io_u_queued >= td->o.iodepth_batch)
td_io_commit(td);

td->last_was_sync = ddir_sync(io_u->ddir);
td->last_ddir_issued = ddir;
}

if (!td_ioengine_flagged(td, FIO_SYNCIO) &&
Expand Down
1 change: 0 additions & 1 deletion libfio.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ static void reset_io_counters(struct thread_data *td, int all)

td->zone_bytes = 0;

td->last_was_sync = false;
td->rwmix_issues = 0;

/*
Expand Down
91 changes: 91 additions & 0 deletions t/nvmept.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,53 @@ def check_result(self):
self.passed = False


class FlushTest(FioJobCmdTest):
def setup(self, parameters):
fio_args = [
"--name=nvmept-flush",
"--ioengine=io_uring_cmd",
"--cmd_type=nvme",
"--randrepeat=0",
f"--filename={self.fio_opts['filename']}",
f"--rw={self.fio_opts['rw']}",
f"--output={self.filenames['output']}",
f"--output-format={self.fio_opts['output-format']}",
]

for opt in ['fixedbufs', 'nonvectored', 'force_async', 'registerfiles',
'sqthread_poll', 'sqthread_poll_cpu', 'hipri', 'nowait',
'time_based', 'runtime', 'verify', 'io_size', 'num_range',
'iodepth', 'iodepth_batch', 'iodepth_batch_complete',
'size', 'rate', 'bs', 'bssplit', 'bsrange', 'randrepeat',
'buffer_pattern', 'verify_pattern', 'offset', 'fdp',
'fdp_pli', 'fdp_pli_select', 'dataplacement', 'plid_select',
'plids', 'dp_scheme', 'number_ios', 'read_iolog', 'fsync']:
if opt in self.fio_opts:
option = f"--{opt}={self.fio_opts[opt]}"
fio_args.append(option)

super().setup(fio_args)

def check_result(self):
super().check_result()

job = self.json_data['jobs'][0]

rw = self.fio_opts['rw']
fsync = self.fio_opts['fsync']

nr_write = job['write']['total_ios']
nr_sync = job['sync']['total_ios']

nr_sync_exp = nr_write // fsync

# The actual number of DDIR_SYNC issued might miss one DDIR_SYNC command
# when the last command issued was DDIR_WRITE command.
if not ((nr_sync == nr_sync_exp) or (nr_sync + 1 == nr_sync_exp)):
logging.error(f"nr_write={nr_write}, nr_sync={nr_sync}, fsync={fsync}")
self.passed = False


TEST_LIST = [
{
"test_id": 1,
Expand Down Expand Up @@ -255,6 +302,50 @@ def check_result(self):
},
"test_class": PassThruTest,
},
{
"test_id": 16,
"fio_opts": {
"rw": 'read',
"bs": 4096,
"number_ios": 10,
"fsync": 1,
"output-format": "json",
},
"test_class": FlushTest,
},
{
"test_id": 17,
"fio_opts": {
"rw": 'write',
"bs": 4096,
"number_ios": 10,
"fsync": 1,
"output-format": "json",
},
"test_class": FlushTest,
},
{
"test_id": 18,
"fio_opts": {
"rw": 'readwrite',
"bs": 4096,
"number_ios": 10,
"fsync": 1,
"output-format": "json",
},
"test_class": FlushTest,
},
{
"test_id": 19,
"fio_opts": {
"rw": 'trimwrite',
"bs": 4096,
"number_ios": 10,
"fsync": 1,
"output-format": "json",
},
"test_class": FlushTest,
},
]

def parse_args():
Expand Down

0 comments on commit 89fc401

Please sign in to comment.