diff options
author | Jens Axboe <axboe@fb.com> | 2014-05-27 19:46:48 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2014-05-27 19:46:48 -0400 |
commit | 95f096849932fe5eaa7bfec887530cf556744a76 (patch) | |
tree | 66f66e18fb1ae13d9e822cc14e4c3da6a59d0681 | |
parent | f14bbe77a96bb979dc539d8308ee18a9363a544f (diff) |
blk-mq: allow non-softirq completions
Right now we export two ways of completing a request:
1) blk_mq_complete_request(). This uses an IPI (if needed) and
completes through q->softirq_done_fn(). It also works with
timeouts.
2) blk_mq_end_io(). This completes inline, and ignores any timeout
state of the request.
Let blk_mq_complete_request() handle non-softirq_done_fn completions
as well, by just completing inline. If a driver has enough completion
ports to place completions correctly, it need not define a
mq_ops->complete() and we can avoid an indirect function call by
doing the completion inline.
Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r-- | block/blk-mq.c | 12 | ||||
-rw-r--r-- | include/linux/blk-mq.h | 4 |
2 files changed, 13 insertions, 3 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c index 30bad930e661..010b878d53b3 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
@@ -434,10 +434,16 @@ void __blk_mq_complete_request(struct request *rq) | |||
434 | **/ | 434 | **/ |
435 | void blk_mq_complete_request(struct request *rq) | 435 | void blk_mq_complete_request(struct request *rq) |
436 | { | 436 | { |
437 | if (unlikely(blk_should_fake_timeout(rq->q))) | 437 | struct request_queue *q = rq->q; |
438 | |||
439 | if (unlikely(blk_should_fake_timeout(q))) | ||
438 | return; | 440 | return; |
439 | if (!blk_mark_rq_complete(rq)) | 441 | if (!blk_mark_rq_complete(rq)) { |
440 | __blk_mq_complete_request(rq); | 442 | if (q->softirq_done_fn) |
443 | __blk_mq_complete_request(rq); | ||
444 | else | ||
445 | blk_mq_end_io(rq, rq->errors); | ||
446 | } | ||
441 | } | 447 | } |
442 | EXPORT_SYMBOL(blk_mq_complete_request); | 448 | EXPORT_SYMBOL(blk_mq_complete_request); |
443 | 449 | ||
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index afeb93496907..1dfeb1529a61 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h | |||
@@ -173,6 +173,10 @@ void __blk_mq_end_io(struct request *rq, int error); | |||
173 | 173 | ||
174 | void blk_mq_requeue_request(struct request *rq); | 174 | void blk_mq_requeue_request(struct request *rq); |
175 | 175 | ||
176 | /* | ||
177 | * Complete request through potential IPI for right placement. Driver must | ||
178 | * have defined a mq_ops->complete() hook for this. | ||
179 | */ | ||
176 | void blk_mq_complete_request(struct request *rq); | 180 | void blk_mq_complete_request(struct request *rq); |
177 | 181 | ||
178 | void blk_mq_stop_hw_queue(struct blk_mq_hw_ctx *hctx); | 182 | void blk_mq_stop_hw_queue(struct blk_mq_hw_ctx *hctx); |