mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 17:25:38 +00:00
blk-mq: free hctx->ctxs in queue's release handler
commitc3b4afca70
upstream. 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],6cd18e711d
(block: destroy bdi before blockdev is unregistered) Reported-by: Stefan Seyfried <stefan.seyfried@googlemail.com> Cc: NeilBrown <neilb@suse.de> Cc: Christoph Hellwig <hch@lst.de> Signed-off-by: Ming Lei <tom.leiming@gmail.com> Signed-off-by: Jens Axboe <axboe@fb.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
0ffafd0b1b
commit
3804579f5c
@ -1589,6 +1589,7 @@ static int blk_mq_hctx_notify(void *data, unsigned long action,
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
/* hctx->ctxs will be freed in queue's release handler */
|
||||
static void blk_mq_exit_hctx(struct request_queue *q,
|
||||
struct blk_mq_tag_set *set,
|
||||
struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx)
|
||||
@ -1607,7 +1608,6 @@ static void blk_mq_exit_hctx(struct request_queue *q,
|
||||
|
||||
blk_mq_unregister_cpu_notifier(&hctx->cpu_notifier);
|
||||
blk_free_flush_queue(hctx->fq);
|
||||
kfree(hctx->ctxs);
|
||||
blk_mq_free_bitmap(&hctx->ctx_map);
|
||||
}
|
||||
|
||||
@ -1873,8 +1873,12 @@ void blk_mq_release(struct request_queue *q)
|
||||
unsigned int i;
|
||||
|
||||
/* hctx kobj stays in hctx */
|
||||
queue_for_each_hw_ctx(q, hctx, i)
|
||||
queue_for_each_hw_ctx(q, hctx, i) {
|
||||
if (!hctx)
|
||||
continue;
|
||||
kfree(hctx->ctxs);
|
||||
kfree(hctx);
|
||||
}
|
||||
|
||||
kfree(q->queue_hw_ctx);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user