summaryrefslogtreecommitdiff
path: root/block/blk-core.c
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2018-06-02 23:04:07 +0300
committerJens Axboe <axboe@kernel.dk>2018-06-03 05:35:00 +0300
commitcd4a4ae4683dc2e09380118e205e057896dcda2b (patch)
tree7991620de08c70556b880e5fc4917382d48e477d /block/blk-core.c
parentd00a11df691466772435ec02471292eae07885e5 (diff)
downloadlinux-cd4a4ae4683dc2e09380118e205e057896dcda2b.tar.xz
block: don't use blocking queue entered for recursive bio submits
If we end up splitting a bio and the queue goes away between the initial submission and the later split submission, then we can block forever in blk_queue_enter() waiting for the reference to drop to zero. This will never happen, since we already hold a reference. Mark a split bio as already having entered the queue, so we can just use the live non-blocking queue enter variant. Thanks to Tetsuo Handa for the analysis. Reported-by: syzbot+c4f9cebf9d651f6e54de@syzkaller.appspotmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/blk-core.c')
-rw-r--r--block/blk-core.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index cd573a33a6f3..3f56be15f17e 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -2377,7 +2377,9 @@ blk_qc_t generic_make_request(struct bio *bio)
if (bio->bi_opf & REQ_NOWAIT)
flags = BLK_MQ_REQ_NOWAIT;
- if (blk_queue_enter(q, flags) < 0) {
+ if (bio_flagged(bio, BIO_QUEUE_ENTERED))
+ blk_queue_enter_live(q);
+ else if (blk_queue_enter(q, flags) < 0) {
if (!blk_queue_dying(q) && (bio->bi_opf & REQ_NOWAIT))
bio_wouldblock_error(bio);
else