Skip to content

Commit c0f3fd2

Browse files
committed
blk-mq: fix deadlock in blk_mq_register_disk() error path
If we fail registering any of the hardware queues, we call into blk_mq_unregister_disk() with the hotplug mutex already held. Since blk_mq_unregister_disk() attempts to acquire the same mutex, we end up in a less than happy place. Reported-by: Jinpu Wang <jinpu.wang@profitbricks.com> Signed-off-by: Jens Axboe <axboe@fb.com>
1 parent 6d25ec1 commit c0f3fd2

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

block/blk-mq-sysfs.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -380,15 +380,13 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx)
380380
return ret;
381381
}
382382

383-
void blk_mq_unregister_disk(struct gendisk *disk)
383+
static void __blk_mq_unregister_disk(struct gendisk *disk)
384384
{
385385
struct request_queue *q = disk->queue;
386386
struct blk_mq_hw_ctx *hctx;
387387
struct blk_mq_ctx *ctx;
388388
int i, j;
389389

390-
blk_mq_disable_hotplug();
391-
392390
queue_for_each_hw_ctx(q, hctx, i) {
393391
blk_mq_unregister_hctx(hctx);
394392

@@ -405,6 +403,12 @@ void blk_mq_unregister_disk(struct gendisk *disk)
405403
kobject_put(&disk_to_dev(disk)->kobj);
406404

407405
q->mq_sysfs_init_done = false;
406+
}
407+
408+
void blk_mq_unregister_disk(struct gendisk *disk)
409+
{
410+
blk_mq_disable_hotplug();
411+
__blk_mq_unregister_disk(disk);
408412
blk_mq_enable_hotplug();
409413
}
410414

@@ -450,7 +454,7 @@ int blk_mq_register_disk(struct gendisk *disk)
450454
}
451455

452456
if (ret)
453-
blk_mq_unregister_disk(disk);
457+
__blk_mq_unregister_disk(disk);
454458
else
455459
q->mq_sysfs_init_done = true;
456460
out:

0 commit comments

Comments
 (0)