Skip to content

Commit 01f0b4e

Browse files
committed
engines/io_uring: add read_mode=prefetch for bsg cmd_type
Introduce a new engine option, read_mode, that selects which command variant is issued for DDIR_READ, symmetric to the existing write_mode option. Two values are supported: 'read', which preserves the current behavior, and 'prefetch', which issues SCSI PRE-FETCH commands. PRE-FETCH pulls the requested LBAs from the medium into the device read cache without transferring the data to the host. This is useful for warming the device read cache prior to a subsequent measurement, and for measuring the overhead of the prefetch path itself. The PRE-FETCH CDB length follows the cdb_len option: PRE-FETCH(10)=0x34 and PRE-FETCH(16)=0x90. readfua is rejected in this mode because the FUA bit is not defined for PRE-FETCH. read_mode is currently only meaningful for the bsg cmd_type. Passing a non-default value with cmd_type=nvme is rejected at engine init rather than silently ignored, so that users notice a misconfiguration. Signed-off-by: Jungwon Lee <jjung1.lee@samsung.com>
1 parent 8c9bb9a commit 01f0b4e

5 files changed

Lines changed: 116 additions & 3 deletions

File tree

HOWTO.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3111,6 +3111,22 @@ with the caveat that when used on the command line, they must come after the
31113111
The device compares a single block against every block
31123112
in the range. Only one block is transferred.
31133113

3114+
.. option:: read_mode=str : [io_uring_cmd]
3115+
3116+
Specifies the type of read operation. Only supported with
3117+
cmd_type=bsg. Defaults to 'read'.
3118+
3119+
**read**
3120+
Use Read commands for read operations
3121+
3122+
**prefetch**
3123+
Use SCSI Pre-Fetch commands, which pull the requested
3124+
blocks from the medium into the device read cache
3125+
without transferring data to the host. Useful for
3126+
cache-warming and prefetch-overhead benchmarks. The
3127+
Pre-Fetch(10)/(16) opcode is selected by :option:`cdb_len`.
3128+
:option:`readfua` is not supported in this mode.
3129+
31143130
.. option:: verify_mode=str : [io_uring_cmd]
31153131

31163132
Specifies the type of command to be used in the verification phase. Defaults to 'read'.

