engines/io_uring_cmd: extend bsg cmd_type with cdb_len, verify, and prefetch - #2123
Open
ljw8161 wants to merge 5 commits into
Open
engines/io_uring_cmd: extend bsg cmd_type with cdb_len, verify, and prefetch#2123ljw8161 wants to merge 5 commits into
ljw8161 wants to merge 5 commits into
Conversation
vincentkfu
reviewed
Aug 3, 2026
vincentkfu
reviewed
Aug 3, 2026
vincentkfu
reviewed
Aug 3, 2026
vincentkfu
reviewed
Aug 3, 2026
vincentkfu
reviewed
Aug 3, 2026
fio_ioring_cmd_init() assigns ld->write_opcode = bsg_cmd_write_10 when cmd_type=bsg, but that field is never read on the bsg submission path. fio_bsg_uring_cmd_prep() fills bc->cdb[0] directly from io_u->ddir, and ld->write_opcode is only consumed by fio_nvme_uring_cmd_prep() on the nvme path. The assignment has therefore never had any effect. Drop the dead assignment. The surrounding `if (write_mode == WRITE)` branch existed only to hold it; once the assignment is gone the branch is empty, so the check collapses to a plain rejection of unsupported write modes. Fixes: d77ed2b ("engines/io_uring: Add bsg support for io_uring_cmd engine") Signed-off-by: Jungwon Lee <jjung1.lee@samsung.com>
The bsg completion was being parsed in two places: fio_ioring_cmd_event() decoded the packed SCSI status from cqe->big_cqe[0] into io_u->error, and fio_ioring_cmd_errdetails() re-derived the SCSI status and host status from io_u->error. The NVMe path only does this breakdown once, in errdetails. Drop the bsg-specific decoding from event and store the raw cqe->big_cqe[0] in io_u->error, leaving errdetails as the single place that splits the SCSI status (bits 0-7) and host status (bits 16-23). Fixes: d77ed2b ("engines/io_uring: Add bsg support for io_uring_cmd engine") Signed-off-by: Jungwon Lee <jjung1.lee@samsung.com>
The bsg cmd_type of the io_uring_cmd engine has so far hardcoded READ(10) and WRITE(10) for DDIR_READ and DDIR_WRITE. That caps the supported LBA range at 32 bits and the transfer length at 65535 blocks, which prevents benchmarking devices whose capacity or per-I/O transfer size exceeds those limits, and it also prevents comparing the performance characteristics of different CDB lengths of the same command. Add a new engine option, cdb_len, that selects the SCSI CDB length used for READ/WRITE commands. Supported values are 10, 16, and 32. The 32-byte command is encoded as a variable-length CDB (opcode 0x7F) with the READ(32) and WRITE(32) service actions. The default is 0 (auto): the smallest CDB whose LBA and transfer-length fields can hold the request is chosen, escalating from READ(10)/WRITE(10) to READ(16)/WRITE(16) as the LBA or transfer length grows, mirroring the sg engine. This lets fio drive devices whose capacity or per-I/O size exceeds the 10-byte limits without requiring the user to pick a CDB length up front. The 32-byte CDB shares the same 64-bit LBA and 32-bit length field widths as the 16-byte CDB, so auto-escalation never reaches it and it remains opt-in only (for exercising the variable-length CDB path itself). When an explicit cdb_len is set, requests whose LBA or transfer length would overflow the fields of the selected CDB length are rejected with -EINVAL rather than being silently promoted to a larger CDB. This preserves the user's explicit intent when a specific CDB length is chosen for benchmarking. SYNCHRONIZE CACHE follows cdb_len as well: the 10-byte command (0x35) is issued when cdb_len=10, and the 16-byte command (0x91) is issued otherwise. SBC does not define a 32-byte SYNCHRONIZE CACHE service action, so cdb_len=32 falls back to the 16-byte command. UNMAP has no CDB length selection and keeps its fixed 10-byte CDB regardless of cdb_len. Signed-off-by: Jungwon Lee <jjung1.lee@samsung.com>
The existing write_mode=verify option is currently only handled for the nvme cmd_type. Extend it to the bsg cmd_type so that SCSI VERIFY commands can be used as the write-side operation of a workload. This is useful for measuring the cost of medium verification against the same address range that would otherwise be written. The VERIFY CDB length follows the cdb_len option: VERIFY(10)=0x2F, VERIFY(16)=0x8F, and VERIFY(32) via the variable-length CDB service action. The data comparison behavior is controlled by a new verify_bytchk option that maps to the CDB BYTCHK field: 0 - medium verification only, no host data transfer (SG_DXFER_NONE) 1 - compare the full transfer against the medium byte by byte 3 - compare a single block against every block in the range For BYTCHK 1 and 3 the command sends data to the device (SG_DXFER_TO_DEV); BYTCHK 3 transfers only a single block while the CDB still carries the full block count. verify_bytchk defaults to 0 and is rejected unless write_mode=verify. VERIFY is the first bsg command that issues SG_DXFER_NONE with a non-zero io_u->xfer_buflen (the buflen encodes the block count that the device verifies against the medium). The previous fio_bsg_uring_cmd_init() lumped SG_DXFER_NONE into the else branch that populates din_xferp/din_xfer_len, which happened to be harmless only because DDIR_SYNC's xfer_buflen was zero. Tighten the else to match SG_DXFER_FROM_DEV explicitly so SG_DXFER_NONE leaves the data transfer fields cleared. writefua is rejected when combined with write_mode=verify. The FUA bit is not defined for the VERIFY command in any of the CDB variants that we support, and silently dropping the flag would hide a user misconfiguration. Signed-off-by: Jungwon Lee <jjung1.lee@samsung.com>
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. SBC does not define a 32-byte PRE-FETCH service action, so cdb_len=32 is rejected with read_mode=prefetch rather than silently falling back. readfua is also 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>
Collaborator
|
It seems that Please intercept this return value (perhaps in |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This series extends the bsg cmd_type of the io_uring_cmd engine, which
until now hardcoded READ(10)/WRITE(10) and supported only plain
read/write as the data-direction operations. The changes let users
select the SCSI CDB length and issue VERIFY and PRE-FETCH commands,
which is useful for benchmarking devices whose capacity or per-I/O
transfer size exceeds the 10-byte CDB limits, and for measuring the
cost of medium verification and read-cache warming.
The series also consolidates the bsg completion decoding into a single
place and drops a dead assignment on the bsg submission path. All new
options default to the current behavior, so existing bsg jobs are
unaffected.
Changes
Drop unused
write_opcodeassignment on the bsg path — cleanup.ld->write_opcodeis only consumed on the nvme path; the bsg pathfills the CDB directly from
io_u->ddir, so the assignment neverhad any effect. Simplifies the surrounding write-mode check.
Consolidate bsg status decoding into
errdetails— cleanup.The bsg completion was decoded in two places:
fio_ioring_cmd_event()split the packed SCSI status from
cqe->big_cqe[0]intoio_u->error, andfio_ioring_cmd_errdetails()re-derived the SCSIand host status from it. The nvme path only does this breakdown once,
in
errdetails. Move the bsg path to the same model:eventnowstores the raw
cqe->big_cqe[0]inio_u->error, leavingerrdetailsas the single place that splits the SCSI status(bits 0-7) and host status (bits 16-23).
Add
cdb_lenoption — selects the CDB length for READ/WRITE(and SYNCHRONIZE CACHE). Supported values are 10, 16, and 32; the
32-byte CDB uses the variable-length CDB (opcode 0x7F). The
default is
0(auto): the smallest CDB whose LBA andtransfer-length fields can hold the request is chosen, escalating
from 10 to 16 as the LBA or transfer length grows. An explicit
cdb_lenrejects requests whose LBA or transfer length wouldoverflow the selected CDB's fields rather than silently
promoting them, so a chosen CDB length is preserved for
benchmarking.
Support
write_mode=verify— extends the existing (nvme-only)option to bsg, issuing SCSI VERIFY as the write-side operation. A
new
verify_bytchkoption maps to the CDB BYTCHK field:0= medium verification only (no host transfer),1= fullbyte-by-byte comparison,
3= single-block comparison against therange.
writefuais rejected in this mode since FUA is not definedfor VERIFY.
Add
read_mode=prefetch— a new option symmetric towrite_mode, issuing SCSI PRE-FETCH for DDIR_READ to warm thedevice read cache without transferring data to the host. Unlike
SYNCHRONIZE CACHE (exposed via DDIR_SYNC), PRE-FETCH moves data
toward the cache and belongs on the read side.
readfuaandcdb_len=32are rejected in this mode: the FUA bit is not definedfor PRE-FETCH, and SBC defines no 32-byte PRE-FETCH service action.
Non-default
read_modewithcmd_type=nvme, andverify_bytchkwithout
write_mode=verify(bsg), are rejected at engine init somisconfigurations are surfaced instead of silently ignored.
Documentation (HOWTO.rst, fio.1) is updated for all new options.