Skip to content

Commit

Permalink
blk-mq: free hctx->ctxs in queue's release handler
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
ming1 authored and axboe committed Jun 9, 2015
1 parent d4a4f75 commit c3b4afc
Showing 1 changed file with 6 additions and 2 deletions.
8 changes: 6 additions & 2 deletions block/blk-mq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);
}

Expand Down Expand Up @@ -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);

Expand Down

0 comments on commit c3b4afc

Please sign in to comment.