Commit c0b79b0f authored by Ming Lei's avatar Ming Lei Committed by Jens Axboe

ublk: add timeout handler

Add timeout handler, so that we can provide forward progress guarantee for
unprivileged ublk, which can't be trusted.

One thing is that sync() calls sync_bdevs(wait) for all block devices after
running sync_bdevs(no_wait), and if one device can't move on, the sync() won't
return any more.

Add timeout for unprivileged ublk to avoid such affect for other users which call
sync() syscall.

Meantime clear UBLK_F_USER_RECOVERY_REISSUE for unprivileged ublk since
that feature may cause IO hang too.

Fixes: 4093cb5a ("ublk_drv: add mechanism for supporting unprivileged ublk device")
Signed-off-by: default avatarMing Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20230502024231.888498-1-ming.lei@redhat.comSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 3899d94e
...@@ -129,6 +129,7 @@ struct ublk_queue { ...@@ -129,6 +129,7 @@ struct ublk_queue {
unsigned long io_addr; /* mapped vm address */ unsigned long io_addr; /* mapped vm address */
unsigned int max_io_sz; unsigned int max_io_sz;
bool force_abort; bool force_abort;
bool timeout;
unsigned short nr_io_ready; /* how many ios setup */ unsigned short nr_io_ready; /* how many ios setup */
struct ublk_device *dev; struct ublk_device *dev;
struct ublk_io ios[]; struct ublk_io ios[];
...@@ -894,6 +895,22 @@ static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq) ...@@ -894,6 +895,22 @@ static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq)
} }
} }
static enum blk_eh_timer_return ublk_timeout(struct request *rq)
{
struct ublk_queue *ubq = rq->mq_hctx->driver_data;
if (ubq->flags & UBLK_F_UNPRIVILEGED_DEV) {
if (!ubq->timeout) {
send_sig(SIGKILL, ubq->ubq_daemon, 0);
ubq->timeout = true;
}
return BLK_EH_DONE;
}
return BLK_EH_RESET_TIMER;
}
static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx, static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx,
const struct blk_mq_queue_data *bd) const struct blk_mq_queue_data *bd)
{ {
...@@ -953,6 +970,7 @@ static const struct blk_mq_ops ublk_mq_ops = { ...@@ -953,6 +970,7 @@ static const struct blk_mq_ops ublk_mq_ops = {
.queue_rq = ublk_queue_rq, .queue_rq = ublk_queue_rq,
.init_hctx = ublk_init_hctx, .init_hctx = ublk_init_hctx,
.init_request = ublk_init_rq, .init_request = ublk_init_rq,
.timeout = ublk_timeout,
}; };
static int ublk_ch_open(struct inode *inode, struct file *filp) static int ublk_ch_open(struct inode *inode, struct file *filp)
...@@ -1713,6 +1731,18 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd) ...@@ -1713,6 +1731,18 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd)
else if (!(info.flags & UBLK_F_UNPRIVILEGED_DEV)) else if (!(info.flags & UBLK_F_UNPRIVILEGED_DEV))
return -EPERM; return -EPERM;
/*
* unprivileged device can't be trusted, but RECOVERY and
* RECOVERY_REISSUE still may hang error handling, so can't
* support recovery features for unprivileged ublk now
*
* TODO: provide forward progress for RECOVERY handler, so that
* unprivileged device can benefit from it
*/
if (info.flags & UBLK_F_UNPRIVILEGED_DEV)
info.flags &= ~(UBLK_F_USER_RECOVERY_REISSUE |
UBLK_F_USER_RECOVERY);
/* the created device is always owned by current user */ /* the created device is always owned by current user */
ublk_store_owner_uid_gid(&info.owner_uid, &info.owner_gid); ublk_store_owner_uid_gid(&info.owner_uid, &info.owner_gid);
...@@ -1981,6 +2011,7 @@ static void ublk_queue_reinit(struct ublk_device *ub, struct ublk_queue *ubq) ...@@ -1981,6 +2011,7 @@ static void ublk_queue_reinit(struct ublk_device *ub, struct ublk_queue *ubq)
put_task_struct(ubq->ubq_daemon); put_task_struct(ubq->ubq_daemon);
/* We have to reset it to NULL, otherwise ub won't accept new FETCH_REQ */ /* We have to reset it to NULL, otherwise ub won't accept new FETCH_REQ */
ubq->ubq_daemon = NULL; ubq->ubq_daemon = NULL;
ubq->timeout = false;
for (i = 0; i < ubq->q_depth; i++) { for (i = 0; i < ubq->q_depth; i++) {
struct ublk_io *io = &ubq->ios[i]; struct ublk_io *io = &ubq->ios[i];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment