Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 713f6ab1 authored by NeilBrown's avatar NeilBrown Committed by Linus Torvalds
Browse files

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: default avatarNeil Brown <neilb@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent df968c4e
Loading
Loading
Loading
Loading
+22 −13
Original line number Original line Diff line number Diff line
@@ -5091,7 +5091,7 @@ static int is_mddev_idle(mddev_t *mddev)
	mdk_rdev_t * rdev;
	mdk_rdev_t * rdev;
	struct list_head *tmp;
	struct list_head *tmp;
	int idle;
	int idle;
	unsigned long curr_events;
	long curr_events;


	idle = 1;
	idle = 1;
	ITERATE_RDEV(mddev,rdev,tmp) {
	ITERATE_RDEV(mddev,rdev,tmp) {
@@ -5099,20 +5099,29 @@ static int is_mddev_idle(mddev_t *mddev)
		curr_events = disk_stat_read(disk, sectors[0]) + 
		curr_events = disk_stat_read(disk, sectors[0]) + 
				disk_stat_read(disk, sectors[1]) - 
				disk_stat_read(disk, sectors[1]) - 
				atomic_read(&disk->sync_io);
				atomic_read(&disk->sync_io);
		/* The difference between curr_events and last_events
		/* sync IO will cause sync_io to increase before the disk_stats
		 * will be affected by any new non-sync IO (making
		 * as sync_io is counted when a request starts, and
		 * curr_events bigger) and any difference in the amount of
		 * disk_stats is counted when it completes.
		 * in-flight syncio (making current_events bigger or smaller)
		 * So resync activity will cause curr_events to be smaller than
		 * The amount in-flight is currently limited to
		 * when there was no such activity.
		 * 32*64K in raid1/10 and 256*PAGE_SIZE in raid5/6
		 * non-sync IO will cause disk_stat to increase without
		 * which is at most 4096 sectors.
		 * increasing sync_io so curr_events will (eventually)
		 * These numbers are fairly fragile and should be made
		 * be larger than it was before.  Once it becomes
		 * more robust, probably by enforcing the
		 * substantially larger, the test below will cause
		 * 'window size' that md_do_sync sort-of uses.
		 * the array to appear non-idle, and resync will slow
		 * down.
		 * If there is a lot of outstanding resync activity when
		 * we set last_event to curr_events, then all that activity
		 * completing might cause the array to appear non-idle
		 * and resync will be slowed down even though there might
		 * not have been non-resync activity.  This will only
		 * happen once though.  'last_events' will soon reflect
		 * the state where there is little or no outstanding
		 * resync requests, and further resync activity will
		 * always make curr_events less than last_events.
		 *
		 *
		 * Note: the following is an unsigned comparison.
		 */
		 */
		if ((long)curr_events - (long)rdev->last_events > 4096) {
		if (curr_events - rdev->last_events > 4096) {
			rdev->last_events = curr_events;
			rdev->last_events = curr_events;
			idle = 0;
			idle = 0;
		}
		}
+1 −1
Original line number Original line Diff line number Diff line
@@ -51,7 +51,7 @@ struct mdk_rdev_s


	sector_t size;			/* Device size (in blocks) */
	sector_t size;			/* Device size (in blocks) */
	mddev_t *mddev;			/* RAID array if running */
	mddev_t *mddev;			/* RAID array if running */
	unsigned long last_events;	/* IO event timestamp */
	long last_events;		/* IO event timestamp */


	struct block_device *bdev;	/* block device handle */
	struct block_device *bdev;	/* block device handle */