Commit 7b4f36cd authored by Jens Axboe's avatar Jens Axboe
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
Fixes: 900e0807 ("block: move queue enter logic into blk_mq_submit_bio()")
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarMing Lei <ming.lei@redhat.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 309ce674
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -2964,12 +2964,6 @@ void blk_mq_submit_bio(struct bio *bio)
	blk_status_t ret;

	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);

	if (plug) {
@@ -2978,6 +2972,11 @@ void blk_mq_submit_bio(struct bio *bio)
			rq = NULL;
	}
	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))
			return;
		if (blk_mq_attempt_bio_merge(q, bio, nr_segs))
@@ -2988,6 +2987,11 @@ void blk_mq_submit_bio(struct bio *bio)
	} else {
		if (unlikely(bio_queue_enter(bio)))
			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))
			goto fail;
	}