engines/bsg.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ static void fio_bsg_set_verify_bytchk(struct bsg_cmd *bc, unsigned int cdb_len,
166166
int fio_bsg_uring_cmd_prep(struct bsg_uring_cmd *cmd, struct io_u *io_u,
167167
struct bsg_cmd *bc, bool fua, unsigned int cdb_len,
168168
enum bsg_write_variant wvariant,
169-
unsigned int verify_bytchk)
169+
unsigned int verify_bytchk,
170+
enum bsg_read_variant rvariant)
170171
{
171172
struct bsg_data *data = FILE_ENG_DATA(io_u->file);
172173
unsigned long long offset, nlb;
@@ -197,6 +198,23 @@ int fio_bsg_uring_cmd_prep(struct bsg_uring_cmd *cmd, struct io_u *io_u,
197198

198199
switch (io_u->ddir) {
199200
case DDIR_READ:
201+
if (rvariant == BSG_READ_VARIANT_PREFETCH) {
202+
/*
203+
* PREFETCH pulls the requested blocks from the medium
204+
* into the device read cache. No host data transfer.
205+
*/
206+
fio_bsg_uring_cmd_init(cmd, bc, io_u, SG_DXFER_NONE,
207+
cdb_len);
208+
switch (cdb_len) {
209+
case 10:
210+
bc->cdb[0] = bsg_cmd_prefetch_10;
211+
break;
212+
case 16:
213+
bc->cdb[0] = bsg_cmd_prefetch_16;
214+
break;
215+
}
216+
break;
217+
}
200218
fio_bsg_uring_cmd_init(cmd, bc, io_u, SG_DXFER_FROM_DEV, cdb_len);
201219
switch (cdb_len) {
202220
case 10:

engines/bsg.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ enum bsg_io_opcode {
6262
bsg_cmd_write_16 = 0x8A,
6363
bsg_cmd_verify_10 = 0x2F,
6464
bsg_cmd_verify_16 = 0x8F,
65+
bsg_cmd_prefetch_10 = 0x34,
66+
bsg_cmd_prefetch_16 = 0x90,
6567
bsg_cmd_varlen = BSG_VARLEN_CDB_OPCODE,
6668
};
6769

@@ -71,6 +73,12 @@ enum bsg_write_variant {
7173
BSG_WRITE_VARIANT_VERIFY,
7274
};
7375

76+
/* Which command variant to issue for DDIR_READ ddir. */
77+
enum bsg_read_variant {
78+
BSG_READ_VARIANT_READ = 0,
79+
BSG_READ_VARIANT_PREFETCH,
80+
};
81+
7482
struct bsg_cmd {
7583
unsigned char cdb[MAX_CDB_LEN];
7684
unsigned char sb[MAX_SB];
@@ -89,6 +97,7 @@ int fio_bsg_uring_cmd_get_file_size(struct thread_data *td, struct fio_file *f);
8997
int fio_bsg_uring_cmd_prep(struct bsg_uring_cmd *cmd, struct io_u *io_u,
9098
struct bsg_cmd *bc, bool fua, unsigned int cdb_len,
9199
enum bsg_write_variant wvariant,
92-
unsigned int verify_bytchk);
100+
unsigned int verify_bytchk,
101+
enum bsg_read_variant rvariant);
93102

94103
#endif /* FIO_BSG_H */

engines/io_uring.c

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ enum uring_cmd_verify_mode {
121121
FIO_URING_CMD_VMODE_COMPARE,
122122
};
123123

124+
enum uring_cmd_read_mode {
125+
FIO_URING_CMD_RMODE_READ = 0,
126+
FIO_URING_CMD_RMODE_PREFETCH,
127+
};
128+
124129
struct io_sq_ring {
125130
unsigned *head;
126131
unsigned *tail;
@@ -216,6 +221,7 @@ struct ioring_options {
216221
enum uring_cmd_type cmd_type;
217222
unsigned int cdb_len;
218223
unsigned int verify_bytchk;
224+
unsigned int read_mode;
219225
};
220226

221227
static unsigned int enter_flags = IORING_ENTER_GETEVENTS;
@@ -566,6 +572,26 @@ static struct fio_option options[] = {
566572
.category = FIO_OPT_C_ENGINE,
567573
.group = FIO_OPT_G_IOURING,
568574
},
575+
{
576+
.name = "read_mode",
577+
.lname = "Read command type",
578+
.type = FIO_OPT_STR,
579+
.off1 = offsetof(struct ioring_options, read_mode),
580+
.help = "Specify the read operation type (bsg cmd_type only)",
581+
.def = "read",
582+
.posval = {
583+
{ .ival = "read",
584+
.oval = FIO_URING_CMD_RMODE_READ,
585+
.help = "Use Read commands for read operations",
586+
},
587+
{ .ival = "prefetch",
588+
.oval = FIO_URING_CMD_RMODE_PREFETCH,
589+
.help = "Use Pre-Fetch commands for read operations",
590+
},
591+
},
592+
.category = FIO_OPT_C_ENGINE,
593+
.group = FIO_OPT_G_IOURING,
594+
},
569595
CMDPRIO_OPTIONS(struct ioring_options, FIO_OPT_G_IOURING),
570596
{
571597
.name = "md_per_io_size",
@@ -880,18 +906,24 @@ static int fio_ioring_cmd_prep(struct thread_data *td, struct io_u *io_u)
880906
} else {
881907
struct bsg_uring_cmd *cmd;
882908
enum bsg_write_variant wvariant;
909+
enum bsg_read_variant rvariant;
883910

884911
if (o->write_mode == FIO_URING_CMD_WMODE_VERIFY)
885912
wvariant = BSG_WRITE_VARIANT_VERIFY;
886913
else
887914
wvariant = BSG_WRITE_VARIANT_WRITE;
915+
if (o->read_mode == FIO_URING_CMD_RMODE_PREFETCH)
916+
rvariant = BSG_READ_VARIANT_PREFETCH;
917+
else
918+
rvariant = BSG_READ_VARIANT_READ;
888919

889920
sqe->len = io_u->xfer_buflen;
890921
cmd = (struct bsg_uring_cmd *)sqe->cmd;
891922

892923
return fio_bsg_uring_cmd_prep(cmd, io_u, &ld->bc[io_u->index],
893924
ld->fua[io_u->ddir], o->cdb_len,
894-
wvariant, o->verify_bytchk);
925+
wvariant, o->verify_bytchk,
926+
rvariant);
895927
}
896928
}
897929

@@ -1613,6 +1645,11 @@ static int fio_ioring_cmd_init(struct thread_data *td, struct ioring_data *ld)
16131645
}
16141646

16151647
if (o->cmd_type == FIO_URING_CMD_NVME) {
1648+
if (o->read_mode != FIO_URING_CMD_RMODE_READ) {
1649+
log_err("fio: read_mode is only supported with "
1650+
"cmd_type=bsg\n");
1651+
return 1;
1652+
}
16161653
if (td_write(td)) {
16171654
if (o->wmode_split_nr > 1) {
16181655
int i;
@@ -1675,6 +1712,22 @@ static int fio_ioring_cmd_init(struct thread_data *td, struct ioring_data *ld)
16751712
return 1;
16761713
}
16771714

1715+
if (o->read_mode == FIO_URING_CMD_RMODE_PREFETCH &&
1716+
o->readfua) {
1717+
log_err("readfua is not supported "
1718+
"with read_mode=prefetch for bsg\n");
1719+
td_verror(td, EINVAL, "fio_ioring_cmd_init");
1720+
return 1;
1721+
}
1722+
1723+
if (o->read_mode == FIO_URING_CMD_RMODE_PREFETCH &&
1724+
o->cdb_len == 32) {
1725+
log_err("cdb_len=32 is not supported "
1726+
"with read_mode=prefetch for bsg\n");
1727+
td_verror(td, EINVAL, "fio_ioring_cmd_init");
1728+
return 1;
1729+
}
1730+
16781731
if (td_write(td)) {
16791732
if (o->write_mode != FIO_URING_CMD_WMODE_WRITE &&
16801733
o->write_mode != FIO_URING_CMD_WMODE_VERIFY) {

fio.1

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2901,6 +2901,23 @@ block is transferred.
29012901
.RE
29022902
.RE
29032903
.TP
2904+
.BI (io_uring_cmd)read_mode \fR=\fPstr
2905+
Specifies the type of read operation. Only supported with cmd_type=bsg.
2906+
Defaults to 'read'.
2907+
.RS
2908+
.RS
2909+
.TP
2910+
.B read
2911+
Use Read commands for read operations
2912+
.TP
2913+
.B prefetch
2914+
Use SCSI Pre-Fetch commands, which pull the requested blocks from the medium
2915+
into the device read cache without transferring data to the host. Useful for
2916+
cache-warming and prefetch-overhead benchmarks. The Pre-Fetch(10)/(16) opcode
2917+
is selected by \fBcdb_len\fR. \fBreadfua\fR is not supported in this mode.
2918+
.RE
2919+
.RE
2920+
.TP
29042921
.BI (io_uring_cmd)verify_mode \fR=\fPstr
29052922
Specifies the type of command to be used in the verification phase. Defaults to 'read'.
29062923
.RS

0 commit comments

Comments
 (0)