From 0507da7d3f350127dbaf50261fa7499c46e75573 Mon Sep 17 00:00:00 2001 From: Minwoo Im Date: Fri, 16 Aug 2024 08:12:34 +0900 Subject: [PATCH] io_uring: Add .errdetails to parse CQ status Background - fio normally prints out the strerr and errno value when facing errors. In case of io_uring_cmd ioengine with --cmd_type=nvme, io_u->error represents the CQ entry status code type and status code which should be parsed as a NVMe error value rather than errno. In io_u error failure condition, it prints out parsed CQ entry error status values with SCT(Status Code Type) and SC(Status Code). The print will be like the following example: fio: io_uring_cmd: /dev/ng0n1: cq entry status (sct=0x00; sc=0x04) For the further use cases of --cmd_type!=nvme, this patch checks the given io_u's file is NVMe generic device or not. If not, it prints out generic status code like below: fio: io_uring_cmd: /dev/: status=0x4 Signed-off-by: Minwoo Im --- engines/io_uring.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/engines/io_uring.c b/engines/io_uring.c index 334c77b9ed..bfbdc3b4b4 100644 --- a/engines/io_uring.c +++ b/engines/io_uring.c @@ -554,6 +554,39 @@ static struct io_u *fio_ioring_cmd_event(struct thread_data *td, int event) return io_u; } +static char *fio_ioring_cmd_errdetails(struct thread_data *td, + struct io_u *io_u) +{ + struct ioring_options *o = td->eo; + unsigned int sct = (io_u->error >> 8) & 0x7; + unsigned int sc = io_u->error & 0xff; +#define MAXERRDETAIL 1024 +#define MAXMSGCHUNK 128 + char *msg, msgchunk[MAXMSGCHUNK]; + + msg = calloc(1, MAXERRDETAIL); + strcpy(msg, "io_uring_cmd: "); + + snprintf(msgchunk, MAXMSGCHUNK, "%s: ", io_u->file->file_name); + strlcat(msg, msgchunk, MAXERRDETAIL); + + if (o->cmd_type == FIO_URING_CMD_NVME) { + strlcat(msg, "cq entry status (", MAXERRDETAIL); + + snprintf(msgchunk, MAXMSGCHUNK, "sct=0x%02x; ", sct); + strlcat(msg, msgchunk, MAXERRDETAIL); + + snprintf(msgchunk, MAXMSGCHUNK, "sc=0x%02x)", sc); + strlcat(msg, msgchunk, MAXERRDETAIL); + } else { + /* Print status code in generic */ + snprintf(msgchunk, MAXMSGCHUNK, "status=0x%x", io_u->error); + strlcat(msg, msgchunk, MAXERRDETAIL); + } + + return msg; +} + static int fio_ioring_cqring_reap(struct thread_data *td, unsigned int events, unsigned int max) { @@ -1590,6 +1623,7 @@ static struct ioengine_ops ioengine_uring_cmd = { .commit = fio_ioring_commit, .getevents = fio_ioring_getevents, .event = fio_ioring_cmd_event, + .errdetails = fio_ioring_cmd_errdetails, .cleanup = fio_ioring_cleanup, .open_file = fio_ioring_cmd_open_file, .close_file = fio_ioring_cmd_close_file,