Skip to content

Commit

Permalink
fallback to ioctl for the old kernels without io_uring support
Browse files Browse the repository at this point in the history
1. add a global variable io_uring_kernel_support to track status
2. run nvme_uring_cmd_probe once on the library loading time

Signed-off-by: letli <[email protected]>
  • Loading branch information
996refuse committed Dec 12, 2024
1 parent 4b79140 commit d2ff8ca
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 18 deletions.
2 changes: 1 addition & 1 deletion meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ option('openssl', type : 'feature', value: 'auto', description : 'OpenSSL suppor
option('libdbus', type : 'feature', value: 'disabled', description : 'libdbus support')
option('json-c', type : 'feature', value: 'auto', description : 'JSON support')
option('keyutils', type: 'feature', value: 'auto', description: 'keyutils support')
option('liburing', type : 'feature', value: 'disabled', description : 'liburing support')
option('liburing', type : 'feature', value: 'auto', description : 'liburing support')
44 changes: 27 additions & 17 deletions src/nvme/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,13 +320,25 @@ int nvme_get_log(struct nvme_get_log_args *args)
}

#ifdef CONFIG_LIBURING
static int nvme_uring_cmd_setup(struct io_uring *ring)
enum {
IO_URING_NOT_AVAILABLE,
IO_URING_AVAILABLE,
} io_uring_kernel_support = IO_URING_NOT_AVAILABLE;

/*
* gcc specific attribute, call automatically on the library loading.
* if IORING_OP_URING_CMD is not supported, fallback to ioctl interface.
*/
__attribute__((constructor))
static void nvme_uring_cmd_probe()
{
struct io_uring_probe *probe = io_uring_get_probe();
if (!io_uring_opcode_supported(probe, IORING_OP_URING_CMD)) {
if (NULL != probe && io_uring_opcode_supported(probe, IORING_OP_URING_CMD))
io_uring_kernel_support = IO_URING_AVAILABLE;
}

return -1;
}
static int nvme_uring_cmd_setup(struct io_uring *ring)
{
return io_uring_queue_init(NVME_URING_ENTRIES, ring, IORING_SETUP_SQE128 | IORING_SETUP_CQE32);
}

Expand Down Expand Up @@ -411,14 +423,14 @@ int nvme_get_log_page(int fd, __u32 xfer_len, struct nvme_get_log_args *args)

args->fd = fd;

bool fallback = true;
#ifdef CONFIG_LIBURING
struct io_uring ring;
int n = 0;
ret = nvme_uring_cmd_setup(&ring);
/* IORING_OP_URING_CMD is not supported, fallback ioctl interface. */
if (!ret)
fallback = false;
struct io_uring ring;
if (io_uring_kernel_support == IO_URING_AVAILABLE) {
ret = nvme_uring_cmd_setup(&ring);
if (ret)
return -1;
}
#endif
/*
* 4k is the smallest possible transfer unit, so restricting to 4k
Expand All @@ -438,18 +450,17 @@ int nvme_get_log_page(int fd, __u32 xfer_len, struct nvme_get_log_args *args)
args->len = xfer;
args->log = ptr;
args->rae = offset + xfer < data_len || retain;
if (fallback)
ret = nvme_get_log(args);
#ifdef CONFIG_LIBURING
else {
if (io_uring_kernel_support == IO_URING_AVAILABLE) {
if (n >= NVME_URING_ENTRIES) {
nvme_uring_cmd_wait_complete(&ring, n);
n = 0;
}
n += 1;
ret = nvme_uring_cmd_admin_passthru_async(&ring, args);
}
} else
#endif
ret = nvme_get_log(args);
if (ret)
return ret;

Expand All @@ -458,14 +469,13 @@ int nvme_get_log_page(int fd, __u32 xfer_len, struct nvme_get_log_args *args)
} while (offset < data_len);

#ifdef CONFIG_LIBURING
if (!fallback) {
if (io_uring_kernel_support == IO_URING_AVAILABLE) {
ret = nvme_uring_cmd_wait_complete(&ring, n);
nvme_uring_cmd_exit(&ring);
if (ret < 0)
return -1;
nvme_uring_cmd_exit(&ring);
}
#endif

return 0;
}

Expand Down

0 comments on commit d2ff8ca

Please sign in to comment.