Skip to content

Commit dbc635c

Browse files
Ming Leiaxboe
authored andcommitted
ublk: move ublk_mark_io_ready() out of __ublk_fetch()
ublk_batch_prep_io() calls __ublk_fetch() while holding io->lock spinlock. When the last IO makes the device ready, ublk_mark_io_ready() tries to acquire ub->cancel_mutex which can sleep, causing a sleeping-while-atomic bug. Fix by moving ublk_mark_io_ready() out of __ublk_fetch() and into the callers (ublk_fetch and ublk_batch_prep_io) after the spinlock is released. Reported-by: Jens Axboe <[email protected]> Fixes: b256795 ("ublk: handle UBLK_U_IO_PREP_IO_CMDS") Signed-off-by: Ming Lei <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent e8cd481 commit dbc635c

1 file changed

Lines changed: 5 additions & 1 deletion

File tree

drivers/block/ublk_drv.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3064,7 +3064,6 @@ static int __ublk_fetch(struct io_uring_cmd *cmd, struct ublk_device *ub,
30643064
WRITE_ONCE(io->task, NULL);
30653065
else
30663066
WRITE_ONCE(io->task, get_task_struct(current));
3067-
ublk_mark_io_ready(ub, q_id);
30683067

30693068
return 0;
30703069
}
@@ -3083,6 +3082,8 @@ static int ublk_fetch(struct io_uring_cmd *cmd, struct ublk_device *ub,
30833082
ret = __ublk_fetch(cmd, ub, io, q_id);
30843083
if (!ret)
30853084
ret = ublk_config_io_buf(ub, io, cmd, buf_addr, NULL);
3085+
if (!ret)
3086+
ublk_mark_io_ready(ub, q_id);
30863087
mutex_unlock(&ub->mutex);
30873088
return ret;
30883089
}
@@ -3484,6 +3485,9 @@ static int ublk_batch_prep_io(struct ublk_queue *ubq,
34843485
io->buf = buf;
34853486
ublk_io_unlock(io);
34863487

3488+
if (!ret)
3489+
ublk_mark_io_ready(data->ub, ubq->q_id);
3490+
34873491
return ret;
34883492
}
34893493

0 commit comments

Comments
 (0)