|
@@ -1600,6 +1600,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)
|
|
@@ -1618,7 +1619,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);
|
|
|
}
|
|
|
|
|
@@ -1891,8 +1891,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);
|
|
|
|