Skip to content

Commit aef1897

Browse files
Jianchao Wangaxboe
authored andcommitted
blk-mq: insert rq with DONTPREP to hctx dispatch list when requeue
When requeue, if RQF_DONTPREP, rq has contained some driver specific data, so insert it to hctx dispatch list to avoid any merge. Take scsi as example, here is the trace event log (no io scheduler, because RQF_STARTED would prevent merging), kworker/0:1H-339 [000] ...1 2037.209289: block_rq_insert: 8,0 R 4096 () 32768 + 8 [kworker/0:1H] scsi_inert_test-1987 [000] .... 2037.220465: block_bio_queue: 8,0 R 32776 + 8 [scsi_inert_test] scsi_inert_test-1987 [000] ...2 2037.220466: block_bio_backmerge: 8,0 R 32776 + 8 [scsi_inert_test] kworker/0:1H-339 [000] .... 2047.220913: block_rq_issue: 8,0 R 8192 () 32768 + 16 [kworker/0:1H] scsi_inert_test-1996 [000] ..s1 2047.221007: block_rq_complete: 8,0 R () 32768 + 8 [0] scsi_inert_test-1996 [000] .Ns1 2047.221045: block_rq_requeue: 8,0 R () 32776 + 8 [0] kworker/0:1H-339 [000] ...1 2047.221054: block_rq_insert: 8,0 R 4096 () 32776 + 8 [kworker/0:1H] kworker/0:1H-339 [000] ...1 2047.221056: block_rq_issue: 8,0 R 4096 () 32776 + 8 [kworker/0:1H] scsi_inert_test-1986 [000] ..s1 2047.221119: block_rq_complete: 8,0 R () 32776 + 8 [0] (32768 + 8) was requeued by scsi_queue_insert and had RQF_DONTPREP. Then it was merged with (32776 + 8) and issued. Due to RQF_DONTPREP, the sdb only contained the part of (32768 + 8), then only that part was completed. The lucky thing was that scsi_io_completion detected it and requeued the remaining part. So we didn't get corrupted data. However, the requeue of (32776 + 8) is not expected. Suggested-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Jianchao Wang <jianchao.w.wang@oracle.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 2698484 commit aef1897

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

block/blk-mq.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -737,12 +737,20 @@ static void blk_mq_requeue_work(struct work_struct *work)
737737
spin_unlock_irq(&q->requeue_lock);
738738

739739
list_for_each_entry_safe(rq, next, &rq_list, queuelist) {
740-
if (!(rq->rq_flags & RQF_SOFTBARRIER))
740+
if (!(rq->rq_flags & (RQF_SOFTBARRIER | RQF_DONTPREP)))
741741
continue;
742742

743743
rq->rq_flags &= ~RQF_SOFTBARRIER;
744744
list_del_init(&rq->queuelist);
745-
blk_mq_sched_insert_request(rq, true, false, false);
745+
/*
746+
* If RQF_DONTPREP, rq has contained some driver specific
747+
* data, so insert it to hctx dispatch list to avoid any
748+
* merge.
749+
*/
750+
if (rq->rq_flags & RQF_DONTPREP)
751+
blk_mq_request_bypass_insert(rq, false);
752+
else
753+
blk_mq_sched_insert_request(rq, true, false, false);
746754
}
747755

748756
while (!list_empty(&rq_list)) {

0 commit comments

Comments
 (0)