Skip to content

Commit c3b4afc

Browse files
ming1axboe
authored andcommitted
blk-mq: free hctx->ctxs in queue's release handler
Now blk_cleanup_queue() can be called before calling del_gendisk()[1], inside which hctx->ctxs is touched from blk_mq_unregister_hctx(), but the variable has been freed by blk_cleanup_queue() at that time. So this patch moves freeing of hctx->ctxs into queue's release handler for fixing the oops reported by Stefan. [1], 6cd18e7 (block: destroy bdi before blockdev is unregistered) Reported-by: Stefan Seyfried <[email protected]> Cc: NeilBrown <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: [email protected] (v4.0) Signed-off-by: Ming Lei <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent d4a4f75 commit c3b4afc

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

block/blk-mq.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,6 +1600,7 @@ static int blk_mq_hctx_notify(void *data, unsigned long action,
16001600
return NOTIFY_OK;
16011601
}
16021602

1603+
/* hctx->ctxs will be freed in queue's release handler */
16031604
static void blk_mq_exit_hctx(struct request_queue *q,
16041605
struct blk_mq_tag_set *set,
16051606
struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx)
@@ -1618,7 +1619,6 @@ static void blk_mq_exit_hctx(struct request_queue *q,
16181619

16191620
blk_mq_unregister_cpu_notifier(&hctx->cpu_notifier);
16201621
blk_free_flush_queue(hctx->fq);
1621-
kfree(hctx->ctxs);
16221622
blk_mq_free_bitmap(&hctx->ctx_map);
16231623
}
16241624

@@ -1891,8 +1891,12 @@ void blk_mq_release(struct request_queue *q)
18911891
unsigned int i;
18921892

18931893
/* hctx kobj stays in hctx */
1894-
queue_for_each_hw_ctx(q, hctx, i)
1894+
queue_for_each_hw_ctx(q, hctx, i) {
1895+
if (!hctx)
1896+
continue;
1897+
kfree(hctx->ctxs);
18951898
kfree(hctx);
1899+
}
18961900

18971901
kfree(q->queue_hw_ctx);
18981902

0 commit comments

Comments
 (0)