Skip to content

Commit 1ad43c0

Browse files
Ming Leiaxboe
authored andcommitted
blk-mq: don't leak preempt counter/q_usage_counter when allocating rq failed
When blk_mq_get_request() failed, preempt counter isn't released, and blk_mq_make_request() doesn't release the counter too. This patch fixes the issue, and makes sure that preempt counter is only held if rq is allocated successfully. The same policy is applied on .q_usage_counter too. Signed-off-by: Ming Lei <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 46d556e commit 1ad43c0

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

block/blk-mq.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -301,11 +301,12 @@ static struct request *blk_mq_get_request(struct request_queue *q,
301301
struct elevator_queue *e = q->elevator;
302302
struct request *rq;
303303
unsigned int tag;
304+
struct blk_mq_ctx *local_ctx = NULL;
304305

305306
blk_queue_enter_live(q);
306307
data->q = q;
307308
if (likely(!data->ctx))
308-
data->ctx = blk_mq_get_ctx(q);
309+
data->ctx = local_ctx = blk_mq_get_ctx(q);
309310
if (likely(!data->hctx))
310311
data->hctx = blk_mq_map_queue(q, data->ctx->cpu);
311312
if (op & REQ_NOWAIT)
@@ -324,6 +325,10 @@ static struct request *blk_mq_get_request(struct request_queue *q,
324325

325326
tag = blk_mq_get_tag(data);
326327
if (tag == BLK_MQ_TAG_FAIL) {
328+
if (local_ctx) {
329+
blk_mq_put_ctx(local_ctx);
330+
data->ctx = NULL;
331+
}
327332
blk_queue_exit(q);
328333
return NULL;
329334
}
@@ -356,12 +361,12 @@ struct request *blk_mq_alloc_request(struct request_queue *q, unsigned int op,
356361

357362
rq = blk_mq_get_request(q, NULL, op, &alloc_data);
358363

359-
blk_mq_put_ctx(alloc_data.ctx);
360-
blk_queue_exit(q);
361-
362364
if (!rq)
363365
return ERR_PTR(-EWOULDBLOCK);
364366

367+
blk_mq_put_ctx(alloc_data.ctx);
368+
blk_queue_exit(q);
369+
365370
rq->__data_len = 0;
366371
rq->__sector = (sector_t) -1;
367372
rq->bio = rq->biotail = NULL;
@@ -407,11 +412,11 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q,
407412

408413
rq = blk_mq_get_request(q, NULL, op, &alloc_data);
409414

410-
blk_queue_exit(q);
411-
412415
if (!rq)
413416
return ERR_PTR(-EWOULDBLOCK);
414417

418+
blk_queue_exit(q);
419+
415420
return rq;
416421
}
417422
EXPORT_SYMBOL_GPL(blk_mq_alloc_request_hctx);

0 commit comments

Comments
 (0)