1 From mgorman@suse.de Mon Aug 1 11:41:52 2011
2 From: Mel Gorman <mgorman@suse.de>
3 Date: Tue, 19 Jul 2011 10:15:49 +0100
4 Subject: mm: compaction: ensure that the compaction free scanner does not move to the next zone
6 Cc: Andrea Arcangeli <aarcange@redhat.com>, Andrew Morton <akpm@linux-foundation.org>, Thomas Sattler <tsattler@gmx.de>, Mel Gorman <mgorman@suse.de>
7 Message-ID: <1311066951-25546-2-git-send-email-mgorman@suse.de>
9 From: Mel Gorman <mgorman@suse.de>
11 commit: 7454f4ba40b419eb999a3c61a99da662bf1a2bb8 upstream
13 Compaction works with two scanners, a migration and a free scanner. When
14 the scanners crossover, migration within the zone is complete. The
15 location of the scanner is recorded on each cycle to avoid excesive
18 When a zone is small and mostly reserved, it's very easy for the migration
19 scanner to be close to the end of the zone. Then the following situation
22 o migration scanner isolates some pages near the end of the zone
23 o free scanner starts at the end of the zone but finds that the
24 migration scanner is already there
25 o free scanner gets reinitialised for the next cycle as
26 cc->migrate_pfn + pageblock_nr_pages
27 moving the free scanner into the next zone
28 o migration scanner moves into the next zone
30 When this happens, NR_ISOLATED accounting goes haywire because some of the
31 accounting happens against the wrong zone. One zones counter remains
32 positive while the other goes negative even though the overall global
33 count is accurate. This was reported on X86-32 with !SMP because !SMP
34 allows the negative counters to be visible. The fact that it is the bug
35 should theoritically be possible there.
37 Signed-off-by: Mel Gorman <mgorman@suse.de>
38 Reviewed-by: Minchan Kim <minchan.kim@gmail.com>
39 Reviewed-by: Michal Hocko <mhocko@suse.cz>
40 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
41 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
42 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
44 mm/compaction.c | 13 ++++++++++++-
45 1 file changed, 12 insertions(+), 1 deletion(-)
49 @@ -144,9 +144,20 @@ static void isolate_freepages(struct zon
50 int nr_freepages = cc->nr_freepages;
51 struct list_head *freelist = &cc->freepages;
54 + * Initialise the free scanner. The starting point is where we last
55 + * scanned from (or the end of the zone if starting). The low point
56 + * is the end of the pageblock the migration scanner is using.
59 low_pfn = cc->migrate_pfn + pageblock_nr_pages;
63 + * Take care that if the migration scanner is at the end of the zone
64 + * that the free scanner does not accidentally move to the next zone
65 + * in the next isolation cycle.
67 + high_pfn = min(low_pfn, pfn);
70 * Isolate free pages until enough are available to migrate the