diff options
author | Vlastimil Babka <vbabka@suse.cz> | 2014-06-04 19:08:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-04 19:54:07 -0400 |
commit | f8c9301fa5a2a8b873c67f2a3d8230d5c13f61b7 (patch) | |
tree | ad788af84a77821f70e77772d7f63eb1dcf00e3d /mm/compaction.c | |
parent | aeef4b83806f49a0c454b7d4578671b71045bee2 (diff) |
mm/compaction: do not count migratepages when unnecessary
During compaction, update_nr_listpages() has been used to count remaining
non-migrated and free pages after a call to migrage_pages(). The
freepages counting has become unneccessary, and it turns out that
migratepages counting is also unnecessary in most cases.
The only situation when it's needed to count cc->migratepages is when
migrate_pages() returns with a negative error code. Otherwise, the
non-negative return value is the number of pages that were not migrated,
which is exactly the count of remaining pages in the cc->migratepages
list.
Furthermore, any non-zero count is only interesting for the tracepoint of
mm_compaction_migratepages events, because after that all remaining
unmigrated pages are put back and their count is set to 0.
This patch therefore removes update_nr_listpages() completely, and changes
the tracepoint definition so that the manual counting is done only when
the tracepoint is enabled, and only when migrate_pages() returns a
negative error code.
Furthermore, migrate_pages() and the tracepoints won't be called when
there's nothing to migrate. This potentially avoids some wasted cycles
and reduces the volume of uninteresting mm_compaction_migratepages events
where "nr_migrated=0 nr_failed=0". In the stress-highalloc mmtest, this
was about 75% of the events. The mm_compaction_isolate_migratepages event
is better for determining that nothing was isolated for migration, and
this one was just duplicating the info.
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Reviewed-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Rik van Riel <riel@redhat.com>
Acked-by: David Rientjes <rientjes@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/compaction.c')
-rw-r--r-- | mm/compaction.c | 31 |
1 files changed, 7 insertions, 24 deletions
diff --git a/mm/compaction.c b/mm/compaction.c index 56331f5124ba..3c60e3d5237e 100644 --- a/mm/compaction.c +++ b/mm/compaction.c | |||
@@ -822,22 +822,6 @@ static void compaction_free(struct page *page, unsigned long data) | |||
822 | cc->nr_freepages++; | 822 | cc->nr_freepages++; |
823 | } | 823 | } |
824 | 824 | ||
825 | /* | ||
826 | * We cannot control nr_migratepages fully when migration is running as | ||
827 | * migrate_pages() has no knowledge of of compact_control. When migration is | ||
828 | * complete, we count the number of pages on the list by hand. | ||
829 | */ | ||
830 | static void update_nr_listpages(struct compact_control *cc) | ||
831 | { | ||
832 | int nr_migratepages = 0; | ||
833 | struct page *page; | ||
834 | |||
835 | list_for_each_entry(page, &cc->migratepages, lru) | ||
836 | nr_migratepages++; | ||
837 | |||
838 | cc->nr_migratepages = nr_migratepages; | ||
839 | } | ||
840 | |||
841 | /* possible outcome of isolate_migratepages */ | 825 | /* possible outcome of isolate_migratepages */ |
842 | typedef enum { | 826 | typedef enum { |
843 | ISOLATE_ABORT, /* Abort compaction now */ | 827 | ISOLATE_ABORT, /* Abort compaction now */ |
@@ -1032,7 +1016,6 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) | |||
1032 | migrate_prep_local(); | 1016 | migrate_prep_local(); |
1033 | 1017 | ||
1034 | while ((ret = compact_finished(zone, cc)) == COMPACT_CONTINUE) { | 1018 | while ((ret = compact_finished(zone, cc)) == COMPACT_CONTINUE) { |
1035 | unsigned long nr_migrate, nr_remaining; | ||
1036 | int err; | 1019 | int err; |
1037 | 1020 | ||
1038 | switch (isolate_migratepages(zone, cc)) { | 1021 | switch (isolate_migratepages(zone, cc)) { |
@@ -1047,20 +1030,20 @@ static int compact_zone(struct zone *zone, struct compact_control *cc) | |||
1047 | ; | 1030 | ; |
1048 | } | 1031 | } |
1049 | 1032 | ||
1050 | nr_migrate = cc->nr_migratepages; | 1033 | if (!cc->nr_migratepages) |
1034 | continue; | ||
1035 | |||
1051 | err = migrate_pages(&cc->migratepages, compaction_alloc, | 1036 | err = migrate_pages(&cc->migratepages, compaction_alloc, |
1052 | compaction_free, (unsigned long)cc, cc->mode, | 1037 | compaction_free, (unsigned long)cc, cc->mode, |
1053 | MR_COMPACTION); | 1038 | MR_COMPACTION); |
1054 | update_nr_listpages(cc); | ||
1055 | nr_remaining = cc->nr_migratepages; | ||
1056 | 1039 | ||
1057 | trace_mm_compaction_migratepages(nr_migrate - nr_remaining, | 1040 | trace_mm_compaction_migratepages(cc->nr_migratepages, err, |
1058 | nr_remaining); | 1041 | &cc->migratepages); |
1059 | 1042 | ||
1060 | /* Release isolated pages not migrated */ | 1043 | /* All pages were either migrated or will be released */ |
1044 | cc->nr_migratepages = 0; | ||
1061 | if (err) { | 1045 | if (err) { |
1062 | putback_movable_pages(&cc->migratepages); | 1046 | putback_movable_pages(&cc->migratepages); |
1063 | cc->nr_migratepages = 0; | ||
1064 | /* | 1047 | /* |
1065 | * migrate_pages() may return -ENOMEM when scanners meet | 1048 | * migrate_pages() may return -ENOMEM when scanners meet |
1066 | * and we want compact_finished() to detect it | 1049 | * and we want compact_finished() to detect it |