1 From eea1bf384e05b5ab747f8530c4fba9e9e6907fff Mon Sep 17 00:00:00 2001
2 From: NeilBrown <neilb@suse.de>
3 Date: Tue, 31 Mar 2009 14:27:02 +1100
4 Subject: [PATCH] md: Fix is_mddev_idle test (again).
6 There are two problems with is_mddev_idle.
8 1/ sync_io is 'atomic_t' and hence 'int'. curr_events and all the
10 So if sync_io were to wrap on a 64bit host, the value of
11 curr_events would go very negative suddenly, and take a very
12 long time to return to positive.
14 So do all calculations as 'int'. That gives us plenty of precision
17 2/ To initialise rdev->last_events we simply call is_mddev_idle, on
18 the assumption that it will make sure that last_events is in a
19 suitable range. It used to do this, but now it does not.
20 So now we need to be more explicit about initialisation.
22 NOTE: to avoid kabi issues in SLES11, we leave 'last_events' as
23 long and cast it to (int) where used.
25 Signed-off-by: NeilBrown <neilb@suse.de>
27 drivers/md/md.c | 10 +++++-----
28 1 file changed, 5 insertions(+), 5 deletions(-)
32 @@ -5580,11 +5580,11 @@ int unregister_md_personality(struct mdk
36 -static int is_mddev_idle(mddev_t *mddev)
37 +static int is_mddev_idle(mddev_t *mddev, int init)
46 @@ -5615,7 +5615,7 @@ static int is_mddev_idle(mddev_t *mddev)
47 * always make curr_events less than last_events.
50 - if (curr_events - rdev->last_events > 4096) {
51 + if (init || curr_events - (int)rdev->last_events > 64) {
52 rdev->last_events = curr_events;
55 @@ -5859,7 +5859,7 @@ void md_do_sync(mddev_t *mddev)
56 "(but not more than %d KB/sec) for %s.\n",
57 speed_max(mddev), desc);
59 - is_mddev_idle(mddev); /* this also initializes IO event counters */
60 + is_mddev_idle(mddev, 1); /* this initializes IO event counters */
63 for (m = 0; m < SYNC_MARKS; m++) {
64 @@ -5961,7 +5961,7 @@ void md_do_sync(mddev_t *mddev)
66 if (currspeed > speed_min(mddev)) {
67 if ((currspeed > speed_max(mddev)) ||
68 - !is_mddev_idle(mddev)) {
69 + !is_mddev_idle(mddev, 0)) {