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>
This commit is contained in:
parent
4f54b0e948
commit
90b08710e4
2 changed files with 39 additions and 4 deletions
|
@ -74,6 +74,8 @@ static DEFINE_SPINLOCK(pers_lock);
|
|||
|
||||
static void md_print_devices(void);
|
||||
|
||||
static DECLARE_WAIT_QUEUE_HEAD(resync_wait);
|
||||
|
||||
#define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); }
|
||||
|
||||
/*
|
||||
|
@ -3012,6 +3014,36 @@ degraded_show(mddev_t *mddev, char *page)
|
|||
}
|
||||
static struct md_sysfs_entry md_degraded = __ATTR_RO(degraded);
|
||||
|
||||
static ssize_t
|
||||
sync_force_parallel_show(mddev_t *mddev, char *page)
|
||||
{
|
||||
return sprintf(page, "%d\n", mddev->parallel_resync);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
sync_force_parallel_store(mddev_t *mddev, const char *buf, size_t len)
|
||||
{
|
||||
long n;
|
||||
|
||||
if (strict_strtol(buf, 10, &n))
|
||||
return -EINVAL;
|
||||
|
||||
if (n != 0 && n != 1)
|
||||
return -EINVAL;
|
||||
|
||||
mddev->parallel_resync = n;
|
||||
|
||||
if (mddev->sync_thread)
|
||||
wake_up(&resync_wait);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* force parallel resync, even with shared block devices */
|
||||
static struct md_sysfs_entry md_sync_force_parallel =
|
||||
__ATTR(sync_force_parallel, S_IRUGO|S_IWUSR,
|
||||
sync_force_parallel_show, sync_force_parallel_store);
|
||||
|
||||
static ssize_t
|
||||
sync_speed_show(mddev_t *mddev, char *page)
|
||||
{
|
||||
|
@ -3187,6 +3219,7 @@ static struct attribute *md_redundancy_attrs[] = {
|
|||
&md_sync_min.attr,
|
||||
&md_sync_max.attr,
|
||||
&md_sync_speed.attr,
|
||||
&md_sync_force_parallel.attr,
|
||||
&md_sync_completed.attr,
|
||||
&md_max_sync.attr,
|
||||
&md_suspend_lo.attr,
|
||||
|
@ -5487,8 +5520,6 @@ void md_allow_write(mddev_t *mddev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(md_allow_write);
|
||||
|
||||
static DECLARE_WAIT_QUEUE_HEAD(resync_wait);
|
||||
|
||||
#define SYNC_MARKS 10
|
||||
#define SYNC_MARK_STEP (3*HZ)
|
||||
void md_do_sync(mddev_t *mddev)
|
||||
|
@ -5552,8 +5583,9 @@ void md_do_sync(mddev_t *mddev)
|
|||
for_each_mddev(mddev2, tmp) {
|
||||
if (mddev2 == mddev)
|
||||
continue;
|
||||
if (mddev2->curr_resync &&
|
||||
match_mddev_units(mddev,mddev2)) {
|
||||
if (!mddev->parallel_resync
|
||||
&& mddev2->curr_resync
|
||||
&& match_mddev_units(mddev, mddev2)) {
|
||||
DEFINE_WAIT(wq);
|
||||
if (mddev < mddev2 && mddev->curr_resync == 2) {
|
||||
/* arbitrarily yield */
|
||||
|
|
|
@ -180,6 +180,9 @@ struct mddev_s
|
|||
int sync_speed_min;
|
||||
int sync_speed_max;
|
||||
|
||||
/* resync even though the same disks are shared among md-devices */
|
||||
int parallel_resync;
|
||||
|
||||
int ok_start_degraded;
|
||||
/* recovery/resync flags
|
||||
* NEEDED: we might need to start a resync/recover
|
||||
|
|
Loading…
Reference in a new issue