Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

io_uring: Pass whole sqe to commands

Currently uring CMD operation relies on having large SQEs, but future
operations might want to use normal SQE.

The io_uring_cmd currently only saves the payload (cmd) part of the SQE,
but, for commands that use normal SQE size, it might be necessary to
access the initial SQE fields outside of the payload/cmd block. So,
saves the whole SQE other than just the pdu.

This changes slightly how the io_uring_cmd works, since the cmd
structures and callbacks are not opaque to io_uring anymore. I.e, the
callbacks can look at the SQE entries, not only, in the cmd structure.

The main advantage is that we don't need to create custom structures for
simple commands.

Creates io_uring_sqe_cmd() that returns the cmd private data as a null
pointer and avoids casting in the callee side.
Also, make most of ublk_drv's sqe->cmd priv structure into const, and use
io_uring_sqe_cmd() to get the private structure, removing the unwanted
cast. (There is one case where the cast is still needed since the
header->{len,addr} is updated in the private structure)

Suggested-by: Pavel Begunkov <asml.silence@gmail.com>
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/20230504121856.904491-3-leitao@debian.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Breno Leitao and committed by
Jens Axboe
fd9b8547 96c7d4f8

+24 -22
+13 -13
drivers/block/ublk_drv.c
··· 1019 1019 } 1020 1020 1021 1021 static void ublk_commit_completion(struct ublk_device *ub, 1022 - struct ublksrv_io_cmd *ub_cmd) 1022 + const struct ublksrv_io_cmd *ub_cmd) 1023 1023 { 1024 1024 u32 qid = ub_cmd->q_id, tag = ub_cmd->tag; 1025 1025 struct ublk_queue *ubq = ublk_get_queue(ub, qid); ··· 1263 1263 1264 1264 static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) 1265 1265 { 1266 - struct ublksrv_io_cmd *ub_cmd = (struct ublksrv_io_cmd *)cmd->cmd; 1266 + const struct ublksrv_io_cmd *ub_cmd = io_uring_sqe_cmd(cmd->sqe); 1267 1267 struct ublk_device *ub = cmd->file->private_data; 1268 1268 struct ublk_queue *ubq; 1269 1269 struct ublk_io *io; ··· 1567 1567 1568 1568 static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd) 1569 1569 { 1570 - struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd; 1570 + const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); 1571 1571 int ublksrv_pid = (int)header->data[0]; 1572 1572 struct gendisk *disk; 1573 1573 int ret = -EINVAL; ··· 1630 1630 static int ublk_ctrl_get_queue_affinity(struct ublk_device *ub, 1631 1631 struct io_uring_cmd *cmd) 1632 1632 { 1633 - struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd; 1633 + const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); 1634 1634 void __user *argp = (void __user *)(unsigned long)header->addr; 1635 1635 cpumask_var_t cpumask; 1636 1636 unsigned long queue; ··· 1681 1681 1682 1682 static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd) 1683 1683 { 1684 - struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd; 1684 + const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); 1685 1685 void __user *argp = (void __user *)(unsigned long)header->addr; 1686 1686 struct ublksrv_ctrl_dev_info info; 1687 1687 struct ublk_device *ub; ··· 1844 1844 1845 1845 static inline void ublk_ctrl_cmd_dump(struct io_uring_cmd *cmd) 1846 1846 { 1847 - struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd; 1847 + const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); 1848 1848 1849 1849 pr_devel("%s: cmd_op %x, dev id %d qid %d data %llx buf %llx len %u\n", 1850 1850 __func__, cmd->cmd_op, header->dev_id, header->queue_id, ··· 1863 1863 static int ublk_ctrl_get_dev_info(struct ublk_device *ub, 1864 1864 struct io_uring_cmd *cmd) 1865 1865 { 1866 - struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd; 1866 + const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); 1867 1867 void __user *argp = (void __user *)(unsigned long)header->addr; 1868 1868 1869 1869 if (header->len < sizeof(struct ublksrv_ctrl_dev_info) || !header->addr) ··· 1894 1894 static int ublk_ctrl_get_params(struct ublk_device *ub, 1895 1895 struct io_uring_cmd *cmd) 1896 1896 { 1897 - struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd; 1897 + const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); 1898 1898 void __user *argp = (void __user *)(unsigned long)header->addr; 1899 1899 struct ublk_params_header ph; 1900 1900 int ret; ··· 1925 1925 static int ublk_ctrl_set_params(struct ublk_device *ub, 1926 1926 struct io_uring_cmd *cmd) 1927 1927 { 1928 - struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd; 1928 + const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); 1929 1929 void __user *argp = (void __user *)(unsigned long)header->addr; 1930 1930 struct ublk_params_header ph; 1931 1931 int ret = -EFAULT; ··· 1983 1983 static int ublk_ctrl_start_recovery(struct ublk_device *ub, 1984 1984 struct io_uring_cmd *cmd) 1985 1985 { 1986 - struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd; 1986 + const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); 1987 1987 int ret = -EINVAL; 1988 1988 int i; 1989 1989 ··· 2025 2025 static int ublk_ctrl_end_recovery(struct ublk_device *ub, 2026 2026 struct io_uring_cmd *cmd) 2027 2027 { 2028 - struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd; 2028 + const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); 2029 2029 int ublksrv_pid = (int)header->data[0]; 2030 2030 int ret = -EINVAL; 2031 2031 ··· 2092 2092 static int ublk_ctrl_uring_cmd_permission(struct ublk_device *ub, 2093 2093 struct io_uring_cmd *cmd) 2094 2094 { 2095 - struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd; 2095 + struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)io_uring_sqe_cmd(cmd->sqe); 2096 2096 bool unprivileged = ub->dev_info.flags & UBLK_F_UNPRIVILEGED_DEV; 2097 2097 void __user *argp = (void __user *)(unsigned long)header->addr; 2098 2098 char *dev_path = NULL; ··· 2171 2171 static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd, 2172 2172 unsigned int issue_flags) 2173 2173 { 2174 - struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd; 2174 + const struct ublksrv_ctrl_cmd *header = io_uring_sqe_cmd(cmd->sqe); 2175 2175 struct ublk_device *ub = NULL; 2176 2176 int ret = -EINVAL; 2177 2177
+1 -1
drivers/nvme/host/ioctl.c
··· 552 552 struct io_uring_cmd *ioucmd, unsigned int issue_flags, bool vec) 553 553 { 554 554 struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd); 555 - const struct nvme_uring_cmd *cmd = ioucmd->cmd; 555 + const struct nvme_uring_cmd *cmd = io_uring_sqe_cmd(ioucmd->sqe); 556 556 struct request_queue *q = ns ? ns->queue : ctrl->admin_q; 557 557 struct nvme_uring_data d; 558 558 struct nvme_command c;
+6 -1
include/linux/io_uring.h
··· 24 24 25 25 struct io_uring_cmd { 26 26 struct file *file; 27 - const void *cmd; 27 + const struct io_uring_sqe *sqe; 28 28 union { 29 29 /* callback to defer completions to task context */ 30 30 void (*task_work_cb)(struct io_uring_cmd *cmd, unsigned); ··· 65 65 { 66 66 if (tsk->io_uring) 67 67 __io_uring_free(tsk); 68 + } 69 + 70 + static inline const void *io_uring_sqe_cmd(const struct io_uring_sqe *sqe) 71 + { 72 + return sqe->cmd; 68 73 } 69 74 #else 70 75 static inline int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw,
+1 -1
io_uring/opdef.c
··· 627 627 }, 628 628 [IORING_OP_URING_CMD] = { 629 629 .name = "URING_CMD", 630 - .async_size = uring_cmd_pdu_size(1), 630 + .async_size = 2 * sizeof(struct io_uring_sqe), 631 631 .prep_async = io_uring_cmd_prep_async, 632 632 }, 633 633 [IORING_OP_SEND_ZC] = {
+3 -6
io_uring/uring_cmd.c
··· 69 69 int io_uring_cmd_prep_async(struct io_kiocb *req) 70 70 { 71 71 struct io_uring_cmd *ioucmd = io_kiocb_to_cmd(req, struct io_uring_cmd); 72 - size_t cmd_size; 73 72 74 73 BUILD_BUG_ON(uring_cmd_pdu_size(0) != 16); 75 74 BUILD_BUG_ON(uring_cmd_pdu_size(1) != 80); 76 75 77 - cmd_size = uring_cmd_pdu_size(req->ctx->flags & IORING_SETUP_SQE128); 78 - 79 - memcpy(req->async_data, ioucmd->cmd, cmd_size); 80 - ioucmd->cmd = req->async_data; 76 + memcpy(req->async_data, ioucmd->sqe, uring_sqe_size(req->ctx)); 77 + ioucmd->sqe = req->async_data; 81 78 return 0; 82 79 } 83 80 ··· 100 103 req->imu = ctx->user_bufs[index]; 101 104 io_req_set_rsrc_node(req, ctx, 0); 102 105 } 103 - ioucmd->cmd = sqe->cmd; 106 + ioucmd->sqe = sqe; 104 107 ioucmd->cmd_op = READ_ONCE(sqe->cmd_op); 105 108 return 0; 106 109 }