This patch depends on patch 10. Change nr_pending from atomic mode to percpu mode. Signed-off-by: Keisuke TADA <keisuke1.tada@xxxxxxxxxx> Signed-off-by: Toshifumi OHTAKE <toshifumi.ootake@xxxxxxxxxx> --- drivers/md/md.c | 5 +++-- drivers/md/raid1.c | 6 ++++++ drivers/md/raid10.c | 6 ++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 18d0f214098b..4928d63209cb 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3746,7 +3746,6 @@ int md_rdev_init(struct md_rdev *rdev) ret = percpu_ref_init(&rdev->nr_pending, percpu_wakeup_handle_req_pending, PERCPU_REF_ALLOW_REINIT, GFP_KERNEL); WARN_ON(ret); - percpu_ref_switch_to_atomic_sync(&rdev->nr_pending); nr_pending_dec(rdev); atomic_set(&rdev->read_errors, 0); atomic_set(&rdev->corrected_errors, 0); @@ -9280,7 +9279,7 @@ static bool rdev_removeable(struct md_rdev *rdev) return false; /* There are still inflight io, don't remove this rdev. */ - if (nr_pending_is_not_zero(rdev)) + if (nr_pending_is_atomic_mode(rdev) && nr_pending_is_not_zero(rdev)) return false; /* @@ -9384,6 +9383,8 @@ static int remove_and_add_spares(struct mddev *mddev, rdev->raid_disk = -1; removed++; } + if (mddev->pers->level != 1 && mddev->pers->level != 10) + percpu_ref_switch_to_percpu(&rdev->nr_pending); } if (removed && mddev->kobj.sd) diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index c38ae13aadab..13fcb80e1cb0 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -2006,6 +2006,7 @@ static int raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev) conf->mirrors[conf->raid_disks + number].rdev = NULL; unfreeze_array(conf); } + percpu_ref_switch_to_percpu(&rdev->nr_pending); clear_bit(WantReplacement, &rdev->flags); err = md_integrity_register(mddev); @@ -3298,6 +3299,11 @@ static int raid1_run(struct mddev *mddev) static void raid1_free(struct mddev *mddev, void *priv) { struct r1conf *conf = priv; + struct md_rdev *rdev; + + rdev_for_each(rdev, mddev) { + percpu_ref_switch_to_percpu(&rdev->nr_pending); + } mempool_exit(&conf->r1bio_pool); kfree(conf->mirrors); diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 66896a1076e1..f8ea5ec22629 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -2180,6 +2180,7 @@ static int raid10_remove_disk(struct mddev *mddev, struct md_rdev *rdev) clear_bit(Replacement, &p->replacement->flags); WRITE_ONCE(p->replacement, NULL); } + percpu_ref_switch_to_percpu(&rdev->nr_pending); clear_bit(WantReplacement, &rdev->flags); err = md_integrity_register(mddev); @@ -4168,6 +4169,11 @@ static int raid10_run(struct mddev *mddev) static void raid10_free(struct mddev *mddev, void *priv) { + struct md_rdev *rdev; + + rdev_for_each(rdev, mddev) { + percpu_ref_switch_to_percpu(&rdev->nr_pending); + } raid10_free_conf(priv); } -- 2.34.1