Skip to content

Commit 87a4903

Browse files
committed
io_uring: Add 'write_mode' option for optional cmds
Add a new option 'write_mode' to support additional optional Write command family such as Write Uncorrectable and Write Zeroes in NVMe. Since we have io_uring_cmd ioengine where we can define the actual opcode of the command, this option will be used to test NVMe device with various combination of Write command types. 'write_mode' option can be given either 'write', 'uncor', 'zeroes' or 'verify'. 'write' is for normal Write command which is by default, 'uncor' is for Write Uncorrectable, 'zeroes' for Write Zeroes and 'verify' for Verify command This should be used with DDIR_WRITE ddir. This patch updates command's opcode in fio_ioring_init() to avoid branches in the I/O hottest path giving opcode value to the fio_nvme_uring_cmd_prep() as an argument. Signed-off-by: Minwoo Im <[email protected]>
1 parent d5fbe84 commit 87a4903

File tree

5 files changed

+105
-4
lines changed

5 files changed

+105
-4
lines changed

HOWTO.rst

+16
Original file line numberDiff line numberDiff line change
@@ -2857,6 +2857,22 @@ with the caveat that when used on the command line, they must come after the
28572857
With writefua option set to 1, write operations include
28582858
the force unit access (fua) flag. Default is 0.
28592859

2860+
.. option:: write_mode=str : [io_uring_cmd]
2861+
2862+
Specifies the type of write operation. Defaults to 'write'.
2863+
2864+
**write**
2865+
Use Write commands for write operations
2866+
2867+
**uncor**
2868+
Use Write Uncorrectable commands for write opreations
2869+
2870+
**zeroes**
2871+
Use Write Zeroes commands for write operations
2872+
2873+
**verify**
2874+
Use Verify commands for write operations
2875+
28602876
.. option:: sg_write_mode=str : [sg]
28612877

28622878
Specify the type of write commands to issue. This option can take ten values:

engines/io_uring.c

+63-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ enum uring_cmd_type {
3434
FIO_URING_CMD_NVME = 1,
3535
};
3636

37+
enum uring_cmd_write_mode {
38+
FIO_URING_CMD_WMODE_WRITE = 1,
39+
FIO_URING_CMD_WMODE_UNCOR,
40+
FIO_URING_CMD_WMODE_ZEROES,
41+
FIO_URING_CMD_WMODE_VERIFY,
42+
};
43+
3744
struct io_sq_ring {
3845
unsigned *head;
3946
unsigned *tail;
@@ -83,13 +90,15 @@ struct ioring_data {
8390

8491
struct nvme_dsm *dsm;
8592
uint32_t cdw12_flags[DDIR_RWDIR_CNT];
93+
uint8_t write_opcode;
8694
};
8795

8896
struct ioring_options {
8997
struct thread_data *td;
9098
unsigned int hipri;
9199
unsigned int readfua;
92100
unsigned int writefua;
101+
unsigned int write_mode;
93102
struct cmdprio_options cmdprio_options;
94103
unsigned int fixedbufs;
95104
unsigned int registerfiles;
@@ -158,6 +167,34 @@ static struct fio_option options[] = {
158167
.category = FIO_OPT_C_ENGINE,
159168
.group = FIO_OPT_G_IOURING,
160169
},
170+
{
171+
.name = "write_mode",
172+
.lname = "Additional Write commands support (Write Uncorrectable, Write Zeores)",
173+
.type = FIO_OPT_STR,
174+
.off1 = offsetof(struct ioring_options, write_mode),
175+
.help = "Issue Write Uncorrectable or Zeroes command instaed of Write command",
176+
.def = "write",
177+
.posval = {
178+
{ .ival = "write",
179+
.oval = FIO_URING_CMD_WMODE_WRITE,
180+
.help = "Issue Write commands for write operations"
181+
},
182+
{ .ival = "uncor",
183+
.oval = FIO_URING_CMD_WMODE_UNCOR,
184+
.help = "Issue Write Uncorrectable commands for write operations"
185+
},
186+
{ .ival = "zeroes",
187+
.oval = FIO_URING_CMD_WMODE_ZEROES,
188+
.help = "Issue Write Zeroes commands for write operations"
189+
},
190+
{ .ival = "verify",
191+
.oval = FIO_URING_CMD_WMODE_VERIFY,
192+
.help = "Issue Verify commands for write operations"
193+
},
194+
},
195+
.category = FIO_OPT_C_ENGINE,
196+
.group = FIO_OPT_G_IOURING,
197+
},
161198
{
162199
.name = "fixedbufs",
163200
.lname = "Fixed (pre-mapped) IO buffers",
@@ -455,7 +492,7 @@ static int fio_ioring_cmd_prep(struct thread_data *td, struct io_u *io_u)
455492

456493
return fio_nvme_uring_cmd_prep(cmd, io_u,
457494
o->nonvectored ? NULL : &ld->iovecs[io_u->index],
458-
dsm, ld->cdw12_flags[io_u->ddir]);
495+
dsm, ld->write_opcode, ld->cdw12_flags[io_u->ddir]);
459496
}
460497

461498
static struct io_u *fio_ioring_event(struct thread_data *td, int event)
@@ -1243,6 +1280,23 @@ static int fio_ioring_init(struct thread_data *td)
12431280
}
12441281

