History

blk-mq: cache request hardware queue mapping

We call blk_mq_map_queue() a lot, at least two times for each request per IO, sometimes more. Since we now have an indirect call as well in that function. cache the mapping so we don't have to re-call blk_mq_map_queue() for the same request multiple times.

Jens Axboe committed 8 years ago

Commit ea4f9951 parent 392546a7 files · +19 −40Browse files

Unified · Split

7 files
  1. block/blk-flush.c +4 −8
  2. block/blk-mq-debugfs.c +1 −3
  3. block/blk-mq-sched.c +2 −4
  4. block/blk-mq-tag.c +1 −8
  5. block/blk-mq.c +9 −13
  6. block/blk-mq.h +1 −4
  7. include/linux/blkdev.h +1 −0
block/blk-flush.c+4−8
@@ -215,7 +215,7 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error) · 214 unmodified lines
215215
216216 /* release the tag's ownership to the req cloned from */
217217 spin_lock_irqsave(&fq->mq_flush_lock, flags);
218− hctx = blk_mq_map_queue(q, flush_rq->cmd_flags, flush_rq->mq_ctx->cpu);
218+ hctx = flush_rq->mq_hctx;
219219 if (!q->elevator) {
220220 blk_mq_tag_set_rq(hctx, flush_rq->tag, fq->orig_rq);
221221 flush_rq->tag = -1;
@@ -262,7 +262,6 @@ static void blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq, · 40 unmodified lines
262262 struct request *first_rq =
263263 list_first_entry(pending, struct request, flush.list);
264264 struct request *flush_rq = fq->flush_rq;
265− struct blk_mq_hw_ctx *hctx;
266265
267266 /* C1 described at the top of this file */
268267 if (fq->flush_pending_idx != fq->flush_running_idx || list_empty(pending))
@@ -297,13 +296,12 @@ static void blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq, · 28 unmodified lines
297296 * just for cheating put/get driver tag.
298297 */
299298 flush_rq->mq_ctx = first_rq->mq_ctx;
299+ flush_rq->mq_hctx = first_rq->mq_hctx;
300300
301301 if (!q->elevator) {
302302 fq->orig_rq = first_rq;
303303 flush_rq->tag = first_rq->tag;
304− hctx = blk_mq_map_queue(q, first_rq->cmd_flags,
305− first_rq->mq_ctx->cpu);
306− blk_mq_tag_set_rq(hctx, first_rq->tag, flush_rq);
304+ blk_mq_tag_set_rq(flush_rq->mq_hctx, first_rq->tag, flush_rq);
307305 } else {
308306 flush_rq->internal_tag = first_rq->internal_tag;
309307 }
@@ -320,13 +318,11 @@ static void blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq, · 10 unmodified lines
320318 static void mq_flush_data_end_io(struct request *rq, blk_status_t error)
321319 {
322320 struct request_queue *q = rq->q;
323− struct blk_mq_hw_ctx *hctx;
321+ struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
324322 struct blk_mq_ctx *ctx = rq->mq_ctx;
325323 unsigned long flags;
326324 struct blk_flush_queue *fq = blk_get_flush_queue(q, ctx);
327325
328− hctx = blk_mq_map_queue(q, rq->cmd_flags, ctx->cpu);
329−
330326 if (q->elevator) {
331327 WARN_ON(rq->tag < 0);
332328 blk_mq_put_driver_tag_hctx(hctx, rq);
block/blk-mq-debugfs.c+1−3
@@ -427,10 +427,8 @@ struct show_busy_params { · 426 unmodified lines
427427 static void hctx_show_busy_rq(struct request *rq, void *data, bool reserved)
428428 {
429429 const struct show_busy_params *params = data;
430− struct blk_mq_hw_ctx *hctx;
431430
432− hctx = blk_mq_map_queue(rq->q, rq->cmd_flags, rq->mq_ctx->cpu);
433− if (hctx == params->hctx)
431+ if (rq->mq_hctx == params->hctx)
434432 __blk_mq_debugfs_rq_show(params->m,
435433 list_entry_rq(&rq->queuelist));
436434 }
block/blk-mq-sched.c+2−4
@@ -366,9 +366,7 @@ void blk_mq_sched_insert_request(struct request *rq, bool at_head, · 365 unmodified lines
366366 struct request_queue *q = rq->q;
367367 struct elevator_queue *e = q->elevator;
368368 struct blk_mq_ctx *ctx = rq->mq_ctx;
369− struct blk_mq_hw_ctx *hctx;
370−
371− hctx = blk_mq_map_queue(q, rq->cmd_flags, ctx->cpu);
369+ struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
372370
373371 /* flush rq in flush machinery need to be dispatched directly */
374372 if (!(rq->rq_flags & RQF_FLUSH_SEQ) && op_is_flush(rq->cmd_flags)) {
@@ -407,7 +405,7 @@ void blk_mq_sched_insert_requests(struct request_queue *q, · 32 unmodified lines
407405
408406 /* For list inserts, requests better be on the same hw queue */
409407 rq = list_first_entry(list, struct request, queuelist);
410− hctx = blk_mq_map_queue(q, rq->cmd_flags, ctx->cpu);
408+ hctx = rq->mq_hctx;
411409
412410 e = hctx->queue->elevator;
413411 if (e && e->type->ops.insert_requests)
block/blk-mq-tag.c+1−8
@@ -527,14 +527,7 @@ int blk_mq_tag_update_depth(struct blk_mq_hw_ctx *hctx, · 526 unmodified lines
527527 */
528528 u32 blk_mq_unique_tag(struct request *rq)
529529 {
530− struct request_queue *q = rq->q;
531− struct blk_mq_hw_ctx *hctx;
532− int hwq = 0;
533−
534− hctx = blk_mq_map_queue(q, rq->cmd_flags, rq->mq_ctx->cpu);
535− hwq = hctx->queue_num;
536−
537− return (hwq << BLK_MQ_UNIQUE_TAG_BITS) |
530+ return (rq->mq_hctx->queue_num << BLK_MQ_UNIQUE_TAG_BITS) |
538531 (rq->tag & BLK_MQ_UNIQUE_TAG_MASK);
539532 }
540533 EXPORT_SYMBOL(blk_mq_unique_tag);
block/blk-mq.c+9−13
@@ -300,6 +300,7 @@ static struct request *blk_mq_rq_ctx_init(struct blk_mq_alloc_data *data, · 299 unmodified lines
300300 /* csd/requeue_work/fifo_time is initialized before use */
301301 rq->q = data->q;
302302 rq->mq_ctx = data->ctx;
303+ rq->mq_hctx = data->hctx;
303304 rq->rq_flags = rq_flags;
304305 rq->cmd_flags = op;
305306 if (data->flags & BLK_MQ_REQ_PREEMPT)
@@ -472,10 +473,11 @@ static void __blk_mq_free_request(struct request *rq) · 166 unmodified lines
472473 {
473474 struct request_queue *q = rq->q;
474475 struct blk_mq_ctx *ctx = rq->mq_ctx;
475− struct blk_mq_hw_ctx *hctx = blk_mq_map_queue(q, rq->cmd_flags, ctx->cpu);
476+ struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
476477 const int sched_tag = rq->internal_tag;
477478
478479 blk_pm_mark_last_busy(rq);
480+ rq->mq_hctx = NULL;
479481 if (rq->tag != -1)
480482 blk_mq_put_tag(hctx, hctx->tags, ctx, rq->tag);
481483 if (sched_tag != -1)
@@ -489,7 +491,7 @@ void blk_mq_free_request(struct request *rq) · 7 unmodified lines
489491 struct request_queue *q = rq->q;
490492 struct elevator_queue *e = q->elevator;
491493 struct blk_mq_ctx *ctx = rq->mq_ctx;
492− struct blk_mq_hw_ctx *hctx = blk_mq_map_queue(q, rq->cmd_flags, ctx->cpu);
494+ struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
493495
494496 if (rq->rq_flags & RQF_ELVPRIV) {
495497 if (e && e->type->ops.finish_request)
@@ -983,7 +985,7 @@ bool blk_mq_get_driver_tag(struct request *rq) · 487 unmodified lines
983985 {
984986 struct blk_mq_alloc_data data = {
985987 .q = rq->q,
986− .hctx = blk_mq_map_queue(rq->q, rq->cmd_flags, rq->mq_ctx->cpu),
988+ .hctx = rq->mq_hctx,
987989 .flags = BLK_MQ_REQ_NOWAIT,
988990 .cmd_flags = rq->cmd_flags,
989991 };
@@ -1149,7 +1151,7 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list, · 159 unmodified lines
11491151
11501152 rq = list_first_entry(list, struct request, queuelist);
11511153
1152− hctx = blk_mq_map_queue(rq->q, rq->cmd_flags, rq->mq_ctx->cpu);
1154+ hctx = rq->mq_hctx;
11531155 if (!got_budget && !blk_mq_get_dispatch_budget(hctx))
11541156 break;
11551157
@@ -1579,9 +1581,7 @@ void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, · 423 unmodified lines
15791581 */
15801582 void blk_mq_request_bypass_insert(struct request *rq, bool run_queue)
15811583 {
1582− struct blk_mq_ctx *ctx = rq->mq_ctx;
1583− struct blk_mq_hw_ctx *hctx = blk_mq_map_queue(rq->q, rq->cmd_flags,
1584− ctx->cpu);
1584+ struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
15851585
15861586 spin_lock(&hctx->lock);
15871587 list_add_tail(&rq->queuelist, &hctx->dispatch);
@@ -1790,9 +1790,7 @@ blk_status_t blk_mq_request_issue_directly(struct request *rq) · 202 unmodified lines
17901790 blk_status_t ret;
17911791 int srcu_idx;
17921792 blk_qc_t unused_cookie;
1793− struct blk_mq_ctx *ctx = rq->mq_ctx;
1794− struct blk_mq_hw_ctx *hctx = blk_mq_map_queue(rq->q, rq->cmd_flags,
1795− ctx->cpu);
1793+ struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
17961794
17971795 hctx_lock(hctx, &srcu_idx);
17981796 ret = __blk_mq_try_issue_directly(hctx, rq, &unused_cookie, true);
@@ -1917,9 +1915,7 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio) · 118 unmodified lines
19171915 blk_mq_put_ctx(data.ctx);
19181916
19191917 if (same_queue_rq) {
1920− data.hctx = blk_mq_map_queue(q,
1921− same_queue_rq->cmd_flags,
1922− same_queue_rq->mq_ctx->cpu);
1918+ data.hctx = same_queue_rq->mq_hctx;
19231919 blk_mq_try_issue_directly(data.hctx, same_queue_rq,
19241920 &cookie);
19251921 }
block/blk-mq.h+1−4
@@ -223,13 +223,10 @@ static inline void blk_mq_put_driver_tag_hctx(struct blk_mq_hw_ctx *hctx, · 222 unmodified lines
223223
224224 static inline void blk_mq_put_driver_tag(struct request *rq)
225225 {
226− struct blk_mq_hw_ctx *hctx;
227−
228226 if (rq->tag == -1 || rq->internal_tag == -1)
229227 return;
230228
231− hctx = blk_mq_map_queue(rq->q, rq->cmd_flags, rq->mq_ctx->cpu);
232− __blk_mq_put_driver_tag(hctx, rq);
229+ __blk_mq_put_driver_tag(rq->mq_hctx, rq);
233230 }
234231
235232 static inline void blk_mq_clear_mq_map(struct blk_mq_queue_map *qmap)
include/linux/blkdev.h+1−0
@@ -129,6 +129,7 @@ enum mq_rq_state { · 128 unmodified lines
129129 struct request {
130130 struct request_queue *q;
131131 struct blk_mq_ctx *mq_ctx;
132+ struct blk_mq_hw_ctx *mq_hctx;
132133
133134 unsigned int cmd_flags; /* op and common flags */
134135 req_flags_t rq_flags;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t