aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2007-07-17 07:06:12 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-17 13:23:15 -0400
commit713f6ab18b0e7d39f14401362bfe8015b1aedde1 (patch)
treefc6ef865d09de1ec816ed96860ffc27dd48d837b /drivers/md
parentdf968c4e8d809deb2602fb0e8db758f26a4006b9 (diff)
md: improve the is_mddev_idle test fix
Don't use 'unsigned' variable to track sync vs non-sync IO, as the only thing we want to do with them is a signed comparison, and fix up the comment which had become quite wrong. 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>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/md.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 3d5a6beb333..bae42331182 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -5091,7 +5091,7 @@ static int is_mddev_idle(mddev_t *mddev)
5091 mdk_rdev_t * rdev; 5091 mdk_rdev_t * rdev;
5092 struct list_head *tmp; 5092 struct list_head *tmp;
5093 int idle; 5093 int idle;
5094 unsigned long curr_events; 5094 long curr_events;
5095 5095
5096 idle = 1; 5096 idle = 1;
5097 ITERATE_RDEV(mddev,rdev,tmp) { 5097 ITERATE_RDEV(mddev,rdev,tmp) {
@@ -5099,20 +5099,29 @@ static int is_mddev_idle(mddev_t *mddev)
5099 curr_events = disk_stat_read(disk, sectors[0]) + 5099 curr_events = disk_stat_read(disk, sectors[0]) +
5100 disk_stat_read(disk, sectors[1]) - 5100 disk_stat_read(disk, sectors[1]) -
5101 atomic_read(&disk->sync_io); 5101 atomic_read(&disk->sync_io);
5102 /* The difference between curr_events and last_events 5102 /* sync IO will cause sync_io to increase before the disk_stats
5103 * will be affected by any new non-sync IO (making 5103 * as sync_io is counted when a request starts, and
5104 * curr_events bigger) and any difference in the amount of 5104 * disk_stats is counted when it completes.
5105 * in-flight syncio (making current_events bigger or smaller) 5105 * So resync activity will cause curr_events to be smaller than
5106 * The amount in-flight is currently limited to 5106 * when there was no such activity.
5107 * 32*64K in raid1/10 and 256*PAGE_SIZE in raid5/6 5107 * non-sync IO will cause disk_stat to increase without
5108 * which is at most 4096 sectors. 5108 * increasing sync_io so curr_events will (eventually)
5109 * These numbers are fairly fragile and should be made 5109 * be larger than it was before. Once it becomes
5110 * more robust, probably by enforcing the 5110 * substantially larger, the test below will cause
5111 * 'window size' that md_do_sync sort-of uses. 5111 * the array to appear non-idle, and resync will slow
5112 * down.
5113 * If there is a lot of outstanding resync activity when
5114 * we set last_event to curr_events, then all that activity
5115 * completing might cause the array to appear non-idle
5116 * and resync will be slowed down even though there might
5117 * not have been non-resync activity. This will only
5118 * happen once though. 'last_events' will soon reflect
5119 * the state where there is little or no outstanding
5120 * resync requests, and further resync activity will
5121 * always make curr_events less than last_events.
5112 * 5122 *
5113 * Note: the following is an unsigned comparison.
5114 */ 5123 */
5115 if ((long)curr_events - (long)rdev->last_events > 4096) { 5124 if (curr_events - rdev->last_events > 4096) {
5116 rdev->last_events = curr_events; 5125 rdev->last_events = curr_events;
5117 idle = 0; 5126 idle = 0;
5118 } 5127 }