Skip to content

Commit

Permalink
block: add blk_io_schedule() for avoiding task hung in sync dio
Browse files Browse the repository at this point in the history
Sync dio could be big, or may take long time in discard or in case of
IO failure.

We have prevented task hung in submit_bio_wait() and blk_execute_rq(),
so apply the same trick for prevent task hung from happening in sync dio.

Add helper of blk_io_schedule() and use io_schedule_timeout() to prevent
task hung warning.

Signed-off-by: Ming Lei <ming.lei@redhat.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Cc: Salman Qazi <sqazi@google.com>
Cc: Jesse Barnes <jsbarnes@google.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Bart Van Assche <bvanassche@acm.org>
Cc: Hannes Reinecke <hare@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
Ming Lei authored and Jens Axboe committed May 13, 2020
1 parent 27eb3af commit e6249cd
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 4 deletions.
4 changes: 2 additions & 2 deletions fs/block_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter,
break;
if (!(iocb->ki_flags & IOCB_HIPRI) ||
!blk_poll(bdev_get_queue(bdev), qc, true))
io_schedule();
blk_io_schedule();
}
__set_current_state(TASK_RUNNING);

Expand Down Expand Up @@ -449,7 +449,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)

if (!(iocb->ki_flags & IOCB_HIPRI) ||
!blk_poll(bdev_get_queue(bdev), qc, true))
io_schedule();
blk_io_schedule();
}
__set_current_state(TASK_RUNNING);

Expand Down
2 changes: 1 addition & 1 deletion fs/direct-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ static struct bio *dio_await_one(struct dio *dio)
spin_unlock_irqrestore(&dio->bio_lock, flags);
if (!(dio->iocb->ki_flags & IOCB_HIPRI) ||
!blk_poll(dio->bio_disk->queue, dio->bio_cookie, true))
io_schedule();
blk_io_schedule();
/* wake up sets us TASK_RUNNING */
spin_lock_irqsave(&dio->bio_lock, flags);
dio->waiter = NULL;
Expand Down
2 changes: 1 addition & 1 deletion fs/iomap/direct-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
!dio->submit.last_queue ||
!blk_poll(dio->submit.last_queue,
dio->submit.cookie, true))
io_schedule();
blk_io_schedule();
}
__set_current_state(TASK_RUNNING);
}
Expand Down
12 changes: 12 additions & 0 deletions include/linux/blkdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <linux/percpu-refcount.h>
#include <linux/scatterlist.h>
#include <linux/blkzoned.h>
#include <linux/sched/sysctl.h>

struct module;
struct scsi_ioctl_command;
Expand Down Expand Up @@ -1827,4 +1828,15 @@ static inline void blk_wake_io_task(struct task_struct *waiter)
wake_up_process(waiter);
}

static inline void blk_io_schedule(void)
{
/* Prevent hang_check timer from firing at us during very long I/O */
unsigned long timeout = sysctl_hung_task_timeout_secs * HZ / 2;

if (timeout)
io_schedule_timeout(timeout);
else
io_schedule();
}

#endif

0 comments on commit e6249cd

Please sign in to comment.