diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-20 13:06:20 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-20 13:06:20 -0800 |
commit | 5a1efc6e68a095917277459091fafba6a6baef17 (patch) | |
tree | 9f3d9b14893689cee1b7918e51b15ca135f6563a /block/blk-mq.c | |
parent | 6d6e352c80f22c446d933ca8103e02bac1f09129 (diff) | |
parent | 01b983c9fcfeea5774ca2df2e167b68c3c299278 (diff) |
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
Pull block IO fixes from Jens Axboe:
"Normally I'd defer my initial for-linus pull request until after the
merge window, but a race was uncovered in the virtio-blk conversion to
blk-mq that could cause hangs. So here's a small collection of fixes
for you to pull:
- The fix for the virtio-blk IO hang reported by Dave Chinner, from
Shaohua and myself.
- Add the Insert blktrace event for blk-mq. This makes 'btt' happy
when it is doing it's state transition analysis.
- Ensure that blk-mq has disk/partition stats enabled by default,
instead of making it opt-in.
- A fix for __bio_add_page() and large sector counts"
* 'for-linus' of git://git.kernel.dk/linux-block:
blk-mq: add blktrace insert event trace
virtio-blk: virtqueue_kick() must be ordered with other virtqueue operations
blk-mq: ensure that we set REQ_IO_STAT so diskstats work
bio: fix argument of __bio_add_page() for max_sectors > 0xffff
Diffstat (limited to 'block/blk-mq.c')
-rw-r--r-- | block/blk-mq.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c index 862f458d4760..cdc629cf075b 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -171,9 +171,12 @@ bool blk_mq_can_queue(struct blk_mq_hw_ctx *hctx) } EXPORT_SYMBOL(blk_mq_can_queue); -static void blk_mq_rq_ctx_init(struct blk_mq_ctx *ctx, struct request *rq, - unsigned int rw_flags) +static void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx, + struct request *rq, unsigned int rw_flags) { + if (blk_queue_io_stat(q)) + rw_flags |= REQ_IO_STAT; + rq->mq_ctx = ctx; rq->cmd_flags = rw_flags; ctx->rq_dispatched[rw_is_sync(rw_flags)]++; @@ -197,7 +200,7 @@ static struct request *blk_mq_alloc_request_pinned(struct request_queue *q, rq = __blk_mq_alloc_request(hctx, gfp & ~__GFP_WAIT, reserved); if (rq) { - blk_mq_rq_ctx_init(ctx, rq, rw); + blk_mq_rq_ctx_init(q, ctx, rq, rw); break; } else if (!(gfp & __GFP_WAIT)) break; @@ -718,6 +721,8 @@ static void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx, { struct blk_mq_ctx *ctx = rq->mq_ctx; + trace_block_rq_insert(hctx->queue, rq); + list_add_tail(&rq->queuelist, &ctx->rq_list); blk_mq_hctx_mark_pending(hctx, ctx); @@ -921,7 +926,7 @@ static void blk_mq_make_request(struct request_queue *q, struct bio *bio) trace_block_getrq(q, bio, rw); rq = __blk_mq_alloc_request(hctx, GFP_ATOMIC, false); if (likely(rq)) - blk_mq_rq_ctx_init(ctx, rq, rw); + blk_mq_rq_ctx_init(q, ctx, rq, rw); else { blk_mq_put_ctx(ctx); trace_block_sleeprq(q, bio, rw); @@ -1377,6 +1382,7 @@ struct request_queue *blk_mq_init_queue(struct blk_mq_reg *reg, q->queue_hw_ctx = hctxs; q->mq_ops = reg->ops; + q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT; blk_queue_make_request(q, blk_mq_make_request); blk_queue_rq_timed_out(q, reg->ops->timeout); |