12451282
if (!strcmp(td->io_ops->name, "io_uring_cmd")) {
1283+
if (td_write(td)) {
1284+
switch (o->write_mode) {
1285+
case FIO_URING_CMD_WMODE_UNCOR:
1286+
ld->write_opcode = nvme_cmd_write_uncor;
1287+
break;
1288+
case FIO_URING_CMD_WMODE_ZEROES:
1289+
ld->write_opcode = nvme_cmd_write_zeroes;
1290+
break;
1291+
case FIO_URING_CMD_WMODE_VERIFY:
1292+
ld->write_opcode = nvme_cmd_verify;
1293+
break;
1294+
default:
1295+
ld->write_opcode = nvme_cmd_write;
1296+
break;
1297+
}
1298+
}
1299+
12461300
if (o->readfua)
12471301
ld->cdw12_flags[DDIR_READ] = 1 << 30;
12481302
if (o->writefua)
@@ -1371,6 +1425,14 @@ static int fio_ioring_cmd_open_file(struct thread_data *td, struct fio_file *f)
13711425
td_verror(td, EINVAL, "fio_ioring_cmd_open_file");
13721426
return 1;
13731427
}
1428+
1429+
if (o->write_mode != FIO_URING_CMD_WMODE_WRITE &&
1430+
!td_write(td)) {
1431+
log_err("%s: 'readwrite=|rw=' has no write\n",
1432+
f->file_name);
1433+
td_verror(td, EINVAL, "fio_ioring_cmd_open_file");
1434+
return 1;
1435+
}
13741436
}
13751437
if (!ld || !o->registerfiles)
13761438
return generic_open_file(td, f);

engines/nvme.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ void fio_nvme_uring_cmd_trim_prep(struct nvme_uring_cmd *cmd, struct io_u *io_u,
363363

364364
int fio_nvme_uring_cmd_prep(struct nvme_uring_cmd *cmd, struct io_u *io_u,
365365
struct iovec *iov, struct nvme_dsm *dsm,
366-
unsigned int cdw12_flags)
366+
uint8_t write_opcode, unsigned int cdw12_flags)
367367
{
368368
struct nvme_data *data = FILE_ENG_DATA(io_u->file);
369369
__u64 slba;
@@ -376,7 +376,7 @@ int fio_nvme_uring_cmd_prep(struct nvme_uring_cmd *cmd, struct io_u *io_u,
376376
cmd->opcode = nvme_cmd_read;
377377
break;
378378
case DDIR_WRITE:
379-
cmd->opcode = nvme_cmd_write;
379+
cmd->opcode = write_opcode;
380380
break;
381381
case DDIR_TRIM:
382382
fio_nvme_uring_cmd_trim_prep(cmd, io_u, dsm);

engines/nvme.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,10 @@ enum nvme_admin_opcode {
7575
enum nvme_io_opcode {
7676
nvme_cmd_write = 0x01,
7777
nvme_cmd_read = 0x02,
78+
nvme_cmd_write_uncor = 0x04,
79+
nvme_cmd_write_zeroes = 0x08,
7880
nvme_cmd_dsm = 0x09,
81+
nvme_cmd_verify = 0x0c,
7982
nvme_cmd_io_mgmt_recv = 0x12,
8083
nvme_zns_cmd_mgmt_send = 0x79,
8184
nvme_zns_cmd_mgmt_recv = 0x7a,
@@ -427,7 +430,7 @@ int fio_nvme_get_info(struct fio_file *f, __u64 *nlba, __u32 pi_act,
427430

428431
int fio_nvme_uring_cmd_prep(struct nvme_uring_cmd *cmd, struct io_u *io_u,
429432
struct iovec *iov, struct nvme_dsm *dsm,
430-
unsigned int cdw12_flags);
433+
uint8_t write_opcode, unsigned int cdw12_flags);
431434

432435
void fio_nvme_pi_fill(struct nvme_uring_cmd *cmd, struct io_u *io_u,
433436
struct nvme_cmd_ext_io_opts *opts);

fio.1

+20
Original file line numberDiff line numberDiff line change
@@ -2640,6 +2640,26 @@ unit access (fua) flag. Default: 0.
26402640
With writefua option set to 1, write operations include the force
26412641
unit access (fua) flag. Default: 0.
26422642
.TP
2643+
.BI (io_uring_cmd)write_mode \fR=\fPstr
2644+
Specifies the type of write operation. Defaults to 'write'.
2645+
.RS
2646+
.RS
2647+
.TP
2648+
.B write
2649+
Use Write commands for write operations
2650+
.TP
2651+
.B uncor
2652+
Use Write Uncorrectable commands for write opreations
2653+
.TP
2654+
.B zeroes
2655+
Use Write Zeroes commands for write operations
2656+
.TP
2657+
.B verify
2658+
Use Verify commands for write operations
2659+
.TP
2660+
.RE
2661+
.RE
2662+
.TP
26432663
.BI (sg)sg_write_mode \fR=\fPstr
26442664
Specify the type of write commands to issue. This option can take multiple
26452665
values:

0 commit comments

Comments
 (0)