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.

ublk: remove io_cmds list in ublk_queue

The current I/O dispatch mechanism - queueing I/O by adding it to the
io_cmds list (and poking task_work as needed), then dispatching it in
ublk server task context by reversing io_cmds and completing the
io_uring command associated to each one - was introduced by commit
7d4a93176e014 ("ublk_drv: don't forward io commands in reserve order")
to ensure that the ublk server received I/O in the same order that the
block layer submitted it to ublk_drv. This mechanism was only needed for
the "raw" task_work submission mechanism, since the io_uring task work
wrapper maintains FIFO ordering (using quite a similar mechanism in
fact). The "raw" task_work submission mechanism is no longer supported
in ublk_drv as of commit 29dc5d06613f2 ("ublk: kill queuing request by
task_work_add"), so the explicit llist/reversal is no longer needed - it
just duplicates logic already present in the underlying io_uring APIs.
Remove it.

Signed-off-by: Uday Shankar <ushankar@purestorage.com>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20250318-ublk_io_cmds-v1-1-c1bb74798fef@purestorage.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Uday Shankar and committed by
Jens Axboe
989bcd62 e1a0202c

+11 -35
+11 -35
drivers/block/ublk_drv.c
··· 74 74 UBLK_PARAM_TYPE_DMA_ALIGN) 75 75 76 76 struct ublk_rq_data { 77 - struct llist_node node; 78 - 79 77 struct kref ref; 80 78 }; 81 79 ··· 139 141 unsigned long flags; 140 142 struct task_struct *ubq_daemon; 141 143 char *io_cmd_buf; 142 - 143 - struct llist_head io_cmds; 144 144 145 145 unsigned long io_addr; /* mapped vm address */ 146 146 unsigned int max_io_sz; ··· 1104 1108 } 1105 1109 1106 1110 /* 1107 - * Since __ublk_rq_task_work always fails requests immediately during 1111 + * Since ublk_rq_task_work_cb always fails requests immediately during 1108 1112 * exiting, __ublk_fail_req() is only called from abort context during 1109 1113 * exiting. So lock is unnecessary. 1110 1114 * ··· 1150 1154 blk_mq_end_request(rq, BLK_STS_IOERR); 1151 1155 } 1152 1156 1153 - static inline void __ublk_rq_task_work(struct request *req, 1154 - unsigned issue_flags) 1157 + static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd, 1158 + unsigned int issue_flags) 1155 1159 { 1156 - struct ublk_queue *ubq = req->mq_hctx->driver_data; 1157 - int tag = req->tag; 1160 + struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd); 1161 + struct ublk_queue *ubq = pdu->ubq; 1162 + int tag = pdu->tag; 1163 + struct request *req = blk_mq_tag_to_rq( 1164 + ubq->dev->tag_set.tags[ubq->q_id], tag); 1158 1165 struct ublk_io *io = &ubq->ios[tag]; 1159 1166 unsigned int mapped_bytes; 1160 1167 ··· 1232 1233 ubq_complete_io_cmd(io, UBLK_IO_RES_OK, issue_flags); 1233 1234 } 1234 1235 1235 - static inline void ublk_forward_io_cmds(struct ublk_queue *ubq, 1236 - unsigned issue_flags) 1237 - { 1238 - struct llist_node *io_cmds = llist_del_all(&ubq->io_cmds); 1239 - struct ublk_rq_data *data, *tmp; 1240 - 1241 - io_cmds = llist_reverse_order(io_cmds); 1242 - llist_for_each_entry_safe(data, tmp, io_cmds, node) 1243 - __ublk_rq_task_work(blk_mq_rq_from_pdu(data), issue_flags); 1244 - } 1245 - 1246 - static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd, unsigned issue_flags) 1247 - { 1248 - struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd); 1249 - struct ublk_queue *ubq = pdu->ubq; 1250 - 1251 - ublk_forward_io_cmds(ubq, issue_flags); 1252 - } 1253 - 1254 1236 static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq) 1255 1237 { 1256 - struct ublk_rq_data *data = blk_mq_rq_to_pdu(rq); 1238 + struct ublk_io *io = &ubq->ios[rq->tag]; 1257 1239 1258 - if (llist_add(&data->node, &ubq->io_cmds)) { 1259 - struct ublk_io *io = &ubq->ios[rq->tag]; 1260 - 1261 - io_uring_cmd_complete_in_task(io->cmd, ublk_rq_task_work_cb); 1262 - } 1240 + io_uring_cmd_complete_in_task(io->cmd, ublk_rq_task_work_cb); 1263 1241 } 1264 1242 1265 1243 static enum blk_eh_timer_return ublk_timeout(struct request *rq) ··· 1429 1453 struct request *rq; 1430 1454 1431 1455 /* 1432 - * Either we fail the request or ublk_rq_task_work_fn 1456 + * Either we fail the request or ublk_rq_task_work_cb 1433 1457 * will do it 1434 1458 */ 1435 1459 rq = blk_mq_tag_to_rq(ub->tag_set.tags[ubq->q_id], i);