Commit 2d35e42d authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] md 19 of 22 - Improve serialisation of md syncing

If two md arrays which share real devices (i.e they each own a partition
on some device) need to sync/reconstruct at the same time, it is much
more efficient to have one wait while the other completes.

The current code uses interruptible_sleep_on which isn't SMP safe (without the BKL).
This patch re-does this code to make it more secure.  Even it two start simultaneously,
one will reliably get priority, and the other wont wait for ever.
parent 7145dd24
...@@ -3160,7 +3160,7 @@ int md_do_sync(mddev_t *mddev, mdp_disk_t *spare) ...@@ -3160,7 +3160,7 @@ int md_do_sync(mddev_t *mddev, mdp_disk_t *spare)
{ {
mddev_t *mddev2; mddev_t *mddev2;
unsigned int max_sectors, currspeed = 0, unsigned int max_sectors, currspeed = 0,
j, window, err, serialize; j, window, err;
unsigned long mark[SYNC_MARKS]; unsigned long mark[SYNC_MARKS];
unsigned long mark_cnt[SYNC_MARKS]; unsigned long mark_cnt[SYNC_MARKS];
int last_mark,m; int last_mark,m;
...@@ -3168,30 +3168,36 @@ int md_do_sync(mddev_t *mddev, mdp_disk_t *spare) ...@@ -3168,30 +3168,36 @@ int md_do_sync(mddev_t *mddev, mdp_disk_t *spare)
unsigned long last_check; unsigned long last_check;
recheck: /* we overload curr_resync somewhat here.
serialize = 0; * 0 == not engaged in resync at all
* 2 == checking that there is no conflict with another sync
* 1 == like 2, but have yielded to allow conflicting resync to
* commense
* other == active in resync - this many blocks
*/
do {
mddev->curr_resync = 2;
ITERATE_MDDEV(mddev2,tmp) { ITERATE_MDDEV(mddev2,tmp) {
if (mddev2 == mddev) if (mddev2 == mddev)
continue; continue;
if (mddev2->curr_resync && match_mddev_units(mddev,mddev2)) { if (mddev2->curr_resync &&
match_mddev_units(mddev,mddev2)) {
printk(KERN_INFO "md: delaying resync of md%d until md%d " printk(KERN_INFO "md: delaying resync of md%d until md%d "
"has finished resync (they share one or more physical units)\n", "has finished resync (they share one or more physical units)\n",
mdidx(mddev), mdidx(mddev2)); mdidx(mddev), mdidx(mddev2));
serialize = 1; if (mddev < mddev2) /* arbitrarily yield */
break; mddev->curr_resync = 1;
} if (wait_event_interruptible(resync_wait,
} mddev2->curr_resync < 2)) {
if (serialize) {
interruptible_sleep_on(&resync_wait);
if (signal_pending(current)) {
flush_curr_signals(); flush_curr_signals();
err = -EINTR; err = -EINTR;
goto out; goto out;
} }
goto recheck;
} }
}
} while (mddev->curr_resync < 2);
mddev->curr_resync = 1;
max_sectors = mddev->sb->size << 1; max_sectors = mddev->sb->size << 1;
printk(KERN_INFO "md: syncing RAID array md%d\n", mdidx(mddev)); printk(KERN_INFO "md: syncing RAID array md%d\n", mdidx(mddev));
...@@ -3229,7 +3235,7 @@ int md_do_sync(mddev_t *mddev, mdp_disk_t *spare) ...@@ -3229,7 +3235,7 @@ int md_do_sync(mddev_t *mddev, mdp_disk_t *spare)
} }
atomic_add(sectors, &mddev->recovery_active); atomic_add(sectors, &mddev->recovery_active);
j += sectors; j += sectors;
mddev->curr_resync = j; if (j>1) mddev->curr_resync = j;
if (last_check + window > j) if (last_check + window > j)
continue; continue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment