summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/compaction.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/mm/compaction.c b/mm/compaction.c
index f74a362d2e28..d0c7c994e11b 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -790,23 +790,32 @@ static struct page *compaction_alloc(struct page *migratepage,
}
/*
- * We cannot control nr_migratepages and nr_freepages fully when migration is
- * running as migrate_pages() has no knowledge of compact_control. When
- * migration is complete, we count the number of pages on the lists by hand.
+ * This is a migrate-callback that "frees" freepages back to the isolated
+ * freelist. All pages on the freelist are from the same zone, so there is no
+ * special handling needed for NUMA.
+ */
+static void compaction_free(struct page *page, unsigned long data)
+{
+ struct compact_control *cc = (struct compact_control *)data;
+
+ list_add(&page->lru, &cc->freepages);
+ cc->nr_freepages++;
+}
+
+/*
+ * We cannot control nr_migratepages fully when migration is running as
+ * migrate_pages() has no knowledge of of compact_control. When migration is
+ * complete, we count the number of pages on the list by hand.
*/
static void update_nr_listpages(struct compact_control *cc)
{
int nr_migratepages = 0;
- int nr_freepages = 0;
struct page *page;
list_for_each_entry(page, &cc->migratepages, lru)
nr_migratepages++;
- list_for_each_entry(page, &cc->freepages, lru)
- nr_freepages++;
cc->nr_migratepages = nr_migratepages;
- cc->nr_freepages = nr_freepages;
}
/* possible outcome of isolate_migratepages */
@@ -1016,8 +1025,8 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
}
nr_migrate = cc->nr_migratepages;
- err = migrate_pages(&cc->migratepages, compaction_alloc, NULL,
- (unsigned long)cc,
+ err = migrate_pages(&cc->migratepages, compaction_alloc,
+ compaction_free, (unsigned long)cc,
cc->sync ? MIGRATE_SYNC_LIGHT : MIGRATE_ASYNC,
MR_COMPACTION);
update_nr_listpages(cc);