aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.com>2017-10-18 21:49:15 -0400
committerShaohua Li <shli@fb.com>2017-11-02 00:32:20 -0400
commitb03e0ccb5ab9df3efbe51c87843a1ffbecbafa1f (patch)
tree4991194aa067e459500bf1c6515b6d716145165c
parent35bfc52187f6df8779d0f1cebdb52b7f797baf4e (diff)
md: remove special meaning of ->quiesce(.., 2)
The '2' argument means "wake up anything that is waiting". This is an inelegant part of the design and was added to help support management of suspend_lo/suspend_hi setting. Now that suspend_lo/hi is managed in mddev_suspend/resume, that need is gone. These is still a couple of places where we call 'quiesce' with an argument of '2', but they can safely be changed to call ->quiesce(.., 1); ->quiesce(.., 0) which achieve the same result at the small cost of pausing IO briefly. This removes a small "optimization" from suspend_{hi,lo}_store, but it isn't clear that optimization served a useful purpose. The code now is a lot clearer. Suggested-by: Shaohua Li <shli@kernel.org> Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Shaohua Li <shli@fb.com>
-rw-r--r--drivers/md/md-cluster.c6
-rw-r--r--drivers/md/md.c34
-rw-r--r--drivers/md/md.h9
-rw-r--r--drivers/md/raid0.c2
-rw-r--r--drivers/md/raid1.c13
-rw-r--r--drivers/md/raid10.c10
-rw-r--r--drivers/md/raid5-cache.c12
-rw-r--r--drivers/md/raid5-log.h2
-rw-r--r--drivers/md/raid5.c18
9 files changed, 37 insertions, 69 deletions
diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c
index bc81ecc24c96..d0fd1bd8575c 100644
--- a/drivers/md/md-cluster.c
+++ b/drivers/md/md-cluster.c
@@ -442,10 +442,11 @@ static void __remove_suspend_info(struct md_cluster_info *cinfo, int slot)
442static void remove_suspend_info(struct mddev *mddev, int slot) 442static void remove_suspend_info(struct mddev *mddev, int slot)
443{ 443{
444 struct md_cluster_info *cinfo = mddev->cluster_info; 444 struct md_cluster_info *cinfo = mddev->cluster_info;
445 mddev->pers->quiesce(mddev, 1);
445 spin_lock_irq(&cinfo->suspend_lock); 446 spin_lock_irq(&cinfo->suspend_lock);
446 __remove_suspend_info(cinfo, slot); 447 __remove_suspend_info(cinfo, slot);
447 spin_unlock_irq(&cinfo->suspend_lock); 448 spin_unlock_irq(&cinfo->suspend_lock);
448 mddev->pers->quiesce(mddev, 2); 449 mddev->pers->quiesce(mddev, 0);
449} 450}
450 451
451 452
@@ -492,13 +493,12 @@ static void process_suspend_info(struct mddev *mddev,
492 s->lo = lo; 493 s->lo = lo;
493 s->hi = hi; 494 s->hi = hi;
494 mddev->pers->quiesce(mddev, 1); 495 mddev->pers->quiesce(mddev, 1);
495 mddev->pers->quiesce(mddev, 0);
496 spin_lock_irq(&cinfo->suspend_lock); 496 spin_lock_irq(&cinfo->suspend_lock);
497 /* Remove existing entry (if exists) before adding */ 497 /* Remove existing entry (if exists) before adding */
498 __remove_suspend_info(cinfo, slot); 498 __remove_suspend_info(cinfo, slot);
499 list_add(&s->list, &cinfo->suspend_list); 499 list_add(&s->list, &cinfo->suspend_list);
500 spin_unlock_irq(&cinfo->suspend_lock); 500 spin_unlock_irq(&cinfo->suspend_lock);
501 mddev->pers->quiesce(mddev, 2); 501 mddev->pers->quiesce(mddev, 0);
502} 502}
503 503
504static void process_add_new_disk(struct mddev *mddev, struct cluster_msg *cmsg) 504static void process_add_new_disk(struct mddev *mddev, struct cluster_msg *cmsg)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 9155f00dca20..d441b1d9846c 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -4846,7 +4846,7 @@ suspend_lo_show(struct mddev *mddev, char *page)
4846static ssize_t 4846static ssize_t
4847suspend_lo_store(struct mddev *mddev, const char *buf, size_t len) 4847suspend_lo_store(struct mddev *mddev, const char *buf, size_t len)
4848{ 4848{
4849 unsigned long long old, new; 4849 unsigned long long new;
4850 int err; 4850 int err;
4851 4851
4852 err = kstrtoull(buf, 10, &new); 4852 err = kstrtoull(buf, 10, &new);
@@ -4862,17 +4862,10 @@ suspend_lo_store(struct mddev *mddev, const char *buf, size_t len)
4862 if (mddev->pers == NULL || 4862 if (mddev->pers == NULL ||
4863 mddev->pers->quiesce == NULL) 4863 mddev->pers->quiesce == NULL)
4864 goto unlock; 4864 goto unlock;
4865 old = mddev->suspend_lo; 4865 mddev_suspend(mddev);
4866 mddev->suspend_lo = new; 4866 mddev->suspend_lo = new;
4867 if (new >= old) { 4867 mddev_resume(mddev);
4868 /* Shrinking suspended region */ 4868
4869 wake_up(&mddev->sb_wait);
4870 mddev->pers->quiesce(mddev, 2);
4871 } else {
4872 /* Expanding suspended region - need to wait */
4873 mddev_suspend(mddev);
4874 mddev_resume(mddev);
4875 }
4876 err = 0; 4869 err = 0;
4877unlock: 4870unlock:
4878 mddev_unlock(mddev); 4871 mddev_unlock(mddev);
@@ -4890,7 +4883,7 @@ suspend_hi_show(struct mddev *mddev, char *page)
4890static ssize_t 4883static ssize_t
4891suspend_hi_store(struct mddev *mddev, const char *buf, size_t len) 4884suspend_hi_store(struct mddev *mddev, const char *buf, size_t len)
4892{ 4885{
4893 unsigned long long old, new; 4886 unsigned long long new;
4894 int err; 4887 int err;
4895 4888
4896 err = kstrtoull(buf, 10, &new); 4889 err = kstrtoull(buf, 10, &new);
@@ -4903,20 +4896,13 @@ suspend_hi_store(struct mddev *mddev, const char *buf, size_t len)
4903 if (err) 4896 if (err)
4904 return err; 4897 return err;
4905 err = -EINVAL; 4898 err = -EINVAL;
4906 if (mddev->pers == NULL || 4899 if (mddev->pers == NULL)
4907 mddev->pers->quiesce == NULL)
4908 goto unlock; 4900 goto unlock;
4909 old = mddev->suspend_hi; 4901
4902 mddev_suspend(mddev);
4910 mddev->suspend_hi = new; 4903 mddev->suspend_hi = new;
4911 if (new <= old) { 4904 mddev_resume(mddev);
4912 /* Shrinking suspended region */ 4905
4913 wake_up(&mddev->sb_wait);
4914 mddev->pers->quiesce(mddev, 2);
4915 } else {
4916 /* Expanding suspended region - need to wait */
4917 mddev_suspend(mddev);
4918 mddev_resume(mddev);
4919 }
4920 err = 0; 4906 err = 0;
4921unlock: 4907unlock:
4922 mddev_unlock(mddev); 4908 mddev_unlock(mddev);
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 03fc641e5da1..998b4ce1498f 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -544,12 +544,11 @@ struct md_personality
544 int (*check_reshape) (struct mddev *mddev); 544 int (*check_reshape) (struct mddev *mddev);
545 int (*start_reshape) (struct mddev *mddev); 545 int (*start_reshape) (struct mddev *mddev);
546 void (*finish_reshape) (struct mddev *mddev); 546 void (*finish_reshape) (struct mddev *mddev);
547 /* quiesce moves between quiescence states 547 /* quiesce suspends or resumes internal processing.
548 * 0 - fully active 548 * 1 - stop new actions and wait for action io to complete
549 * 1 - no new requests allowed 549 * 0 - return to normal behaviour
550 * others - reserved
551 */ 550 */
552 void (*quiesce) (struct mddev *mddev, int state); 551 void (*quiesce) (struct mddev *mddev, int quiesce);
553 /* takeover is used to transition an array from one 552 /* takeover is used to transition an array from one
554 * personality to another. The new personality must be able 553 * personality to another. The new personality must be able
555 * to handle the data in the current layout. 554 * to handle the data in the current layout.
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 5a00fc118470..5ecba9eef441 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -768,7 +768,7 @@ static void *raid0_takeover(struct mddev *mddev)
768 return ERR_PTR(-EINVAL); 768 return ERR_PTR(-EINVAL);
769} 769}
770 770
771static void raid0_quiesce(struct mddev *mddev, int state) 771static void raid0_quiesce(struct mddev *mddev, int quiesce)
772{ 772{
773} 773}
774 774
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index fb56ef79a1c3..9428dfa7e9a0 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -3273,21 +3273,14 @@ static int raid1_reshape(struct mddev *mddev)
3273 return 0; 3273 return 0;
3274} 3274}
3275 3275
3276static void raid1_quiesce(struct mddev *mddev, int state) 3276static void raid1_quiesce(struct mddev *mddev, int quiesce)
3277{ 3277{
3278 struct r1conf *conf = mddev->private; 3278 struct r1conf *conf = mddev->private;
3279 3279
3280 switch(state) { 3280 if (quiesce)
3281 case 2: /* wake for suspend */
3282 wake_up(&conf->wait_barrier);
3283 break;
3284 case 1:
3285 freeze_array(conf, 0); 3281 freeze_array(conf, 0);
3286 break; 3282 else
3287 case 0:
3288 unfreeze_array(conf); 3283 unfreeze_array(conf);
3289 break;
3290 }
3291} 3284}
3292 3285
3293static void *raid1_takeover(struct mddev *mddev) 3286static void *raid1_takeover(struct mddev *mddev)
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index b0de5b5ee689..615f677ceb1a 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -3828,18 +3828,14 @@ static void raid10_free(struct mddev *mddev, void *priv)
3828 kfree(conf); 3828 kfree(conf);
3829} 3829}
3830 3830
3831static void raid10_quiesce(struct mddev *mddev, int state) 3831static void raid10_quiesce(struct mddev *mddev, int quiesce)
3832{ 3832{
3833 struct r10conf *conf = mddev->private; 3833 struct r10conf *conf = mddev->private;
3834 3834
3835 switch(state) { 3835 if (quiesce)
3836 case 1:
3837 raise_barrier(conf, 0); 3836 raise_barrier(conf, 0);
3838 break; 3837 else
3839 case 0:
3840 lower_barrier(conf); 3838 lower_barrier(conf);
3841 break;
3842 }
3843} 3839}
3844 3840
3845static int raid10_resize(struct mddev *mddev, sector_t sectors) 3841static int raid10_resize(struct mddev *mddev, sector_t sectors)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 59af7cf35092..037ed274807f 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -1589,21 +1589,21 @@ void r5l_wake_reclaim(struct r5l_log *log, sector_t space)
1589 md_wakeup_thread(log->reclaim_thread); 1589 md_wakeup_thread(log->reclaim_thread);
1590} 1590}
1591 1591
1592void r5l_quiesce(struct r5l_log *log, int state) 1592void r5l_quiesce(struct r5l_log *log, int quiesce)
1593{ 1593{
1594 struct mddev *mddev; 1594 struct mddev *mddev;
1595 if (!log || state == 2) 1595 if (!log)
1596 return; 1596 return;
1597 if (state == 0) 1597
1598 kthread_unpark(log->reclaim_thread->tsk); 1598 if (quiesce) {
1599 else if (state == 1) {
1600 /* make sure r5l_write_super_and_discard_space exits */ 1599 /* make sure r5l_write_super_and_discard_space exits */
1601 mddev = log->rdev->mddev; 1600 mddev = log->rdev->mddev;
1602 wake_up(&mddev->sb_wait); 1601 wake_up(&mddev->sb_wait);
1603 kthread_park(log->reclaim_thread->tsk); 1602 kthread_park(log->reclaim_thread->tsk);
1604 r5l_wake_reclaim(log, MaxSector); 1603 r5l_wake_reclaim(log, MaxSector);
1605 r5l_do_reclaim(log); 1604 r5l_do_reclaim(log);
1606 } 1605 } else
1606 kthread_unpark(log->reclaim_thread->tsk);
1607} 1607}
1608 1608
1609bool r5l_log_disk_error(struct r5conf *conf) 1609bool r5l_log_disk_error(struct r5conf *conf)
diff --git a/drivers/md/raid5-log.h b/drivers/md/raid5-log.h
index 328d67aedda4..c3596a27a5a8 100644
--- a/drivers/md/raid5-log.h
+++ b/drivers/md/raid5-log.h
@@ -8,7 +8,7 @@ extern void r5l_write_stripe_run(struct r5l_log *log);
8extern void r5l_flush_stripe_to_raid(struct r5l_log *log); 8extern void r5l_flush_stripe_to_raid(struct r5l_log *log);
9extern void r5l_stripe_write_finished(struct stripe_head *sh); 9extern void r5l_stripe_write_finished(struct stripe_head *sh);
10extern int r5l_handle_flush_request(struct r5l_log *log, struct bio *bio); 10extern int r5l_handle_flush_request(struct r5l_log *log, struct bio *bio);
11extern void r5l_quiesce(struct r5l_log *log, int state); 11extern void r5l_quiesce(struct r5l_log *log, int quiesce);
12extern bool r5l_log_disk_error(struct r5conf *conf); 12extern bool r5l_log_disk_error(struct r5conf *conf);
13extern bool r5c_is_writeback(struct r5l_log *log); 13extern bool r5c_is_writeback(struct r5l_log *log);
14extern int 14extern int
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 354a969f50a6..17ffa1e44c84 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -8008,16 +8008,12 @@ static void raid5_finish_reshape(struct mddev *mddev)
8008 } 8008 }
8009} 8009}
8010 8010
8011static void raid5_quiesce(struct mddev *mddev, int state) 8011static void raid5_quiesce(struct mddev *mddev, int quiesce)
8012{ 8012{
8013 struct r5conf *conf = mddev->private; 8013 struct r5conf *conf = mddev->private;
8014 8014
8015 switch(state) { 8015 if (quiesce) {
8016 case 2: /* resume for a suspend */ 8016 /* stop all writes */
8017 wake_up(&conf->wait_for_overlap);
8018 break;
8019
8020 case 1: /* stop all writes */
8021 lock_all_device_hash_locks_irq(conf); 8017 lock_all_device_hash_locks_irq(conf);
8022 /* '2' tells resync/reshape to pause so that all 8018 /* '2' tells resync/reshape to pause so that all
8023 * active stripes can drain 8019 * active stripes can drain
@@ -8033,17 +8029,15 @@ static void raid5_quiesce(struct mddev *mddev, int state)
8033 unlock_all_device_hash_locks_irq(conf); 8029 unlock_all_device_hash_locks_irq(conf);
8034 /* allow reshape to continue */ 8030 /* allow reshape to continue */
8035 wake_up(&conf->wait_for_overlap); 8031 wake_up(&conf->wait_for_overlap);
8036 break; 8032 } else {
8037 8033 /* re-enable writes */
8038 case 0: /* re-enable writes */
8039 lock_all_device_hash_locks_irq(conf); 8034 lock_all_device_hash_locks_irq(conf);
8040 conf->quiesce = 0; 8035 conf->quiesce = 0;
8041 wake_up(&conf->wait_for_quiescent); 8036 wake_up(&conf->wait_for_quiescent);
8042 wake_up(&conf->wait_for_overlap); 8037 wake_up(&conf->wait_for_overlap);
8043 unlock_all_device_hash_locks_irq(conf); 8038 unlock_all_device_hash_locks_irq(conf);
8044 break;
8045 } 8039 }
8046 r5l_quiesce(conf->log, state); 8040 r5l_quiesce(conf->log, quiesce);
8047} 8041}
8048 8042
8049static void *raid45_takeover_raid0(struct mddev *mddev, int level) 8043static void *raid45_takeover_raid0(struct mddev *mddev, int level)