blk-mq: blk_mq_try_issue_directly() should lookup hardware queue
authorJens Axboe <axboe@fb.com>
Fri, 11 Nov 2016 19:24:46 +0000 (12:24 -0700)
committerJens Axboe <axboe@fb.com>
Fri, 11 Nov 2016 19:24:46 +0000 (12:24 -0700)
A previous commit changed this to pass in the hardware queue, but
it was using the wrong hardware queue. Hence a request that was
allocated on one hardware queue ended up being issued on another
one, and that caused IO timeouts and oopses on some drivers. Since
the request holds hardware queue private resources, like a tag,
we can't just issue it on a different hardware queue.

Fixes: 2253efc850c4 ("blk-mq: Move more code into blk_mq_direct_issue_request()")
Signed-off-by: Jens Axboe <axboe@fb.com>
block/blk-mq.c

index d180c989a0e52238ab140ffdb0648801a662b30d..77110aed24ea075710949c8ef3a4598732a46375 100644 (file)
@@ -1291,11 +1291,11 @@ static struct request *blk_mq_map_request(struct request_queue *q,
        return rq;
 }
 
-static void blk_mq_try_issue_directly(struct blk_mq_hw_ctx *hctx,
-                                     struct request *rq, blk_qc_t *cookie)
+static void blk_mq_try_issue_directly(struct request *rq, blk_qc_t *cookie)
 {
        int ret;
        struct request_queue *q = rq->q;
+       struct blk_mq_hw_ctx *hctx = blk_mq_map_queue(q, rq->mq_ctx->cpu);
        struct blk_mq_queue_data bd = {
                .rq = rq,
                .list = NULL,
@@ -1414,11 +1414,11 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
 
                if (!(data.hctx->flags & BLK_MQ_F_BLOCKING)) {
                        rcu_read_lock();
-                       blk_mq_try_issue_directly(data.hctx, old_rq, &cookie);
+                       blk_mq_try_issue_directly(old_rq, &cookie);
                        rcu_read_unlock();
                } else {
                        srcu_idx = srcu_read_lock(&data.hctx->queue_rq_srcu);
-                       blk_mq_try_issue_directly(data.hctx, old_rq, &cookie);
+                       blk_mq_try_issue_directly(old_rq, &cookie);
                        srcu_read_unlock(&data.hctx->queue_rq_srcu, srcu_idx);
                }
                goto done;