Skip to content

Commit f7bf358

Browse files
Tetsuo Handaaxboe
authored andcommitted
brd: reduce the brd_devices_mutex scope
As with commit 8b52d8b ("loop: reorder loop_exit"), unregister_blkdev() needs to be called first in order to avoid calling brd_alloc() from brd_probe() after brd_del_one() from brd_exit(). Then, we can avoid holding global mutex during add_disk()/del_gendisk() as with commit 1c500ad ("loop: reduce the loop_ctl_mutex scope"). Signed-off-by: Tetsuo Handa <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent c411080 commit f7bf358

File tree

1 file changed

+22
-22
lines changed

1 file changed

+22
-22
lines changed

drivers/block/brd.c

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -373,10 +373,22 @@ static int brd_alloc(int i)
373373
struct gendisk *disk;
374374
char buf[DISK_NAME_LEN];
375375

376+
mutex_lock(&brd_devices_mutex);
377+
list_for_each_entry(brd, &brd_devices, brd_list) {
378+
if (brd->brd_number == i) {
379+
mutex_unlock(&brd_devices_mutex);
380+
return -EEXIST;
381+
}
382+
}
376383
brd = kzalloc(sizeof(*brd), GFP_KERNEL);
377-
if (!brd)
384+
if (!brd) {
385+
mutex_unlock(&brd_devices_mutex);
378386
return -ENOMEM;
387+
}
379388
brd->brd_number = i;
389+
list_add_tail(&brd->brd_list, &brd_devices);
390+
mutex_unlock(&brd_devices_mutex);
391+
380392
spin_lock_init(&brd->brd_lock);
381393
INIT_RADIX_TREE(&brd->brd_pages, GFP_ATOMIC);
382394

@@ -411,37 +423,30 @@ static int brd_alloc(int i)
411423
blk_queue_flag_set(QUEUE_FLAG_NONROT, disk->queue);
412424
blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, disk->queue);
413425
add_disk(disk);
414-
list_add_tail(&brd->brd_list, &brd_devices);
415426

416427
return 0;
417428

418429
out_free_dev:
430+
mutex_lock(&brd_devices_mutex);
431+
list_del(&brd->brd_list);
432+
mutex_unlock(&brd_devices_mutex);
419433
kfree(brd);
420434
return -ENOMEM;
421435
}
422436

423437
static void brd_probe(dev_t dev)
424438
{
425-
int i = MINOR(dev) / max_part;
426-
struct brd_device *brd;
427-
428-
mutex_lock(&brd_devices_mutex);
429-
list_for_each_entry(brd, &brd_devices, brd_list) {
430-
if (brd->brd_number == i)
431-
goto out_unlock;
432-
}
433-
434-
brd_alloc(i);
435-
out_unlock:
436-
mutex_unlock(&brd_devices_mutex);
439+
brd_alloc(MINOR(dev) / max_part);
437440
}
438441

439442
static void brd_del_one(struct brd_device *brd)
440443
{
441-
list_del(&brd->brd_list);
442444
del_gendisk(brd->brd_disk);
443445
blk_cleanup_disk(brd->brd_disk);
444446
brd_free_pages(brd);
447+
mutex_lock(&brd_devices_mutex);
448+
list_del(&brd->brd_list);
449+
mutex_unlock(&brd_devices_mutex);
445450
kfree(brd);
446451
}
447452

@@ -491,25 +496,21 @@ static int __init brd_init(void)
491496

492497
brd_debugfs_dir = debugfs_create_dir("ramdisk_pages", NULL);
493498

494-
mutex_lock(&brd_devices_mutex);
495499
for (i = 0; i < rd_nr; i++) {
496500
err = brd_alloc(i);
497501
if (err)
498502
goto out_free;
499503
}
500504

501-
mutex_unlock(&brd_devices_mutex);
502-
503505
pr_info("brd: module loaded\n");
504506
return 0;
505507

506508
out_free:
509+
unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
507510
debugfs_remove_recursive(brd_debugfs_dir);
508511

509512
list_for_each_entry_safe(brd, next, &brd_devices, brd_list)
510513
brd_del_one(brd);
511-
mutex_unlock(&brd_devices_mutex);
512-
unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
513514

514515
pr_info("brd: module NOT loaded !!!\n");
515516
return err;
@@ -519,13 +520,12 @@ static void __exit brd_exit(void)
519520
{
520521
struct brd_device *brd, *next;
521522

523+
unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
522524
debugfs_remove_recursive(brd_debugfs_dir);
523525

524526
list_for_each_entry_safe(brd, next, &brd_devices, brd_list)
525527
brd_del_one(brd);
526528

527-
unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
528-
529529
pr_info("brd: module unloaded\n");
530530
}
531531

0 commit comments

Comments
 (0)