Skip to content

Commit e169bd4

Browse files
bigunclemaxaxboe
authored andcommitted
aoe: avoid potential deadlock at set_capacity
Move set_capacity() outside of the section procected by (&d->lock). To avoid possible interrupt unsafe locking scenario: CPU0 CPU1 ---- ---- [1] lock(&bdev->bd_size_lock); local_irq_disable(); [2] lock(&d->lock); [3] lock(&bdev->bd_size_lock); <Interrupt> [4] lock(&d->lock); *** DEADLOCK *** Where [1](&bdev->bd_size_lock) hold by zram_add()->set_capacity(). [2]lock(&d->lock) hold by aoeblk_gdalloc(). And aoeblk_gdalloc() is trying to acquire [3](&bdev->bd_size_lock) at set_capacity() call. In this situation an attempt to acquire [4]lock(&d->lock) from aoecmd_cfg_rsp() will lead to deadlock. So the simplest solution is breaking lock dependency [2](&d->lock) -> [3](&bdev->bd_size_lock) by moving set_capacity() outside. Signed-off-by: Maksim Kiselev <bigunclemax@gmail.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/r/20240124072436.3745720-2-bigunclemax@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 13f3956 commit e169bd4

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

drivers/block/aoe/aoeblk.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ aoeblk_gdalloc(void *vp)
333333
struct gendisk *gd;
334334
mempool_t *mp;
335335
struct blk_mq_tag_set *set;
336+
sector_t ssize;
336337
ulong flags;
337338
int late = 0;
338339
int err;
@@ -396,7 +397,7 @@ aoeblk_gdalloc(void *vp)
396397
gd->minors = AOE_PARTITIONS;
397398
gd->fops = &aoe_bdops;
398399
gd->private_data = d;
399-
set_capacity(gd, d->ssize);
400+
ssize = d->ssize;
400401
snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d",
401402
d->aoemajor, d->aoeminor);
402403

@@ -405,6 +406,8 @@ aoeblk_gdalloc(void *vp)
405406

406407
spin_unlock_irqrestore(&d->lock, flags);
407408

409+
set_capacity(gd, ssize);
410+
408411
err = device_add_disk(NULL, gd, aoe_attr_groups);
409412
if (err)
410413
goto out_disk_cleanup;

0 commit comments

Comments
 (0)