Skip to content

Commit

Permalink
io_uring: Add IO_U_F_DEVICE_ERROR to identify error types
Browse files Browse the repository at this point in the history
__io_u_log_error expects a positive value of io_u->error parsing it with
strerror() expecting it to be an errno.  io_uring_cmd (cmd_type=nvme),
for example, has returned errno value as a positive value and
device-specific CQE status type and code as well.

Commit 78831c6 ("io_uring: Fix the flip to negative of CQE status")
has put the abs() to the cqe->res, and it caused confusions between the
actual CQE stauts and the system error value (errno).  Now we have
Commit 2a13699 ("io_uring: Add .errdetails to parse CQ status"),
meaning that io_uring_cmd ioengines will parse the actual value of
io_u->error value as CQE status value, so we should know if the value is
for CQE status or errno.

This patch added a flag IO_U_F_DEVICE_ERROR to io_u to represent if
io_u->error has device-specific error value, otherwise it's errno.

Signed-off-by: Minwoo Im <minwoo.im.dev@gmail.com>
Link: https://lore.kernel.org/r/20240926004134.26004-1-minwoo.im.dev@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
minwooim authored and axboe committed Sep 26, 2024
1 parent 12c4b85 commit ebe67b6
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 9 deletions.
22 changes: 16 additions & 6 deletions engines/io_uring.c
Original file line number Diff line number Diff line change
Expand Up @@ -528,12 +528,9 @@ static struct io_u *fio_ioring_cmd_event(struct thread_data *td, int event)
cqe = &ld->cq_ring.cqes[index];
io_u = (struct io_u *) (uintptr_t) cqe->user_data;

if (cqe->res != 0) {
io_u->error = abs(cqe->res);
return io_u;
} else {
io_u->error = 0;
}
io_u->error = cqe->res;
if (io_u->error != 0)
goto ret;

if (o->cmd_type == FIO_URING_CMD_NVME) {
data = FILE_ENG_DATA(io_u->file);
Expand All @@ -544,6 +541,16 @@ static struct io_u *fio_ioring_cmd_event(struct thread_data *td, int event)
}
}

ret:
/*
* If IO_U_F_DEVICE_ERROR is not set, io_u->error will be parsed as an
* errno, otherwise device-specific error value (status value in CQE).
*/
if ((int)io_u->error > 0)
io_u_set(td, io_u, IO_U_F_DEVICE_ERROR);
else
io_u_clear(td, io_u, IO_U_F_DEVICE_ERROR);
io_u->error = abs(io_u->error);
return io_u;
}

Expand All @@ -557,6 +564,9 @@ static char *fio_ioring_cmd_errdetails(struct thread_data *td,
#define MAXMSGCHUNK 128
char *msg, msgchunk[MAXMSGCHUNK];

if (!(io_u->flags & IO_U_F_DEVICE_ERROR))
return NULL;

msg = calloc(1, MAXERRDETAIL);
strcpy(msg, "io_uring_cmd: ");

Expand Down
9 changes: 6 additions & 3 deletions io_u.c
Original file line number Diff line number Diff line change
Expand Up @@ -1956,7 +1956,8 @@ static void __io_u_log_error(struct thread_data *td, struct io_u *io_u)
log_err("fio: io_u error%s%s: %s: %s offset=%llu, buflen=%llu\n",
io_u->file ? " on file " : "",
io_u->file ? io_u->file->file_name : "",
strerror(io_u->error),
(io_u->flags & IO_U_F_DEVICE_ERROR) ?
"Device-specific error" : strerror(io_u->error),
io_ddir_name(io_u->ddir),
io_u->offset, io_u->xfer_buflen);

Expand All @@ -1965,8 +1966,10 @@ static void __io_u_log_error(struct thread_data *td, struct io_u *io_u)
if (td->io_ops->errdetails) {
char *err = td->io_ops->errdetails(td, io_u);

log_err("fio: %s\n", err);
free(err);
if (err) {
log_err("fio: %s\n", err);
free(err);
}
}

if (!td->error)
Expand Down
1 change: 1 addition & 0 deletions io_u.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ enum {
IO_U_F_BARRIER = 1 << 6,
IO_U_F_VER_LIST = 1 << 7,
IO_U_F_PATTERN_DONE = 1 << 8,
IO_U_F_DEVICE_ERROR = 1 << 9,
};

/*
Expand Down

0 comments on commit ebe67b6

Please sign in to comment.