block: ensure we hold a queue reference when using queue limits
q_usage_counter is the only thing preventing us from the limits changing
under us in __bio_split_to_limits, but blk_mq_submit_bio doesn't hold
it while calling into it.
Move the splitting inside the region where we know we've got a queue
reference. Ideally this could still remain a shared section of code, but
let's keep the fix simple and defer any refactoring here to later.
Reported-by: Christoph Hellwig <hch@lst.de>
Fixes: 900e080752
("block: move queue enter logic into blk_mq_submit_bio()")
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
309ce67414
commit
7b4f36cd22
@ -2964,12 +2964,6 @@ void blk_mq_submit_bio(struct bio *bio)
|
|||||||
blk_status_t ret;
|
blk_status_t ret;
|
||||||
|
|
||||||
bio = blk_queue_bounce(bio, q);
|
bio = blk_queue_bounce(bio, q);
|
||||||
if (bio_may_exceed_limits(bio, &q->limits)) {
|
|
||||||
bio = __bio_split_to_limits(bio, &q->limits, &nr_segs);
|
|
||||||
if (!bio)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bio_set_ioprio(bio);
|
bio_set_ioprio(bio);
|
||||||
|
|
||||||
if (plug) {
|
if (plug) {
|
||||||
@ -2978,6 +2972,11 @@ void blk_mq_submit_bio(struct bio *bio)
|
|||||||
rq = NULL;
|
rq = NULL;
|
||||||
}
|
}
|
||||||
if (rq) {
|
if (rq) {
|
||||||
|
if (unlikely(bio_may_exceed_limits(bio, &q->limits))) {
|
||||||
|
bio = __bio_split_to_limits(bio, &q->limits, &nr_segs);
|
||||||
|
if (!bio)
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!bio_integrity_prep(bio))
|
if (!bio_integrity_prep(bio))
|
||||||
return;
|
return;
|
||||||
if (blk_mq_attempt_bio_merge(q, bio, nr_segs))
|
if (blk_mq_attempt_bio_merge(q, bio, nr_segs))
|
||||||
@ -2988,6 +2987,11 @@ void blk_mq_submit_bio(struct bio *bio)
|
|||||||
} else {
|
} else {
|
||||||
if (unlikely(bio_queue_enter(bio)))
|
if (unlikely(bio_queue_enter(bio)))
|
||||||
return;
|
return;
|
||||||
|
if (unlikely(bio_may_exceed_limits(bio, &q->limits))) {
|
||||||
|
bio = __bio_split_to_limits(bio, &q->limits, &nr_segs);
|
||||||
|
if (!bio)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
if (!bio_integrity_prep(bio))
|
if (!bio_integrity_prep(bio))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user