* [PATCH blktests] nvme/067: test io_uring pass through for NVMe admin queue
@ 2026-01-29 2:37 sw.prabhu6
2026-01-30 3:49 ` Shinichiro Kawasaki
0 siblings, 1 reply; 2+ messages in thread
From: sw.prabhu6 @ 2026-01-29 2:37 UTC (permalink / raw)
To: linux-block, shinichiro.kawasaki; +Cc: vincentfu, joshi.k, Swarna Prabhu
From: Swarna Prabhu <s.prabhu@samsung.com>
Simple test to excersie the nvme admin commands usage with
io uring passthrough interfaces.
Signed-off-by: Swarna Prabhu <s.prabhu@samsung.com>
---
src/Makefile | 3 +-
src/nvme-passthrough-admin.c | 94 ++++++++++++++++++++++++++++++++++++
tests/nvme/067 | 27 +++++++++++
tests/nvme/067.out | 2 +
4 files changed, 125 insertions(+), 1 deletion(-)
mode change 100644 => 100755 src/Makefile
create mode 100755 src/nvme-passthrough-admin.c
create mode 100755 tests/nvme/067
create mode 100755 tests/nvme/067.out
diff --git a/src/Makefile b/src/Makefile
old mode 100644
new mode 100755
index dac07c7..0cb8d4e
--- a/src/Makefile
+++ b/src/Makefile
@@ -23,7 +23,8 @@ C_TARGETS := \
zbdioctl
C_URING_TARGETS := miniublk \
- metadata
+ metadata \
+ nvme-passthrough-admin
HAVE_LIBURING := $(call HAVE_C_MACRO,liburing.h,IORING_OP_URING_CMD)
HAVE_UBLK_HEADER := $(call HAVE_C_HEADER,linux/ublk_cmd.h,1)
diff --git a/src/nvme-passthrough-admin.c b/src/nvme-passthrough-admin.c
new file mode 100755
index 0000000..ef5c241
--- /dev/null
+++ b/src/nvme-passthrough-admin.c
@@ -0,0 +1,94 @@
+/*
+ * Simple test exercising the admin queue accesses via io_uring passthrough
+ * commands.
+ */
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <liburing.h>
+#include <linux/nvme_ioctl.h>
+
+#define NVME_IDENTIFY_ADMIN_CMD 0x06 /*Identify command using admin queue */
+#define NVME_IDENTIFY_CNS_CTRL 0x01 /*Identify controller command to a NVME device*/
+struct nvme_id_ctrl {
+ __le16 vid;
+ __le16 ssvid;
+ char sn[20];
+ char mn[40];
+ char fr[8];
+ __u8 rab;
+ __u8 ieee[3];
+ char pad[4020];
+};
+
+int main(int argc, char **argv)
+{
+ int fd, ret;
+ struct nvme_passthru_cmd *cmd;
+ struct nvme_id_ctrl *nctrl;
+ struct io_uring nvring;
+ int queue_depth = 80;
+ struct io_uring_sqe *sqe = NULL;
+ struct io_uring_cqe *cqe = NULL;
+
+ if (argc < 2) {
+ fprintf(stderr, "usage: %s /dev/nvmeXnY", argv[0]);
+ return -EINVAL;
+ }
+
+ fd = open(argv[1], O_RDONLY);
+ if (fd < 0) {
+ perror("open");
+ return -errno;
+ }
+
+ nctrl = (struct nvme_id_ctrl *)calloc(1, sizeof(struct nvme_id_ctrl));
+ if (!nctrl) {
+ fprintf(stderr, "Memory allocation failure\n");
+ return -ENOMEM;
+ }
+
+ ret = io_uring_queue_init(queue_depth, &nvring, IORING_SETUP_SQE128 | IORING_SETUP_CQE32);
+ if (ret < 0) {
+ fprintf(stderr, "Initialize io uring fail %d \n", ret);
+ return ret;
+ }
+ /* Prepare the SQE to use the IORING_OP_URING_CMD opcode */
+ sqe = io_uring_get_sqe(&nvring);
+ sqe->fd = fd;
+ sqe->opcode = IORING_OP_URING_CMD;
+ sqe->cmd_op = NVME_URING_CMD_ADMIN;
+
+ cmd = (struct nvme_passthru_cmd *)&sqe->cmd;
+ memset(cmd, 0, sizeof(*cmd));
+
+ /* populate the cmd struct for the opcode */
+ cmd->opcode = NVME_IDENTIFY_ADMIN_CMD;
+ cmd->addr = (__u64)(uintptr_t)nctrl;
+ cmd->data_len = sizeof(struct nvme_id_ctrl);
+ cmd->cdw10 = NVME_IDENTIFY_CNS_CTRL;
+
+ /*submit the SQE */
+ io_uring_submit(&nvring);
+
+ ret = io_uring_wait_cqe(&nvring, &cqe);
+
+ if (ret < 0) {
+ fprintf(stderr, "wait_cqe: %s\n", strerror(-ret));
+ } else if (cqe && cqe->res < 0) {
+ fprintf(stderr, "Command failed (cqe->res): %d\n", cqe->res);
+ ret = cqe->res;
+ } else {
+ ret = 0;
+ }
+
+ if (cqe)
+ io_uring_cqe_seen(&nvring, cqe);
+ io_uring_queue_exit(&nvring);
+ close(fd);
+ free(nctrl);
+
+ return ret;
+}
\ No newline at end of file
diff --git a/tests/nvme/067 b/tests/nvme/067
new file mode 100755
index 0000000..8c273fa
--- /dev/null
+++ b/tests/nvme/067
@@ -0,0 +1,27 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0+
+# Test out admin commands through the io uring passthrough interfaces.
+
+. tests/nvme/rc
+
+requires() {
+ _nvme_requires
+ _have_kernel_option IO_URING
+}
+
+DESCRIPTION="exercise the nvme admin commands usage with io uring passthrough interfaces"
+QUICK=1
+
+test_device() {
+ echo "Running ${TEST_NAME}"
+
+ # extract the ctrl dev from the test dev
+ devname=${TEST_DEV#/dev/}
+ ctrl_dev="/dev/${devname%n*}"
+
+ if ! sudo src/nvme-passthrough-admin "${ctrl_dev}"; then
+ echo "src/nvme-passthrough-admin failed"
+ fi
+
+ echo "Test Complete"
+}
diff --git a/tests/nvme/067.out b/tests/nvme/067.out
new file mode 100755
index 0000000..c56866e
--- /dev/null
+++ b/tests/nvme/067.out
@@ -0,0 +1,2 @@
+Running nvme/067
+Test Complete
--
2.39.5
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH blktests] nvme/067: test io_uring pass through for NVMe admin queue
2026-01-29 2:37 [PATCH blktests] nvme/067: test io_uring pass through for NVMe admin queue sw.prabhu6
@ 2026-01-30 3:49 ` Shinichiro Kawasaki
0 siblings, 0 replies; 2+ messages in thread
From: Shinichiro Kawasaki @ 2026-01-30 3:49 UTC (permalink / raw)
To: sw.prabhu6@gmail.com
Cc: linux-block@vger.kernel.org, vincentfu@gmail.com,
joshi.k@samsung.com, Swarna Prabhu
Hello Swarna, thank yo for this patch. I ran the test case and it looks
working good. Please find my reivew comments in line.
May I know the background to add this test case? Is it relevant to any kernel
side fix? (If so, I would like to have a link to the fix) Or does it intend to
extend kernel code coverage?
On Jan 28, 2026 / 18:37, sw.prabhu6@gmail.com wrote:
> From: Swarna Prabhu <s.prabhu@samsung.com>
>
> Simple test to excersie the nvme admin commands usage with
s/excersie/exercise/
> io uring passthrough interfaces.
>
> Signed-off-by: Swarna Prabhu <s.prabhu@samsung.com>
> ---
> src/Makefile | 3 +-
> src/nvme-passthrough-admin.c | 94 ++++++++++++++++++++++++++++++++++++
> tests/nvme/067 | 27 +++++++++++
> tests/nvme/067.out | 2 +
> 4 files changed, 125 insertions(+), 1 deletion(-)
> mode change 100644 => 100755 src/Makefile
> create mode 100755 src/nvme-passthrough-admin.c
> create mode 100755 tests/nvme/067
> create mode 100755 tests/nvme/067.out
>
> diff --git a/src/Makefile b/src/Makefile
> old mode 100644
> new mode 100755
No need to change the file mode of src/Makefile.
> index dac07c7..0cb8d4e
> --- a/src/Makefile
> +++ b/src/Makefile
> @@ -23,7 +23,8 @@ C_TARGETS := \
> zbdioctl
>
> C_URING_TARGETS := miniublk \
> - metadata
> + metadata \
> + nvme-passthrough-admin
Nit: the name of the program does not show that io_uring is used. To show it,
I suggest the program name "nvme-passthru-admin-uring.c".
>
> HAVE_LIBURING := $(call HAVE_C_MACRO,liburing.h,IORING_OP_URING_CMD)
> HAVE_UBLK_HEADER := $(call HAVE_C_HEADER,linux/ublk_cmd.h,1)
> diff --git a/src/nvme-passthrough-admin.c b/src/nvme-passthrough-admin.c
> new file mode 100755
I think file mode 644 is apporopriate for .c files.
> index 0000000..ef5c241
> --- /dev/null
> +++ b/src/nvme-passthrough-admin.c
> @@ -0,0 +1,94 @@
SPDX-License-Identifier and your copyright are missing.
> +/*
> + * Simple test exercising the admin queue accesses via io_uring passthrough
> + * commands.
> + */
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <liburing.h>
> +#include <linux/nvme_ioctl.h>
> +
> +#define NVME_IDENTIFY_ADMIN_CMD 0x06 /*Identify command using admin queue */
> +#define NVME_IDENTIFY_CNS_CTRL 0x01 /*Identify controller command to a NVME device*/
Nit: some comments in this file do not have a space after the comment start
"/*".
> +struct nvme_id_ctrl {
> + __le16 vid;
> + __le16 ssvid;
> + char sn[20];
> + char mn[40];
> + char fr[8];
> + __u8 rab;
> + __u8 ieee[3];
> + char pad[4020];
Spaces are used for ident in the above lines. I suggest to use tabs instead.
> +};
> +
> +int main(int argc, char **argv)
> +{
> + int fd, ret;
> + struct nvme_passthru_cmd *cmd;
> + struct nvme_id_ctrl *nctrl;
> + struct io_uring nvring;
> + int queue_depth = 80;
> + struct io_uring_sqe *sqe = NULL;
> + struct io_uring_cqe *cqe = NULL;
> +
> + if (argc < 2) {
> + fprintf(stderr, "usage: %s /dev/nvmeXnY", argv[0]);
Nit: I suggest to add "\n" to the end of the usage message.
> + return -EINVAL;
> + }
> +
> + fd = open(argv[1], O_RDONLY);
> + if (fd < 0) {
> + perror("open");
> + return -errno;
> + }
> +
> + nctrl = (struct nvme_id_ctrl *)calloc(1, sizeof(struct nvme_id_ctrl));
> + if (!nctrl) {
> + fprintf(stderr, "Memory allocation failure\n");
> + return -ENOMEM;
Nit: Its a userspace program and we do not care much about resource clean up,
but it would be a bit better to "ret = -ENOMEM" and "goto" to the line of
close(fd).
> + }
> +
> + ret = io_uring_queue_init(queue_depth, &nvring, IORING_SETUP_SQE128 | IORING_SETUP_CQE32);
> + if (ret < 0) {
> + fprintf(stderr, "Initialize io uring fail %d \n", ret);
Nit: same, it's a better go goto to the line of free(nctrl).
> + return ret;
> + }
> + /* Prepare the SQE to use the IORING_OP_URING_CMD opcode */
> + sqe = io_uring_get_sqe(&nvring);
> + sqe->fd = fd;
> + sqe->opcode = IORING_OP_URING_CMD;
> + sqe->cmd_op = NVME_URING_CMD_ADMIN;
> +
> + cmd = (struct nvme_passthru_cmd *)&sqe->cmd;
> + memset(cmd, 0, sizeof(*cmd));
> +
> + /* populate the cmd struct for the opcode */
> + cmd->opcode = NVME_IDENTIFY_ADMIN_CMD;
> + cmd->addr = (__u64)(uintptr_t)nctrl;
> + cmd->data_len = sizeof(struct nvme_id_ctrl);
> + cmd->cdw10 = NVME_IDENTIFY_CNS_CTRL;
> +
> + /*submit the SQE */
> + io_uring_submit(&nvring);
> +
> + ret = io_uring_wait_cqe(&nvring, &cqe);
> +
> + if (ret < 0) {
> + fprintf(stderr, "wait_cqe: %s\n", strerror(-ret));
> + } else if (cqe && cqe->res < 0) {
> + fprintf(stderr, "Command failed (cqe->res): %d\n", cqe->res);
> + ret = cqe->res;
> + } else {
> + ret = 0;
> + }
> +
> + if (cqe)
> + io_uring_cqe_seen(&nvring, cqe);
> + io_uring_queue_exit(&nvring);
> + close(fd);
> + free(nctrl);
Nit: To allow goto from the error paths, the order of the two lines above
can be reversed:
free_nctrl:
free(nctrl);
free_fd:
close(fd);
> +
> + return ret;
> +}
> \ No newline at end of file
> diff --git a/tests/nvme/067 b/tests/nvme/067
> new file mode 100755
> index 0000000..8c273fa
> --- /dev/null
> +++ b/tests/nvme/067
> @@ -0,0 +1,27 @@
> +#!/bin/bash
> +# SPDX-License-Identifier: GPL-3.0+
> +# Test out admin commands through the io uring passthrough interfaces.
> +
> +. tests/nvme/rc
> +
> +requires() {
> + _nvme_requires
> + _have_kernel_option IO_URING
> +}
> +
> +DESCRIPTION="exercise the nvme admin commands usage with io uring passthrough interfaces"
> +QUICK=1
> +
> +test_device() {
> + echo "Running ${TEST_NAME}"
> +
> + # extract the ctrl dev from the test dev
> + devname=${TEST_DEV#/dev/}
> + ctrl_dev="/dev/${devname%n*}"
I suggest to add _io_uring_enable here,
> +
> + if ! sudo src/nvme-passthrough-admin "${ctrl_dev}"; then
> + echo "src/nvme-passthrough-admin failed"
> + fi
and _io_uring_restore here, just in case the system has
/proc/sys/kernel/io_uring_disabled value "2".
> +
> + echo "Test Complete"
> +}
> diff --git a/tests/nvme/067.out b/tests/nvme/067.out
> new file mode 100755
I suggest to run "make check" or "make check-parallel" before blktests patch
post. It reports that 067.out should have the file mode 644 instead of 755.
$ make check-parallel
Running shellcheck with 4 parallel jobs...
./tests/nvme/067.out is executable
> index 0000000..c56866e
> --- /dev/null
> +++ b/tests/nvme/067.out
> @@ -0,0 +1,2 @@
> +Running nvme/067
> +Test Complete
> --
> 2.39.5
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-01-30 3:49 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-29 2:37 [PATCH blktests] nvme/067: test io_uring pass through for NVMe admin queue sw.prabhu6
2026-01-30 3:49 ` Shinichiro Kawasaki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox