From: Swarna Prabhu Simple test to exercise the nvme admin commands usage with io uring passthrough interfaces. The motivation for the test is to extend the kernel code coverage for NVMe admin commands via io_uring passthrough. Signed-off-by: Swarna Prabhu --- Changes since v1: - Fixed typo in the git commit description and included motivation. - Revert the file mode of src/Makefile to 644 from 755. - Change src program name from "nvme-passthrough-admin.c" to "nvme-passthru-admin-uring.c". - Change the file mode of src/nvme-passthru-admin-uring.c from 755 to 644. - Added missing SPDX-License-Identifier and copyright in src/nvme-passthru-admin-uring.c - Add space after commment markers in src/nvme-passthru-admin-uring.c. - Added tab for indentation to 'struct nvme_id_ctrl' declaration in src/nvme-passthru-admin-uring.c. - Added missing "\n" to the end of fprintf statement in src/nvme-passthru-admin-uring.c. - Replaced direct return statements with goto to do resource clean up in src/nvme-passthru-admin-uring.c - Added missing copyright and SPDX-License-Identifier in tests/nvme/067 script. - Added '_io_uring_enable' and '_io_uring_restore' functions to script tests/nvme/067 to enable and restore io_uring setting for the test run. Link to v1: https://lore.kernel.org/all/20260129023754.685508-1-sw.prabhu6@gmail.com/ src/Makefile | 3 +- src/nvme-passthru-admin-uring.c | 100 ++++++++++++++++++++++++++++++++ tests/nvme/067 | 34 +++++++++++ tests/nvme/067.out | 2 + 4 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 src/nvme-passthru-admin-uring.c create mode 100755 tests/nvme/067 create mode 100644 tests/nvme/067.out diff --git a/src/Makefile b/src/Makefile index dac07c7..bd94636 100644 --- a/src/Makefile +++ b/src/Makefile @@ -23,7 +23,8 @@ C_TARGETS := \ zbdioctl C_URING_TARGETS := miniublk \ - metadata + metadata \ + nvme-passthru-admin-uring 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-passthru-admin-uring.c b/src/nvme-passthru-admin-uring.c new file mode 100644 index 0000000..d7868a6 --- /dev/null +++ b/src/nvme-passthru-admin-uring.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-3.0+ +// Copyright (C) 2026 Swarna Prabhu, Samsung Electronics +/* + * Simple test exercising the admin queue accesses via io_uring passthrough + * commands. + */ +#include +#include +#include +#include +#include +#include +#include + +#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\n", 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"); + ret = -ENOMEM; + goto free_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); + goto free_nctrl; + } + /* 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); +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..38d55ad --- /dev/null +++ b/tests/nvme/067 @@ -0,0 +1,34 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-3.0+ +# Copyright (C) 2026 Swarna Prabhu, Samsung Electronics +# 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*}" + + # enable io_uring when it is disabled + _io_uring_enable + + if ! sudo src/nvme-passthrough-admin "${ctrl_dev}"; then + echo "src/nvme-passthrough-admin failed" + fi + + # reset io_uring setting before test exits + _io_uring_restore + + echo "Test Complete" +} diff --git a/tests/nvme/067.out b/tests/nvme/067.out new file mode 100644 index 0000000..c56866e --- /dev/null +++ b/tests/nvme/067.out @@ -0,0 +1,2 @@ +Running nvme/067 +Test Complete -- 2.39.5