diff options
author | Christoph Hellwig <hch@lst.de> | 2014-09-13 19:40:12 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2014-09-22 14:00:07 -0400 |
commit | 46f92d42ee37e10970e33891b7b61a342bd97aeb (patch) | |
tree | f8e8a59f0daa0c0fa4406a34b120d1d67b9a1c22 /block | |
parent | 81481eb423c295c5480a3fab9bb961cf286c91e7 (diff) |
blk-mq: unshared timeout handler
Duplicate the (small) timeout handler in blk-mq so that we can pass
arguments more easily to the driver timeout handler. This enables
the next patch.
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.c | 53 | ||||
-rw-r--r-- | block/blk-timeout.c | 8 | ||||
-rw-r--r-- | block/blk.h | 2 |
3 files changed, 39 insertions, 24 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c index 3baebcaf36db..298d6e360661 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
@@ -525,9 +525,15 @@ struct request *blk_mq_tag_to_rq(struct blk_mq_tags *tags, unsigned int tag) | |||
525 | } | 525 | } |
526 | EXPORT_SYMBOL(blk_mq_tag_to_rq); | 526 | EXPORT_SYMBOL(blk_mq_tag_to_rq); |
527 | 527 | ||
528 | static enum blk_eh_timer_return blk_mq_rq_timed_out(struct request *rq) | 528 | struct blk_mq_timeout_data { |
529 | unsigned long next; | ||
530 | unsigned int next_set; | ||
531 | }; | ||
532 | |||
533 | static void blk_mq_rq_timed_out(struct request *req) | ||
529 | { | 534 | { |
530 | struct request_queue *q = rq->q; | 535 | struct blk_mq_ops *ops = req->q->mq_ops; |
536 | enum blk_eh_timer_return ret = BLK_EH_RESET_TIMER; | ||
531 | 537 | ||
532 | /* | 538 | /* |
533 | * We know that complete is set at this point. If STARTED isn't set | 539 | * We know that complete is set at this point. If STARTED isn't set |
@@ -538,27 +544,43 @@ static enum blk_eh_timer_return blk_mq_rq_timed_out(struct request *rq) | |||
538 | * we both flags will get cleared. So check here again, and ignore | 544 | * we both flags will get cleared. So check here again, and ignore |
539 | * a timeout event with a request that isn't active. | 545 | * a timeout event with a request that isn't active. |
540 | */ | 546 | */ |
541 | if (!test_bit(REQ_ATOM_STARTED, &rq->atomic_flags)) | 547 | if (!test_bit(REQ_ATOM_STARTED, &req->atomic_flags)) |
542 | return BLK_EH_NOT_HANDLED; | 548 | return; |
543 | |||
544 | if (!q->mq_ops->timeout) | ||
545 | return BLK_EH_RESET_TIMER; | ||
546 | 549 | ||
547 | return q->mq_ops->timeout(rq); | 550 | if (ops->timeout) |
551 | ret = ops->timeout(req); | ||
552 | |||
553 | switch (ret) { | ||
554 | case BLK_EH_HANDLED: | ||
555 | __blk_mq_complete_request(req); | ||
556 | break; | ||
557 | case BLK_EH_RESET_TIMER: | ||
558 | blk_add_timer(req); | ||
559 | blk_clear_rq_complete(req); | ||
560 | break; | ||
561 | case BLK_EH_NOT_HANDLED: | ||
562 | break; | ||
563 | default: | ||
564 | printk(KERN_ERR "block: bad eh return: %d\n", ret); | ||
565 | break; | ||
566 | } | ||
548 | } | 567 | } |
549 | 568 | ||
550 | struct blk_mq_timeout_data { | ||
551 | unsigned long next; | ||
552 | unsigned int next_set; | ||
553 | }; | ||
554 | |||
555 | static void blk_mq_check_expired(struct blk_mq_hw_ctx *hctx, | 569 | static void blk_mq_check_expired(struct blk_mq_hw_ctx *hctx, |
556 | struct request *rq, void *priv, bool reserved) | 570 | struct request *rq, void *priv, bool reserved) |
557 | { | 571 | { |
558 | struct blk_mq_timeout_data *data = priv; | 572 | struct blk_mq_timeout_data *data = priv; |
559 | 573 | ||
560 | if (test_bit(REQ_ATOM_STARTED, &rq->atomic_flags)) | 574 | if (!test_bit(REQ_ATOM_STARTED, &rq->atomic_flags)) |
561 | blk_rq_check_expired(rq, &data->next, &data->next_set); | 575 | return; |
576 | |||
577 | if (time_after_eq(jiffies, rq->deadline)) { | ||
578 | if (!blk_mark_rq_complete(rq)) | ||
579 | blk_mq_rq_timed_out(rq); | ||
580 | } else if (!data->next_set || time_after(data->next, rq->deadline)) { | ||
581 | data->next = rq->deadline; | ||
582 | data->next_set = 1; | ||
583 | } | ||
562 | } | 584 | } |
563 | 585 | ||
564 | static void blk_mq_rq_timer(unsigned long priv) | 586 | static void blk_mq_rq_timer(unsigned long priv) |
@@ -1781,7 +1803,6 @@ struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *set) | |||
1781 | else | 1803 | else |
1782 | blk_queue_make_request(q, blk_sq_make_request); | 1804 | blk_queue_make_request(q, blk_sq_make_request); |
1783 | 1805 | ||
1784 | blk_queue_rq_timed_out(q, blk_mq_rq_timed_out); | ||
1785 | if (set->timeout) | 1806 | if (set->timeout) |
1786 | blk_queue_rq_timeout(q, set->timeout); | 1807 | blk_queue_rq_timeout(q, set->timeout); |
1787 | 1808 | ||
diff --git a/block/blk-timeout.c b/block/blk-timeout.c index 95a09590ccfd..4d448259e622 100644 --- a/block/blk-timeout.c +++ b/block/blk-timeout.c | |||
@@ -7,7 +7,6 @@ | |||
7 | #include <linux/fault-inject.h> | 7 | #include <linux/fault-inject.h> |
8 | 8 | ||
9 | #include "blk.h" | 9 | #include "blk.h" |
10 | #include "blk-mq.h" | ||
11 | 10 | ||
12 | #ifdef CONFIG_FAIL_IO_TIMEOUT | 11 | #ifdef CONFIG_FAIL_IO_TIMEOUT |
13 | 12 | ||
@@ -90,10 +89,7 @@ static void blk_rq_timed_out(struct request *req) | |||
90 | switch (ret) { | 89 | switch (ret) { |
91 | case BLK_EH_HANDLED: | 90 | case BLK_EH_HANDLED: |
92 | /* Can we use req->errors here? */ | 91 | /* Can we use req->errors here? */ |
93 | if (q->mq_ops) | 92 | __blk_complete_request(req); |
94 | __blk_mq_complete_request(req); | ||
95 | else | ||
96 | __blk_complete_request(req); | ||
97 | break; | 93 | break; |
98 | case BLK_EH_RESET_TIMER: | 94 | case BLK_EH_RESET_TIMER: |
99 | blk_add_timer(req); | 95 | blk_add_timer(req); |
@@ -113,7 +109,7 @@ static void blk_rq_timed_out(struct request *req) | |||
113 | } | 109 | } |
114 | } | 110 | } |
115 | 111 | ||
116 | void blk_rq_check_expired(struct request *rq, unsigned long *next_timeout, | 112 | static void blk_rq_check_expired(struct request *rq, unsigned long *next_timeout, |
117 | unsigned int *next_set) | 113 | unsigned int *next_set) |
118 | { | 114 | { |
119 | if (time_after_eq(jiffies, rq->deadline)) { | 115 | if (time_after_eq(jiffies, rq->deadline)) { |
diff --git a/block/blk.h b/block/blk.h index 6748c4f8d7a1..e515a285d4c9 100644 --- a/block/blk.h +++ b/block/blk.h | |||
@@ -38,8 +38,6 @@ bool __blk_end_bidi_request(struct request *rq, int error, | |||
38 | unsigned int nr_bytes, unsigned int bidi_bytes); | 38 | unsigned int nr_bytes, unsigned int bidi_bytes); |
39 | 39 | ||
40 | void blk_rq_timed_out_timer(unsigned long data); | 40 | void blk_rq_timed_out_timer(unsigned long data); |
41 | void blk_rq_check_expired(struct request *rq, unsigned long *next_timeout, | ||
42 | unsigned int *next_set); | ||
43 | unsigned long blk_rq_timeout(unsigned long timeout); | 41 | unsigned long blk_rq_timeout(unsigned long timeout); |
44 | void blk_add_timer(struct request *req); | 42 | void blk_add_timer(struct request *req); |
45 | void blk_delete_timer(struct request *); | 43 | void blk_delete_timer(struct request *); |