aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2014-09-13 19:40:11 -0400
committerJens Axboe <axboe@fb.com>2014-09-22 14:00:07 -0400
commit81481eb423c295c5480a3fab9bb961cf286c91e7 (patch)
tree3d4f0eaed9f784ba5beb41aa9fec3e76b867c1e8 /block
parentc8a446ad695ada43a885ec12b38411dbd190a11b (diff)
blk-mq: fix and simplify tag iteration for the timeout handler
Don't do a kmalloc from timer to handle timeouts, chances are we could be under heavy load or similar and thus just miss out on the timeouts. Fortunately it is very easy to just iterate over all in use tags, and doing this properly actually cleans up the blk_mq_busy_iter API as well, and prepares us for the next patch by passing a reserved argument to the iterator. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'block')
-rw-r--r--block/blk-mq-tag.c44
-rw-r--r--block/blk-mq.c85
2 files changed, 43 insertions, 86 deletions
diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c
index c1b92426c95e..b08788086414 100644
--- a/block/blk-mq-tag.c
+++ b/block/blk-mq-tag.c
@@ -392,45 +392,37 @@ void blk_mq_put_tag(struct blk_mq_hw_ctx *hctx, unsigned int tag,
392 __blk_mq_put_reserved_tag(tags, tag); 392 __blk_mq_put_reserved_tag(tags, tag);
393} 393}
394 394
395static void bt_for_each_free(struct blk_mq_bitmap_tags *bt, 395static void bt_for_each(struct blk_mq_hw_ctx *hctx,
396 unsigned long *free_map, unsigned int off) 396 struct blk_mq_bitmap_tags *bt, unsigned int off,
397 busy_iter_fn *fn, void *data, bool reserved)
397{ 398{
398 int i; 399 struct request *rq;
400 int bit, i;
399 401
400 for (i = 0; i < bt->map_nr; i++) { 402 for (i = 0; i < bt->map_nr; i++) {
401 struct blk_align_bitmap *bm = &bt->map[i]; 403 struct blk_align_bitmap *bm = &bt->map[i];
402 int bit = 0;
403
404 do {
405 bit = find_next_zero_bit(&bm->word, bm->depth, bit);
406 if (bit >= bm->depth)
407 break;
408 404
409 __set_bit(bit + off, free_map); 405 for (bit = find_first_bit(&bm->word, bm->depth);
410 bit++; 406 bit < bm->depth;
411 } while (1); 407 bit = find_next_bit(&bm->word, bm->depth, bit + 1)) {
408 rq = blk_mq_tag_to_rq(hctx->tags, off + bit);
409 if (rq->q == hctx->queue)
410 fn(hctx, rq, data, reserved);
411 }
412 412
413 off += (1 << bt->bits_per_word); 413 off += (1 << bt->bits_per_word);
414 } 414 }
415} 415}
416 416
417void blk_mq_tag_busy_iter(struct blk_mq_tags *tags, 417void blk_mq_tag_busy_iter(struct blk_mq_hw_ctx *hctx, busy_iter_fn *fn,
418 void (*fn)(void *, unsigned long *), void *data) 418 void *priv)
419{ 419{
420 unsigned long *tag_map; 420 struct blk_mq_tags *tags = hctx->tags;
421 size_t map_size;
422
423 map_size = ALIGN(tags->nr_tags, BITS_PER_LONG) / BITS_PER_LONG;
424 tag_map = kzalloc(map_size * sizeof(unsigned long), GFP_ATOMIC);
425 if (!tag_map)
426 return;
427 421
428 bt_for_each_free(&tags->bitmap_tags, tag_map, tags->nr_reserved_tags);
429 if (tags->nr_reserved_tags) 422 if (tags->nr_reserved_tags)
430 bt_for_each_free(&tags->breserved_tags, tag_map, 0); 423 bt_for_each(hctx, &tags->breserved_tags, 0, fn, priv, true);
431 424 bt_for_each(hctx, &tags->bitmap_tags, tags->nr_reserved_tags, fn, priv,
432 fn(data, tag_map); 425 false);
433 kfree(tag_map);
434} 426}
435EXPORT_SYMBOL(blk_mq_tag_busy_iter); 427EXPORT_SYMBOL(blk_mq_tag_busy_iter);
436 428
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 1713686f5c2f..3baebcaf36db 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -525,58 +525,6 @@ struct request *blk_mq_tag_to_rq(struct blk_mq_tags *tags, unsigned int tag)
525} 525}
526EXPORT_SYMBOL(blk_mq_tag_to_rq); 526EXPORT_SYMBOL(blk_mq_tag_to_rq);
527 527
528struct blk_mq_timeout_data {
529 struct blk_mq_hw_ctx *hctx;
530 unsigned long *next;
531 unsigned int *next_set;
532};
533
534static void blk_mq_timeout_check(void *__data, unsigned long *free_tags)
535{
536 struct blk_mq_timeout_data *data = __data;
537 struct blk_mq_hw_ctx *hctx = data->hctx;
538 unsigned int tag;
539
540 /* It may not be in flight yet (this is where
541 * the REQ_ATOMIC_STARTED flag comes in). The requests are
542 * statically allocated, so we know it's always safe to access the
543 * memory associated with a bit offset into ->rqs[].
544 */
545 tag = 0;
546 do {
547 struct request *rq;
548
549 tag = find_next_zero_bit(free_tags, hctx->tags->nr_tags, tag);
550 if (tag >= hctx->tags->nr_tags)
551 break;
552
553 rq = blk_mq_tag_to_rq(hctx->tags, tag++);
554 if (rq->q != hctx->queue)
555 continue;
556 if (!test_bit(REQ_ATOM_STARTED, &rq->atomic_flags))
557 continue;
558
559 blk_rq_check_expired(rq, data->next, data->next_set);
560 } while (1);
561}
562
563static void blk_mq_hw_ctx_check_timeout(struct blk_mq_hw_ctx *hctx,
564 unsigned long *next,
565 unsigned int *next_set)
566{
567 struct blk_mq_timeout_data data = {
568 .hctx = hctx,
569 .next = next,
570 .next_set = next_set,
571 };
572
573 /*
574 * Ask the tagging code to iterate busy requests, so we can
575 * check them for timeout.
576 */
577 blk_mq_tag_busy_iter(hctx->tags, blk_mq_timeout_check, &data);
578}
579
580static enum blk_eh_timer_return blk_mq_rq_timed_out(struct request *rq) 528static enum blk_eh_timer_return blk_mq_rq_timed_out(struct request *rq)
581{ 529{
582 struct request_queue *q = rq->q; 530 struct request_queue *q = rq->q;
@@ -598,13 +546,30 @@ static enum blk_eh_timer_return blk_mq_rq_timed_out(struct request *rq)
598 546
599 return q->mq_ops->timeout(rq); 547 return q->mq_ops->timeout(rq);
600} 548}
549
550struct blk_mq_timeout_data {
551 unsigned long next;
552 unsigned int next_set;
553};
554
555static void blk_mq_check_expired(struct blk_mq_hw_ctx *hctx,
556 struct request *rq, void *priv, bool reserved)
557{
558 struct blk_mq_timeout_data *data = priv;
559
560 if (test_bit(REQ_ATOM_STARTED, &rq->atomic_flags))
561 blk_rq_check_expired(rq, &data->next, &data->next_set);
562}
601 563
602static void blk_mq_rq_timer(unsigned long data) 564static void blk_mq_rq_timer(unsigned long priv)
603{ 565{
604 struct request_queue *q = (struct request_queue *) data; 566 struct request_queue *q = (struct request_queue *)priv;
567 struct blk_mq_timeout_data data = {
568 .next = 0,
569 .next_set = 0,
570 };
605 struct blk_mq_hw_ctx *hctx; 571 struct blk_mq_hw_ctx *hctx;
606 unsigned long next = 0; 572 int i;
607 int i, next_set = 0;
608 573
609 queue_for_each_hw_ctx(q, hctx, i) { 574 queue_for_each_hw_ctx(q, hctx, i) {
610 /* 575 /*
@@ -614,12 +579,12 @@ static void blk_mq_rq_timer(unsigned long data)
614 if (!hctx->nr_ctx || !hctx->tags) 579 if (!hctx->nr_ctx || !hctx->tags)
615 continue; 580 continue;
616 581
617 blk_mq_hw_ctx_check_timeout(hctx, &next, &next_set); 582 blk_mq_tag_busy_iter(hctx, blk_mq_check_expired, &data);
618 } 583 }
619 584
620 if (next_set) { 585 if (data.next_set) {
621 next = blk_rq_timeout(round_jiffies_up(next)); 586 data.next = blk_rq_timeout(round_jiffies_up(data.next));
622 mod_timer(&q->timeout, next); 587 mod_timer(&q->timeout, data.next);
623 } else { 588 } else {
624 queue_for_each_hw_ctx(q, hctx, i) 589 queue_for_each_hw_ctx(q, hctx, i)
625 blk_mq_tag_idle(hctx); 590 blk_mq_tag_idle(hctx);