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 1c7b774dbb48..7cbf199bd168 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3742,7 +3742,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); @@ -9266,7 +9265,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; /* @@ -9364,6 +9363,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 146eda6c4961..dd721b9c19b9 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 eebbf9185deb..e285481464b9 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); @@ -4172,6 +4173,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