Commit e3ef9445 authored by Nilay Shroff's avatar Nilay Shroff Committed by Jens Axboe
Browse files

block: validate QoS before calling __rq_qos_done_bio()



If a bio has BIO_QOS_xxx set, it doesn't guarantee that q->rq_qos is
also present at-least for stacked block devices. For instance, in case
of NVMe when multipath is enabled, the bottom device may have QoS
enabled but top device doesn't. So always validate QoS is enabled and
q->rq_qos is present before calling __rq_qos_done_bio().

Fixes: 370ac285 ("block: avoid cpu_hotplug_lock depedency on freeze_lock")
Reported-by: default avatarVenkat Rao Bagalkote <venkat88@linux.ibm.com>
Closes: https://lore.kernel.org/all/3a07b752-06a4-4eee-b302-f4669feb859d@linux.ibm.com/


Signed-off-by: default avatarNilay Shroff <nilay@linux.ibm.com>
Link: https://lore.kernel.org/r/20250826163128.1952394-1-nilay@linux.ibm.com


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 198f36f9
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -149,11 +149,14 @@ static inline void rq_qos_done_bio(struct bio *bio)
	q = bdev_get_queue(bio->bi_bdev);

	/*
	 * If a bio has BIO_QOS_xxx set, it implicitly implies that
	 * q->rq_qos is present. So, we skip re-checking q->rq_qos
	 * here as an extra optimization and directly call
	 * __rq_qos_done_bio().
	 * A BIO may carry BIO_QOS_* flags even if the associated request_queue
	 * does not have rq_qos enabled. This can happen with stacked block
	 * devices — for example, NVMe multipath, where it's possible that the
	 * bottom device has QoS enabled but the top device does not. Therefore,
	 * always verify that q->rq_qos is present and QoS is enabled before
	 * calling __rq_qos_done_bio().
	 */
	if (test_bit(QUEUE_FLAG_QOS_ENABLED, &q->queue_flags) && q->rq_qos)
		__rq_qos_done_bio(q->rq_qos, bio);
}