diff mbox series

[v3,9/9] block: mq-deadline: Fix handling of at-head zoned writes

Message ID 20230424203329.2369688-10-bvanassche@acm.org (mailing list archive)
State New, archived
Headers show
Series mq-deadline: Improve support for zoned block devices | expand

Commit Message

Bart Van Assche April 24, 2023, 8:33 p.m. UTC
Before dispatching a zoned write from the FIFO list, check whether there
are any zoned writes in the RB-tree for a lower LBA for the same zone.
This patch ensures that zoned writes happen in order even if at_head is
set for some writes for a zone and not for others.

Cc: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 block/mq-deadline.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

Comments

Christoph Hellwig April 28, 2023, 5:58 a.m. UTC | #1
>  	/*
>  	 * Look for a write request that can be dispatched, that is one with
> +	 * an unlocked target zone. For each write request from the FIFO list,
> +	 * check whether an earlier write request exists in the RB tree.

I can see that you are checking the RB tree, so the comment is a bit
useless.  It should explain why.  And preferably right next to the code
instead of hidden in this long and fairly hard to read above the loop
comment.
diff mbox series

Patch

diff --git a/block/mq-deadline.c b/block/mq-deadline.c
index 2de6c63190d8..ed0da04c51ec 100644
--- a/block/mq-deadline.c
+++ b/block/mq-deadline.c
@@ -341,7 +341,7 @@  static struct request *
 deadline_fifo_request(struct deadline_data *dd, struct dd_per_prio *per_prio,
 		      enum dd_data_dir data_dir)
 {
-	struct request *rq;
+	struct request *rq, *rb_rq, *next;
 	unsigned long flags;
 
 	if (list_empty(&per_prio->fifo_list[data_dir]))
@@ -353,13 +353,19 @@  deadline_fifo_request(struct deadline_data *dd, struct dd_per_prio *per_prio,
 
 	/*
 	 * Look for a write request that can be dispatched, that is one with
-	 * an unlocked target zone. For some HDDs, breaking a sequential
-	 * write stream can lead to lower throughput, so make sure to preserve
-	 * sequential write streams, even if that stream crosses into the next
-	 * zones and these zones are unlocked.
+	 * an unlocked target zone. For each write request from the FIFO list,
+	 * check whether an earlier write request exists in the RB tree. For
+	 * some HDDs, breaking a sequential write stream can lead to lower
+	 * throughput, so make sure to preserve sequential write streams, even
+	 * if that stream crosses into the next zones and these zones are
+	 * unlocked.
 	 */
 	spin_lock_irqsave(&dd->zone_lock, flags);
-	list_for_each_entry(rq, &per_prio->fifo_list[DD_WRITE], queuelist) {
+	list_for_each_entry_safe(rq, next, &per_prio->fifo_list[DD_WRITE],
+				 queuelist) {
+		rb_rq = deadline_from_pos(per_prio, data_dir, blk_rq_pos(rq));
+		if (rb_rq && blk_rq_pos(rb_rq) < blk_rq_pos(rq))
+			rq = rb_rq;
 		if (blk_req_can_dispatch_to_zone(rq) &&
 		    (blk_queue_nonrot(rq->q) ||
 		     !deadline_is_seq_write(dd, rq)))