blk-mq: blk_mq_tag_to_rq should handle flush request
authorShaohua Li <shli@kernel.org>
Fri, 30 May 2014 14:06:42 +0000 (08:06 -0600)
committerJens Axboe <axboe@fb.com>
Fri, 30 May 2014 14:06:42 +0000 (08:06 -0600)
flush request is special, which borrows the tag from the parent
request. Hence blk_mq_tag_to_rq needs special handling to return
the flush request from the tag.

Signed-off-by: Shaohua Li <shli@fusionio.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
block/blk-flush.c
block/blk-mq.c
include/linux/blk-mq.h

index ef608b35d9be2531e7153d3018a6954cac1960d5..ff87c664b7df63e62710faad323f8eae8fcd082c 100644 (file)
@@ -223,8 +223,10 @@ static void flush_end_io(struct request *flush_rq, int error)
        struct request *rq, *n;
        unsigned long flags = 0;
 
-       if (q->mq_ops)
+       if (q->mq_ops) {
                spin_lock_irqsave(&q->mq_flush_lock, flags);
+               q->flush_rq->cmd_flags = 0;
+       }
 
        running = &q->flush_queue[q->flush_running_idx];
        BUG_ON(q->flush_pending_idx == q->flush_running_idx);
index 6160128085fc8a533694bb69de7495c8c05e84e4..21f952ab358195bbfc686ce722ce47cf529f51ef 100644 (file)
@@ -541,9 +541,15 @@ void blk_mq_kick_requeue_list(struct request_queue *q)
 }
 EXPORT_SYMBOL(blk_mq_kick_requeue_list);
 
-struct request *blk_mq_tag_to_rq(struct blk_mq_tags *tags, unsigned int tag)
+struct request *blk_mq_tag_to_rq(struct blk_mq_hw_ctx *hctx, unsigned int tag)
 {
-       return tags->rqs[tag];
+       struct request_queue *q = hctx->queue;
+
+       if ((q->flush_rq->cmd_flags & REQ_FLUSH_SEQ) &&
+           q->flush_rq->tag == tag)
+               return q->flush_rq;
+
+       return hctx->tags->rqs[tag];
 }
 EXPORT_SYMBOL(blk_mq_tag_to_rq);
 
@@ -572,7 +578,7 @@ static void blk_mq_timeout_check(void *__data, unsigned long *free_tags)
                if (tag >= hctx->tags->nr_tags)
                        break;
 
-               rq = blk_mq_tag_to_rq(hctx->tags, tag++);
+               rq = blk_mq_tag_to_rq(hctx, tag++);
                if (rq->q != hctx->queue)
                        continue;
                if (!test_bit(REQ_ATOM_STARTED, &rq->atomic_flags))
index 95de239444d2f2d4bcdb76fe293923b90aca4115..ad3adb73cc70c779c2e7dd7b62e9d15047a2a978 100644 (file)
@@ -154,7 +154,7 @@ void blk_mq_free_request(struct request *rq);
 bool blk_mq_can_queue(struct blk_mq_hw_ctx *);
 struct request *blk_mq_alloc_request(struct request_queue *q, int rw,
                gfp_t gfp, bool reserved);
-struct request *blk_mq_tag_to_rq(struct blk_mq_tags *tags, unsigned int tag);
+struct request *blk_mq_tag_to_rq(struct blk_mq_hw_ctx *hctx, unsigned int tag);
 
 struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *, const int ctx_index);
 struct blk_mq_hw_ctx *blk_mq_alloc_single_hw_queue(struct blk_mq_tag_set *, unsigned int, int);