mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-18 03:06:43 +00:00
ublk_drv: check 'current' instead of 'ubq_daemon'
This check is not atomic. So with recovery feature, ubq_daemon may be modified simultaneously by recovery task. Instead, check 'current' is safe here because 'current' never changes. Also add comment explaining this check, which is really important for understanding recovery feature. Signed-off-by: ZiyangZhang <ZiyangZhang@linux.alibaba.com> Reviewed-by: Ming Lei <ming.lei@redhat.com> Link: https://lore.kernel.org/r/20220923153919.44078-2-ZiyangZhang@linux.alibaba.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
4324796ed0
commit
ae3f719300
@ -645,14 +645,22 @@ static inline void __ublk_rq_task_work(struct request *req)
|
||||
struct ublk_device *ub = ubq->dev;
|
||||
int tag = req->tag;
|
||||
struct ublk_io *io = &ubq->ios[tag];
|
||||
bool task_exiting = current != ubq->ubq_daemon || ubq_daemon_is_dying(ubq);
|
||||
unsigned int mapped_bytes;
|
||||
|
||||
pr_devel("%s: complete: op %d, qid %d tag %d io_flags %x addr %llx\n",
|
||||
__func__, io->cmd->cmd_op, ubq->q_id, req->tag, io->flags,
|
||||
ublk_get_iod(ubq, req->tag)->addr);
|
||||
|
||||
if (unlikely(task_exiting)) {
|
||||
/*
|
||||
* Task is exiting if either:
|
||||
*
|
||||
* (1) current != ubq_daemon.
|
||||
* io_uring_cmd_complete_in_task() tries to run task_work
|
||||
* in a workqueue if ubq_daemon(cmd's task) is PF_EXITING.
|
||||
*
|
||||
* (2) current->flags & PF_EXITING.
|
||||
*/
|
||||
if (unlikely(current != ubq->ubq_daemon || current->flags & PF_EXITING)) {
|
||||
blk_mq_end_request(req, BLK_STS_IOERR);
|
||||
mod_delayed_work(system_wq, &ub->monitor_work, 0);
|
||||
return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user