diff options
author | Bernd Schubert <bs@q-leap.de> | 2008-05-23 16:04:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-24 12:56:10 -0400 |
commit | 90b08710e41a07d4ff0fb8940dcce3a552991a56 (patch) | |
tree | 8e45d1c6d9b4020099fd36781065bf8b8fdb76e4 | |
parent | 4f54b0e9485644a3c5fca2ae43bcbe7376825747 (diff) |
md: allow parallel resync of md-devices.
In some configurations, a raid6 resync can be limited by CPU speed
(Calculating P and Q and moving data) rather than by device speed. In
these cases there is nothing to be gained byt serialising resync of arrays
that share a device, and doing the resync in parallel can provide benefit.
So add a sysfs tunable to flag an array as being allowed to resync in
parallel with other arrays that use (a different part of) the same device.
Signed-off-by: Bernd Schubert <bs@q-leap.de>
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/md/md.c | 40 | ||||
-rw-r--r-- | include/linux/raid/md_k.h | 3 |
2 files changed, 39 insertions, 4 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index e57213dacd25..295be1a68806 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -74,6 +74,8 @@ static DEFINE_SPINLOCK(pers_lock); | |||
74 | 74 | ||
75 | static void md_print_devices(void); | 75 | static void md_print_devices(void); |
76 | 76 | ||
77 | static DECLARE_WAIT_QUEUE_HEAD(resync_wait); | ||
78 | |||
77 | #define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); } | 79 | #define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); } |
78 | 80 | ||
79 | /* | 81 | /* |
@@ -3013,6 +3015,36 @@ degraded_show(mddev_t *mddev, char *page) | |||
3013 | static struct md_sysfs_entry md_degraded = __ATTR_RO(degraded); | 3015 | static struct md_sysfs_entry md_degraded = __ATTR_RO(degraded); |
3014 | 3016 | ||
3015 | static ssize_t | 3017 | static ssize_t |
3018 | sync_force_parallel_show(mddev_t *mddev, char *page) | ||
3019 | { | ||
3020 | return sprintf(page, "%d\n", mddev->parallel_resync); | ||
3021 | } | ||
3022 | |||
3023 | static ssize_t | ||
3024 | sync_force_parallel_store(mddev_t *mddev, const char *buf, size_t len) | ||
3025 | { | ||
3026 | long n; | ||
3027 | |||
3028 | if (strict_strtol(buf, 10, &n)) | ||
3029 | return -EINVAL; | ||
3030 | |||
3031 | if (n != 0 && n != 1) | ||
3032 | return -EINVAL; | ||
3033 | |||
3034 | mddev->parallel_resync = n; | ||
3035 | |||
3036 | if (mddev->sync_thread) | ||
3037 | wake_up(&resync_wait); | ||
3038 | |||
3039 | return len; | ||
3040 | } | ||
3041 | |||
3042 | /* force parallel resync, even with shared block devices */ | ||
3043 | static struct md_sysfs_entry md_sync_force_parallel = | ||
3044 | __ATTR(sync_force_parallel, S_IRUGO|S_IWUSR, | ||
3045 | sync_force_parallel_show, sync_force_parallel_store); | ||
3046 | |||
3047 | static ssize_t | ||
3016 | sync_speed_show(mddev_t *mddev, char *page) | 3048 | sync_speed_show(mddev_t *mddev, char *page) |
3017 | { | 3049 | { |
3018 | unsigned long resync, dt, db; | 3050 | unsigned long resync, dt, db; |
@@ -3187,6 +3219,7 @@ static struct attribute *md_redundancy_attrs[] = { | |||
3187 | &md_sync_min.attr, | 3219 | &md_sync_min.attr, |
3188 | &md_sync_max.attr, | 3220 | &md_sync_max.attr, |
3189 | &md_sync_speed.attr, | 3221 | &md_sync_speed.attr, |
3222 | &md_sync_force_parallel.attr, | ||
3190 | &md_sync_completed.attr, | 3223 | &md_sync_completed.attr, |
3191 | &md_max_sync.attr, | 3224 | &md_max_sync.attr, |
3192 | &md_suspend_lo.attr, | 3225 | &md_suspend_lo.attr, |
@@ -5487,8 +5520,6 @@ void md_allow_write(mddev_t *mddev) | |||
5487 | } | 5520 | } |
5488 | EXPORT_SYMBOL_GPL(md_allow_write); | 5521 | EXPORT_SYMBOL_GPL(md_allow_write); |
5489 | 5522 | ||
5490 | static DECLARE_WAIT_QUEUE_HEAD(resync_wait); | ||
5491 | |||
5492 | #define SYNC_MARKS 10 | 5523 | #define SYNC_MARKS 10 |
5493 | #define SYNC_MARK_STEP (3*HZ) | 5524 | #define SYNC_MARK_STEP (3*HZ) |
5494 | void md_do_sync(mddev_t *mddev) | 5525 | void md_do_sync(mddev_t *mddev) |
@@ -5552,8 +5583,9 @@ void md_do_sync(mddev_t *mddev) | |||
5552 | for_each_mddev(mddev2, tmp) { | 5583 | for_each_mddev(mddev2, tmp) { |
5553 | if (mddev2 == mddev) | 5584 | if (mddev2 == mddev) |
5554 | continue; | 5585 | continue; |
5555 | if (mddev2->curr_resync && | 5586 | if (!mddev->parallel_resync |
5556 | match_mddev_units(mddev,mddev2)) { | 5587 | && mddev2->curr_resync |
5588 | && match_mddev_units(mddev, mddev2)) { | ||
5557 | DEFINE_WAIT(wq); | 5589 | DEFINE_WAIT(wq); |
5558 | if (mddev < mddev2 && mddev->curr_resync == 2) { | 5590 | if (mddev < mddev2 && mddev->curr_resync == 2) { |
5559 | /* arbitrarily yield */ | 5591 | /* arbitrarily yield */ |
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 812ffa590cff..a6d7ab688ede 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h | |||
@@ -180,6 +180,9 @@ struct mddev_s | |||
180 | int sync_speed_min; | 180 | int sync_speed_min; |
181 | int sync_speed_max; | 181 | int sync_speed_max; |
182 | 182 | ||
183 | /* resync even though the same disks are shared among md-devices */ | ||
184 | int parallel_resync; | ||
185 | |||
183 | int ok_start_degraded; | 186 | int ok_start_degraded; |
184 | /* recovery/resync flags | 187 | /* recovery/resync flags |
185 | * NEEDED: we might need to start a resync/recover | 188 | * NEEDED: we might need to start a resync/recover |