diff options
-rw-r--r-- | block/blk-mq.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c index 041f7b7fa0d6..211ef367345f 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
@@ -301,11 +301,12 @@ static struct request *blk_mq_get_request(struct request_queue *q, | |||
301 | struct elevator_queue *e = q->elevator; | 301 | struct elevator_queue *e = q->elevator; |
302 | struct request *rq; | 302 | struct request *rq; |
303 | unsigned int tag; | 303 | unsigned int tag; |
304 | struct blk_mq_ctx *local_ctx = NULL; | ||
304 | 305 | ||
305 | blk_queue_enter_live(q); | 306 | blk_queue_enter_live(q); |
306 | data->q = q; | 307 | data->q = q; |
307 | if (likely(!data->ctx)) | 308 | if (likely(!data->ctx)) |
308 | data->ctx = blk_mq_get_ctx(q); | 309 | data->ctx = local_ctx = blk_mq_get_ctx(q); |
309 | if (likely(!data->hctx)) | 310 | if (likely(!data->hctx)) |
310 | data->hctx = blk_mq_map_queue(q, data->ctx->cpu); | 311 | data->hctx = blk_mq_map_queue(q, data->ctx->cpu); |
311 | if (op & REQ_NOWAIT) | 312 | if (op & REQ_NOWAIT) |
@@ -324,6 +325,10 @@ static struct request *blk_mq_get_request(struct request_queue *q, | |||
324 | 325 | ||
325 | tag = blk_mq_get_tag(data); | 326 | tag = blk_mq_get_tag(data); |
326 | if (tag == BLK_MQ_TAG_FAIL) { | 327 | if (tag == BLK_MQ_TAG_FAIL) { |
328 | if (local_ctx) { | ||
329 | blk_mq_put_ctx(local_ctx); | ||
330 | data->ctx = NULL; | ||
331 | } | ||
327 | blk_queue_exit(q); | 332 | blk_queue_exit(q); |
328 | return NULL; | 333 | return NULL; |
329 | } | 334 | } |
@@ -356,12 +361,12 @@ struct request *blk_mq_alloc_request(struct request_queue *q, unsigned int op, | |||
356 | 361 | ||
357 | rq = blk_mq_get_request(q, NULL, op, &alloc_data); | 362 | rq = blk_mq_get_request(q, NULL, op, &alloc_data); |
358 | 363 | ||
359 | blk_mq_put_ctx(alloc_data.ctx); | ||
360 | blk_queue_exit(q); | ||
361 | |||
362 | if (!rq) | 364 | if (!rq) |
363 | return ERR_PTR(-EWOULDBLOCK); | 365 | return ERR_PTR(-EWOULDBLOCK); |
364 | 366 | ||
367 | blk_mq_put_ctx(alloc_data.ctx); | ||
368 | blk_queue_exit(q); | ||
369 | |||
365 | rq->__data_len = 0; | 370 | rq->__data_len = 0; |
366 | rq->__sector = (sector_t) -1; | 371 | rq->__sector = (sector_t) -1; |
367 | rq->bio = rq->biotail = NULL; | 372 | rq->bio = rq->biotail = NULL; |
@@ -407,11 +412,11 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q, | |||
407 | 412 | ||
408 | rq = blk_mq_get_request(q, NULL, op, &alloc_data); | 413 | rq = blk_mq_get_request(q, NULL, op, &alloc_data); |
409 | 414 | ||
410 | blk_queue_exit(q); | ||
411 | |||
412 | if (!rq) | 415 | if (!rq) |
413 | return ERR_PTR(-EWOULDBLOCK); | 416 | return ERR_PTR(-EWOULDBLOCK); |
414 | 417 | ||
418 | blk_queue_exit(q); | ||
419 | |||
415 | return rq; | 420 | return rq; |
416 | } | 421 | } |
417 | EXPORT_SYMBOL_GPL(blk_mq_alloc_request_hctx); | 422 | EXPORT_SYMBOL_GPL(blk_mq_alloc_request_hctx); |