Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Bernd Schubert and committed by
Linus Torvalds
90b08710 4f54b0e9

+39 -4
+36 -4
drivers/md/md.c
··· 74 74 75 75 static void md_print_devices(void); 76 76 77 + static DECLARE_WAIT_QUEUE_HEAD(resync_wait); 78 + 77 79 #define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); } 78 80 79 81 /* ··· 3015 3013 static struct md_sysfs_entry md_degraded = __ATTR_RO(degraded); 3016 3014 3017 3015 static ssize_t 3016 + sync_force_parallel_show(mddev_t *mddev, char *page) 3017 + { 3018 + return sprintf(page, "%d\n", mddev->parallel_resync); 3019 + } 3020 + 3021 + static ssize_t 3022 + sync_force_parallel_store(mddev_t *mddev, const char *buf, size_t len) 3023 + { 3024 + long n; 3025 + 3026 + if (strict_strtol(buf, 10, &n)) 3027 + return -EINVAL; 3028 + 3029 + if (n != 0 && n != 1) 3030 + return -EINVAL; 3031 + 3032 + mddev->parallel_resync = n; 3033 + 3034 + if (mddev->sync_thread) 3035 + wake_up(&resync_wait); 3036 + 3037 + return len; 3038 + } 3039 + 3040 + /* force parallel resync, even with shared block devices */ 3041 + static struct md_sysfs_entry md_sync_force_parallel = 3042 + __ATTR(sync_force_parallel, S_IRUGO|S_IWUSR, 3043 + sync_force_parallel_show, sync_force_parallel_store); 3044 + 3045 + static ssize_t 3018 3046 sync_speed_show(mddev_t *mddev, char *page) 3019 3047 { 3020 3048 unsigned long resync, dt, db; ··· 3219 3187 &md_sync_min.attr, 3220 3188 &md_sync_max.attr, 3221 3189 &md_sync_speed.attr, 3190 + &md_sync_force_parallel.attr, 3222 3191 &md_sync_completed.attr, 3223 3192 &md_max_sync.attr, 3224 3193 &md_suspend_lo.attr, ··· 5520 5487 } 5521 5488 EXPORT_SYMBOL_GPL(md_allow_write); 5522 5489 5523 - static DECLARE_WAIT_QUEUE_HEAD(resync_wait); 5524 - 5525 5490 #define SYNC_MARKS 10 5526 5491 #define SYNC_MARK_STEP (3*HZ) 5527 5492 void md_do_sync(mddev_t *mddev) ··· 5583 5552 for_each_mddev(mddev2, tmp) { 5584 5553 if (mddev2 == mddev) 5585 5554 continue; 5586 - if (mddev2->curr_resync && 5587 - match_mddev_units(mddev,mddev2)) { 5555 + if (!mddev->parallel_resync 5556 + && mddev2->curr_resync 5557 + && match_mddev_units(mddev, mddev2)) { 5588 5558 DEFINE_WAIT(wq); 5589 5559 if (mddev < mddev2 && mddev->curr_resync == 2) { 5590 5560 /* arbitrarily yield */
+3
include/linux/raid/md_k.h
··· 180 180 int sync_speed_min; 181 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 186 int ok_start_degraded; 184 187 /* recovery/resync flags 185 188 * NEEDED: we might need to start a resync/recover