aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2014-09-13 19:40:09 -0400
committerJens Axboe <axboe@fb.com>2014-09-22 14:00:07 -0400
commite2490073cd7c3d6f6ef6e029a208edd4d38efac4 (patch)
tree48465e67b335f6d696d698641365b4a4d1e89d32
parentbf57229745f849e500ba69ff91e35bc8160a7373 (diff)
blk-mq: call blk_mq_start_request from ->queue_rq
When we call blk_mq_start_request from the core blk-mq code before calling into ->queue_rq there is a racy window where the timeout handler can hit before we've fully set up the driver specific part of the command. Move the call to blk_mq_start_request into the driver so the driver can start the request only once it is fully set up. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--block/blk-mq.c13
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c2
-rw-r--r--drivers/block/null_blk.c2
-rw-r--r--drivers/block/virtio_blk.c2
-rw-r--r--drivers/scsi/scsi_lib.c1
-rw-r--r--include/linux/blk-mq.h1
6 files changed, 14 insertions, 7 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 32b4797f4186..141f2e06803a 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -384,7 +384,7 @@ void blk_mq_complete_request(struct request *rq)
384} 384}
385EXPORT_SYMBOL(blk_mq_complete_request); 385EXPORT_SYMBOL(blk_mq_complete_request);
386 386
387static void blk_mq_start_request(struct request *rq) 387void blk_mq_start_request(struct request *rq)
388{ 388{
389 struct request_queue *q = rq->q; 389 struct request_queue *q = rq->q;
390 390
@@ -422,16 +422,18 @@ static void blk_mq_start_request(struct request *rq)
422 rq->nr_phys_segments++; 422 rq->nr_phys_segments++;
423 } 423 }
424} 424}
425EXPORT_SYMBOL(blk_mq_start_request);
425 426
426static void __blk_mq_requeue_request(struct request *rq) 427static void __blk_mq_requeue_request(struct request *rq)
427{ 428{
428 struct request_queue *q = rq->q; 429 struct request_queue *q = rq->q;
429 430
430 trace_block_rq_requeue(q, rq); 431 trace_block_rq_requeue(q, rq);
431 clear_bit(REQ_ATOM_STARTED, &rq->atomic_flags);
432 432
433 if (q->dma_drain_size && blk_rq_bytes(rq)) 433 if (test_and_clear_bit(REQ_ATOM_STARTED, &rq->atomic_flags)) {
434 rq->nr_phys_segments--; 434 if (q->dma_drain_size && blk_rq_bytes(rq))
435 rq->nr_phys_segments--;
436 }
435} 437}
436 438
437void blk_mq_requeue_request(struct request *rq) 439void blk_mq_requeue_request(struct request *rq)
@@ -743,8 +745,6 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx)
743 rq = list_first_entry(&rq_list, struct request, queuelist); 745 rq = list_first_entry(&rq_list, struct request, queuelist);
744 list_del_init(&rq->queuelist); 746 list_del_init(&rq->queuelist);
745 747
746 blk_mq_start_request(rq);
747
748 ret = q->mq_ops->queue_rq(hctx, rq, list_empty(&rq_list)); 748 ret = q->mq_ops->queue_rq(hctx, rq, list_empty(&rq_list));
749 switch (ret) { 749 switch (ret) {
750 case BLK_MQ_RQ_QUEUE_OK: 750 case BLK_MQ_RQ_QUEUE_OK:
@@ -1186,7 +1186,6 @@ static void blk_mq_make_request(struct request_queue *q, struct bio *bio)
1186 int ret; 1186 int ret;
1187 1187
1188 blk_mq_bio_to_request(rq, bio); 1188 blk_mq_bio_to_request(rq, bio);
1189 blk_mq_start_request(rq);
1190 1189
1191 /* 1190 /*
1192 * For OK queue, we are done. For error, kill it. Any other 1191 * For OK queue, we are done. For error, kill it. Any other
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index 0e2084f37c67..4042440a0470 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -3783,6 +3783,8 @@ static int mtip_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *rq,
3783 if (unlikely(mtip_check_unal_depth(hctx, rq))) 3783 if (unlikely(mtip_check_unal_depth(hctx, rq)))
3784 return BLK_MQ_RQ_QUEUE_BUSY; 3784 return BLK_MQ_RQ_QUEUE_BUSY;
3785 3785
3786 blk_mq_start_request(rq);
3787
3786 ret = mtip_submit_request(hctx, rq); 3788 ret = mtip_submit_request(hctx, rq);
3787 if (likely(!ret)) 3789 if (likely(!ret))
3788 return BLK_MQ_RQ_QUEUE_OK; 3790 return BLK_MQ_RQ_QUEUE_OK;
diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c
index c5b7315c2c13..332ce20d45da 100644
--- a/drivers/block/null_blk.c
+++ b/drivers/block/null_blk.c
@@ -321,6 +321,8 @@ static int null_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *rq,
321 cmd->rq = rq; 321 cmd->rq = rq;
322 cmd->nq = hctx->driver_data; 322 cmd->nq = hctx->driver_data;
323 323
324 blk_mq_start_request(rq);
325
324 null_handle_cmd(cmd); 326 null_handle_cmd(cmd);
325 return BLK_MQ_RQ_QUEUE_OK; 327 return BLK_MQ_RQ_QUEUE_OK;
326} 328}
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 13756e016797..83816bf6882f 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -205,6 +205,8 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req,
205 } 205 }
206 } 206 }
207 207
208 blk_mq_start_request(req);
209
208 num = blk_rq_map_sg(hctx->queue, vbr->req, vbr->sg); 210 num = blk_rq_map_sg(hctx->queue, vbr->req, vbr->sg);
209 if (num) { 211 if (num) {
210 if (rq_data_dir(vbr->req) == WRITE) 212 if (rq_data_dir(vbr->req) == WRITE)
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index f1df41168391..2dcd9078de48 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1890,6 +1890,7 @@ static int scsi_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req,
1890 scsi_init_cmd_errh(cmd); 1890 scsi_init_cmd_errh(cmd);
1891 cmd->scsi_done = scsi_mq_done; 1891 cmd->scsi_done = scsi_mq_done;
1892 1892
1893 blk_mq_start_request(req);
1893 reason = scsi_dispatch_cmd(cmd); 1894 reason = scsi_dispatch_cmd(cmd);
1894 if (reason) { 1895 if (reason) {
1895 scsi_set_blocked(cmd, reason); 1896 scsi_set_blocked(cmd, reason);
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index 9c4e306a9217..878b6f71da48 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -159,6 +159,7 @@ struct request *blk_mq_tag_to_rq(struct blk_mq_tags *tags, unsigned int tag);
159struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *, const int ctx_index); 159struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *, const int ctx_index);
160struct blk_mq_hw_ctx *blk_mq_alloc_single_hw_queue(struct blk_mq_tag_set *, unsigned int, int); 160struct blk_mq_hw_ctx *blk_mq_alloc_single_hw_queue(struct blk_mq_tag_set *, unsigned int, int);
161 161
162void blk_mq_start_request(struct request *rq);
162void blk_mq_end_io(struct request *rq, int error); 163void blk_mq_end_io(struct request *rq, int error);
163void __blk_mq_end_io(struct request *rq, int error); 164void __blk_mq_end_io(struct request *rq, int error);
164 165