diff options
author | Yu Kuai <yukuai3@huawei.com> | 2023-11-25 09:16:00 +0100 |
---|---|---|
committer | Song Liu <song@kernel.org> | 2023-11-28 00:49:04 +0100 |
commit | c891f1fd90e66e584bb1353e1859cef7c9eb36f8 (patch) | |
tree | 564d8541ff7bc4be1145f85bb0ef194c833ea587 /drivers/md/raid5.c | |
parent | Revert "md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d" (diff) | |
download | linux-c891f1fd90e66e584bb1353e1859cef7c9eb36f8.tar.xz linux-c891f1fd90e66e584bb1353e1859cef7c9eb36f8.zip |
md: remove flag RemoveSynchronized
rcu is not used correctly here, because synchronize_rcu() is called
before replacing old value, for example:
remove_and_add_spares // other path
synchronize_rcu
// called before replacing old value
set_bit(RemoveSynchronized)
rcu_read_lock()
rdev = conf->mirros[].rdev
pers->hot_remove_disk
conf->mirros[].rdev = NULL;
if (!test_bit(RemoveSynchronized))
synchronize_rcu
/*
* won't be called, and won't wait
* for concurrent readers to be done.
*/
// access rdev after remove_and_add_spares()
rcu_read_unlock()
Fortunately, there is a separate rcu protection to prevent such rdev
to be freed:
md_kick_rdev_from_array //other path
rcu_read_lock()
rdev = conf->mirros[].rdev
list_del_rcu(&rdev->same_set)
rcu_read_unlock()
/*
* rdev can be removed from conf, but
* rdev won't be freed.
*/
synchronize_rcu()
free rdev
Hence remove this useless flag and prepare to remove rcu protection to
access rdev from 'conf'.
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Signed-off-by: Song Liu <song@kernel.org>
Link: https://lore.kernel.org/r/20231125081604.3939938-2-yukuai1@huaweicloud.com
Diffstat (limited to '')
-rw-r--r-- | drivers/md/raid5.c | 9 |
1 files changed, 0 insertions, 9 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index fcc8a44dd4fd..d431e4625cc5 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -8233,15 +8233,6 @@ static int raid5_remove_disk(struct mddev *mddev, struct md_rdev *rdev) goto abort; } *rdevp = NULL; - if (!test_bit(RemoveSynchronized, &rdev->flags)) { - lockdep_assert_held(&mddev->reconfig_mutex); - synchronize_rcu(); - if (atomic_read(&rdev->nr_pending)) { - /* lost the race, try later */ - err = -EBUSY; - rcu_assign_pointer(*rdevp, rdev); - } - } if (!err) { err = log_modify(conf, rdev, false); if (err) |