aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJens Axboe <axboe@fb.com>2014-10-29 13:14:52 -0400
committerJens Axboe <axboe@fb.com>2014-10-29 13:14:52 -0400
commit74c450521dd8d245b982da62592a18aa6f88b045 (patch)
treeb45928c02f0ee9051cd5cb257ad4bf1e0df125a8 /drivers
parent34b48db66e08ca1c1bc07cf305d672ac940268dc (diff)
blk-mq: add a 'list' parameter to ->queue_rq()
Since we have the notion of a 'last' request in a chain, we can use this to have the hardware optimize the issuing of requests. Add a list_head parameter to queue_rq that the driver can use to temporarily store hw commands for issue when 'last' is true. If we are doing a chain of requests, pass in a NULL list for the first request to force issue of that immediately, then batch the remainder for deferred issue until the last request has been sent. Instead of adding yet another argument to the hot ->queue_rq path, encapsulate the passed arguments in a blk_mq_queue_data structure. This is passed as a constant, and has been tested as faster than passing 4 (or even 3) args through ->queue_rq. Update drivers for the new ->queue_rq() prototype. There are no functional changes in this patch for drivers - if they don't use the passed in list, then they will just queue requests individually like before. Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c5
-rw-r--r--drivers/block/null_blk.c10
-rw-r--r--drivers/block/virtio_blk.c7
-rw-r--r--drivers/scsi/scsi_lib.c5
4 files changed, 15 insertions, 12 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index 1bd5f523f8fd..3bd7ca9853a8 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -3775,9 +3775,10 @@ static bool mtip_check_unal_depth(struct blk_mq_hw_ctx *hctx,
3775 return false; 3775 return false;
3776} 3776}
3777 3777
3778static int mtip_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *rq, 3778static int mtip_queue_rq(struct blk_mq_hw_ctx *hctx,
3779 bool last) 3779 const struct blk_mq_queue_data *bd)
3780{ 3780{
3781 struct request *rq = bd->rq;
3781 int ret; 3782 int ret;
3782 3783
3783 if (unlikely(mtip_check_unal_depth(hctx, rq))) 3784 if (unlikely(mtip_check_unal_depth(hctx, rq)))
diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c
index 2671a3f02f0c..8433bc8ead3d 100644
--- a/drivers/block/null_blk.c
+++ b/drivers/block/null_blk.c
@@ -313,15 +313,15 @@ static void null_request_fn(struct request_queue *q)
313 } 313 }
314} 314}
315 315
316static int null_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *rq, 316static int null_queue_rq(struct blk_mq_hw_ctx *hctx,
317 bool last) 317 const struct blk_mq_queue_data *bd)
318{ 318{
319 struct nullb_cmd *cmd = blk_mq_rq_to_pdu(rq); 319 struct nullb_cmd *cmd = blk_mq_rq_to_pdu(bd->rq);
320 320
321 cmd->rq = rq; 321 cmd->rq = bd->rq;
322 cmd->nq = hctx->driver_data; 322 cmd->nq = hctx->driver_data;
323 323
324 blk_mq_start_request(rq); 324 blk_mq_start_request(bd->rq);
325 325
326 null_handle_cmd(cmd); 326 null_handle_cmd(cmd);
327 return BLK_MQ_RQ_QUEUE_OK; 327 return BLK_MQ_RQ_QUEUE_OK;
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index c6a27d54ad62..cecd3f983e49 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -158,10 +158,11 @@ static void virtblk_done(struct virtqueue *vq)
158 spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); 158 spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags);
159} 159}
160 160
161static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req, 161static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
162 bool last) 162 const struct blk_mq_queue_data *bd)
163{ 163{
164 struct virtio_blk *vblk = hctx->queue->queuedata; 164 struct virtio_blk *vblk = hctx->queue->queuedata;
165 struct request *req = bd->rq;
165 struct virtblk_req *vbr = blk_mq_rq_to_pdu(req); 166 struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
166 unsigned long flags; 167 unsigned long flags;
167 unsigned int num; 168 unsigned int num;
@@ -222,7 +223,7 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req,
222 return BLK_MQ_RQ_QUEUE_ERROR; 223 return BLK_MQ_RQ_QUEUE_ERROR;
223 } 224 }
224 225
225 if (last && virtqueue_kick_prepare(vblk->vqs[qid].vq)) 226 if (bd->last && virtqueue_kick_prepare(vblk->vqs[qid].vq))
226 notify = true; 227 notify = true;
227 spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); 228 spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags);
228 229
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 9eff8a375132..161dcc93ac75 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1858,9 +1858,10 @@ static void scsi_mq_done(struct scsi_cmnd *cmd)
1858 blk_mq_complete_request(cmd->request); 1858 blk_mq_complete_request(cmd->request);
1859} 1859}
1860 1860
1861static int scsi_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req, 1861static int scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
1862 bool last) 1862 const struct blk_mq_queue_data *bd)
1863{ 1863{
1864 struct request *req = bd->rq;
1864 struct request_queue *q = req->q; 1865 struct request_queue *q = req->q;
1865 struct scsi_device *sdev = q->queuedata; 1866 struct scsi_device *sdev = q->queuedata;
1866 struct Scsi_Host *shost = sdev->host; 1867 struct Scsi_Host *shost = sdev->host;