Skip to content

Commit e6190dd

Browse files
old-memoriesaxboe
authored andcommitted
ublk_drv: do not add a re-issued request aborted previously to ioucmd's task_work
In ublk_queue_rq(), Assume current request is a re-issued request aborted previously in monitor_work because the ubq_daemon(ioucmd's task) is PF_EXITING. For this request, we cannot call io_uring_cmd_complete_in_task() anymore because at that moment io_uring context may be freed in case that no inflight ioucmd exists. Otherwise, we may cause null-deref in ctx->fallback_work. Add a check on UBLK_IO_FLAG_ABORTED to prevent the above situation. This check is safe and makes sense. Note: monitor_work sets UBLK_IO_FLAG_ABORTED and ends this request (releasing the tag). Then the request is restarted(allocating the tag) and we are here. Since releasing/allocating a tag implies smp_mb(), finding UBLK_IO_FLAG_ABORTED guarantees that here is a re-issued request aborted previously. Suggested-by: Ming Lei <[email protected]> Signed-off-by: ZiyangZhang <[email protected]> Reviewed-by: Ming Lei <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent bb24174 commit e6190dd

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

drivers/block/ublk_drv.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,9 +756,25 @@ static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx,
756756
if (task_work_add(ubq->ubq_daemon, &data->work, notify_mode))
757757
goto fail;
758758
} else {
759-
struct io_uring_cmd *cmd = ubq->ios[rq->tag].cmd;
759+
struct ublk_io *io = &ubq->ios[rq->tag];
760+
struct io_uring_cmd *cmd = io->cmd;
760761
struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd);
761762

763+
/*
764+
* If the check pass, we know that this is a re-issued request aborted
765+
* previously in monitor_work because the ubq_daemon(cmd's task) is
766+
* PF_EXITING. We cannot call io_uring_cmd_complete_in_task() anymore
767+
* because this ioucmd's io_uring context may be freed now if no inflight
768+
* ioucmd exists. Otherwise we may cause null-deref in ctx->fallback_work.
769+
*
770+
* Note: monitor_work sets UBLK_IO_FLAG_ABORTED and ends this request(releasing
771+
* the tag). Then the request is re-started(allocating the tag) and we are here.
772+
* Since releasing/allocating a tag implies smp_mb(), finding UBLK_IO_FLAG_ABORTED
773+
* guarantees that here is a re-issued request aborted previously.
774+
*/
775+
if ((io->flags & UBLK_IO_FLAG_ABORTED))
776+
goto fail;
777+
762778
pdu->req = rq;
763779
io_uring_cmd_complete_in_task(cmd, ublk_rq_task_work_cb);
764780
}

0 commit comments

Comments
 (0)