Skip to content

Commit c36591f

Browse files
committed
Merge tag 'md-next-20230623' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md into for-6.5/block-late
Pull MD fixes from Song. * tag 'md-next-20230623' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md: raid10: avoid spin_lock from fastpath from raid10_unplug() md: fix 'delete_mutex' deadlock md: use mddev->external to select holder in export_rdev() md/raid1-10: fix casting from randomized structure in raid1_submit_write() md/raid10: fix the condition to call bio_end_io_acct()
2 parents fcaa174 + a8d5fdd commit c36591f

4 files changed

Lines changed: 16 additions & 28 deletions

File tree

drivers/md/md.c

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,6 @@ void mddev_init(struct mddev *mddev)
643643
{
644644
mutex_init(&mddev->open_mutex);
645645
mutex_init(&mddev->reconfig_mutex);
646-
mutex_init(&mddev->delete_mutex);
647646
mutex_init(&mddev->bitmap_info.mutex);
648647
INIT_LIST_HEAD(&mddev->disks);
649648
INIT_LIST_HEAD(&mddev->all_mddevs);
@@ -749,26 +748,15 @@ static void mddev_free(struct mddev *mddev)
749748

750749
static const struct attribute_group md_redundancy_group;
751750

752-
static void md_free_rdev(struct mddev *mddev)
751+
void mddev_unlock(struct mddev *mddev)
753752
{
754753
struct md_rdev *rdev;
755754
struct md_rdev *tmp;
755+
LIST_HEAD(delete);
756756

757-
mutex_lock(&mddev->delete_mutex);
758-
if (list_empty(&mddev->deleting))
759-
goto out;
760-
761-
list_for_each_entry_safe(rdev, tmp, &mddev->deleting, same_set) {
762-
list_del_init(&rdev->same_set);
763-
kobject_del(&rdev->kobj);
764-
export_rdev(rdev, mddev);
765-
}
766-
out:
767-
mutex_unlock(&mddev->delete_mutex);
768-
}
757+
if (!list_empty(&mddev->deleting))
758+
list_splice_init(&mddev->deleting, &delete);
769759

770-
void mddev_unlock(struct mddev *mddev)
771-
{
772760
if (mddev->to_remove) {
773761
/* These cannot be removed under reconfig_mutex as
774762
* an access to the files will try to take reconfig_mutex
@@ -808,7 +796,11 @@ void mddev_unlock(struct mddev *mddev)
808796
} else
809797
mutex_unlock(&mddev->reconfig_mutex);
810798

811-
md_free_rdev(mddev);
799+
list_for_each_entry_safe(rdev, tmp, &delete, same_set) {
800+
list_del_init(&rdev->same_set);
801+
kobject_del(&rdev->kobj);
802+
export_rdev(rdev, mddev);
803+
}
812804

813805
md_wakeup_thread(mddev->thread);
814806
wake_up(&mddev->sb_wait);
@@ -2458,7 +2450,7 @@ static void export_rdev(struct md_rdev *rdev, struct mddev *mddev)
24582450
if (test_bit(AutoDetected, &rdev->flags))
24592451
md_autodetect_dev(rdev->bdev->bd_dev);
24602452
#endif
2461-
blkdev_put(rdev->bdev, mddev->major_version == -2 ? &claim_rdev : rdev);
2453+
blkdev_put(rdev->bdev, mddev->external ? &claim_rdev : rdev);
24622454
rdev->bdev = NULL;
24632455
kobject_put(&rdev->kobj);
24642456
}
@@ -2488,9 +2480,7 @@ static void md_kick_rdev_from_array(struct md_rdev *rdev)
24882480
* reconfig_mutex is held, hence it can't be called under
24892481
* reconfig_mutex and it's delayed to mddev_unlock().
24902482
*/
2491-
mutex_lock(&mddev->delete_mutex);
24922483
list_add(&rdev->same_set, &mddev->deleting);
2493-
mutex_unlock(&mddev->delete_mutex);
24942484
}
24952485

24962486
static void export_array(struct mddev *mddev)
@@ -6140,7 +6130,7 @@ static void md_clean(struct mddev *mddev)
61406130
mddev->resync_min = 0;
61416131
mddev->resync_max = MaxSector;
61426132
mddev->reshape_position = MaxSector;
6143-
mddev->external = 0;
6133+
/* we still need mddev->external in export_rdev, do not clear it yet */
61446134
mddev->persistent = 0;
61456135
mddev->level = LEVEL_NONE;
61466136
mddev->clevel[0] = 0;

drivers/md/md.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -531,11 +531,9 @@ struct mddev {
531531

532532
/*
533533
* Temporarily store rdev that will be finally removed when
534-
* reconfig_mutex is unlocked.
534+
* reconfig_mutex is unlocked, protected by reconfig_mutex.
535535
*/
536536
struct list_head deleting;
537-
/* Protect the deleting list */
538-
struct mutex delete_mutex;
539537

540538
bool has_superblocks:1;
541539
bool fail_last_dev:1;

drivers/md/raid1-10.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ static void md_bio_reset_resync_pages(struct bio *bio, struct resync_pages *rp,
116116

117117
static inline void raid1_submit_write(struct bio *bio)
118118
{
119-
struct md_rdev *rdev = (struct md_rdev *)bio->bi_bdev;
119+
struct md_rdev *rdev = (void *)bio->bi_bdev;
120120

121121
bio->bi_next = NULL;
122122
bio_set_dev(bio, rdev->bdev);

drivers/md/raid10.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ static void raid_end_bio_io(struct r10bio *r10_bio)
325325
if (!test_bit(R10BIO_Uptodate, &r10_bio->state))
326326
bio->bi_status = BLK_STS_IOERR;
327327

328-
if (blk_queue_io_stat(bio->bi_bdev->bd_disk->queue))
328+
if (r10_bio->start_time)
329329
bio_end_io_acct(bio, r10_bio->start_time);
330330
bio_endio(bio);
331331
/*
@@ -1118,7 +1118,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
11181118
spin_lock_irq(&conf->device_lock);
11191119
bio_list_merge(&conf->pending_bio_list, &plug->pending);
11201120
spin_unlock_irq(&conf->device_lock);
1121-
wake_up(&conf->wait_barrier);
1121+
wake_up_barrier(conf);
11221122
md_wakeup_thread(mddev->thread);
11231123
kfree(plug);
11241124
return;
@@ -1127,7 +1127,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
11271127
/* we aren't scheduling, so we can do the write-out directly. */
11281128
bio = bio_list_get(&plug->pending);
11291129
raid1_prepare_flush_writes(mddev->bitmap);
1130-
wake_up(&conf->wait_barrier);
1130+
wake_up_barrier(conf);
11311131

11321132
while (bio) { /* submit pending writes */
11331133
struct bio *next = bio->bi_next;

0 commit comments

Comments
 (0)