Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 332440
b: refs/heads/master
c: c89511a
h: refs/heads/master
v: v3
  • Loading branch information
Mel Gorman authored and Linus Torvalds committed Oct 9, 2012
1 parent 2625201 commit de7720a
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bb13ffeb9f6bfeb301443994dfbf29f91117dfb3
refs/heads/master: c89511ab2f8fe2b47585e60da8af7fd213ec877e
4 changes: 4 additions & 0 deletions trunk/include/linux/mmzone.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,10 @@ struct zone {
int all_unreclaimable; /* All pages pinned */
#if defined CONFIG_COMPACTION || defined CONFIG_CMA
unsigned long compact_blockskip_expire;

/* pfns where compaction scanners should start */
unsigned long compact_cached_free_pfn;
unsigned long compact_cached_migrate_pfn;
#endif
#ifdef CONFIG_MEMORY_HOTPLUG
/* see spanned/present_pages for more description */
Expand Down
58 changes: 48 additions & 10 deletions trunk/mm/compaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ static void reset_isolation_suitable(struct zone *zone)
*/
if (time_before(jiffies, zone->compact_blockskip_expire))
return;

zone->compact_cached_migrate_pfn = start_pfn;
zone->compact_cached_free_pfn = end_pfn;
zone->compact_blockskip_expire = jiffies + (HZ * 5);

/* Walk the zone and mark every pageblock as suitable for isolation */
Expand All @@ -103,13 +106,29 @@ static void reset_isolation_suitable(struct zone *zone)
* If no pages were isolated then mark this pageblock to be skipped in the
* future. The information is later cleared by reset_isolation_suitable().
*/
static void update_pageblock_skip(struct page *page, unsigned long nr_isolated)
static void update_pageblock_skip(struct compact_control *cc,
struct page *page, unsigned long nr_isolated,
bool migrate_scanner)
{
struct zone *zone = cc->zone;
if (!page)
return;

if (!nr_isolated)
if (!nr_isolated) {
unsigned long pfn = page_to_pfn(page);
set_pageblock_skip(page);

/* Update where compaction should restart */
if (migrate_scanner) {
if (!cc->finished_update_migrate &&
pfn > zone->compact_cached_migrate_pfn)
zone->compact_cached_migrate_pfn = pfn;
} else {
if (!cc->finished_update_free &&
pfn < zone->compact_cached_free_pfn)
zone->compact_cached_free_pfn = pfn;
}
}
}
#else
static inline bool isolation_suitable(struct compact_control *cc,
Expand All @@ -118,7 +137,9 @@ static inline bool isolation_suitable(struct compact_control *cc,
return true;
}

static void update_pageblock_skip(struct page *page, unsigned long nr_isolated)
static void update_pageblock_skip(struct compact_control *cc,
struct page *page, unsigned long nr_isolated,
bool migrate_scanner)
{
}
#endif /* CONFIG_COMPACTION */
Expand Down Expand Up @@ -327,7 +348,7 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,

/* Update the pageblock-skip if the whole pageblock was scanned */
if (blockpfn == end_pfn)
update_pageblock_skip(valid_page, total_isolated);
update_pageblock_skip(cc, valid_page, total_isolated, false);

return total_isolated;
}
Expand Down Expand Up @@ -533,6 +554,7 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
*/
if (!cc->sync && last_pageblock_nr != pageblock_nr &&
!migrate_async_suitable(get_pageblock_migratetype(page))) {
cc->finished_update_migrate = true;
goto next_pageblock;
}

Expand Down Expand Up @@ -583,6 +605,7 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
VM_BUG_ON(PageTransCompound(page));

/* Successfully isolated */
cc->finished_update_migrate = true;
del_page_from_lru_list(page, lruvec, page_lru(page));
list_add(&page->lru, migratelist);
cc->nr_migratepages++;
Expand All @@ -609,7 +632,7 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc,

/* Update the pageblock-skip if the whole pageblock was scanned */
if (low_pfn == end_pfn)
update_pageblock_skip(valid_page, nr_isolated);
update_pageblock_skip(cc, valid_page, nr_isolated, true);

trace_mm_compaction_isolate_migratepages(nr_scanned, nr_isolated);

Expand Down Expand Up @@ -690,8 +713,10 @@ static void isolate_freepages(struct zone *zone,
* looking for free pages, the search will restart here as
* page migration may have returned some pages to the allocator
*/
if (isolated)
if (isolated) {
cc->finished_update_free = true;
high_pfn = max(high_pfn, pfn);
}
}

/* split_free_page does not map the pages */
Expand Down Expand Up @@ -888,6 +913,8 @@ unsigned long compaction_suitable(struct zone *zone, int order)
static int compact_zone(struct zone *zone, struct compact_control *cc)
{
int ret;
unsigned long start_pfn = zone->zone_start_pfn;
unsigned long end_pfn = zone->zone_start_pfn + zone->spanned_pages;

ret = compaction_suitable(zone, cc->order);
switch (ret) {
Expand All @@ -900,10 +927,21 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
;
}

/* Setup to move all movable pages to the end of the zone */
cc->migrate_pfn = zone->zone_start_pfn;
cc->free_pfn = cc->migrate_pfn + zone->spanned_pages;
cc->free_pfn &= ~(pageblock_nr_pages-1);
/*
* Setup to move all movable pages to the end of the zone. Used cached
* information on where the scanners should start but check that it
* is initialised by ensuring the values are within zone boundaries.
*/
cc->migrate_pfn = zone->compact_cached_migrate_pfn;
cc->free_pfn = zone->compact_cached_free_pfn;
if (cc->free_pfn < start_pfn || cc->free_pfn > end_pfn) {
cc->free_pfn = end_pfn & ~(pageblock_nr_pages-1);
zone->compact_cached_free_pfn = cc->free_pfn;
}
if (cc->migrate_pfn < start_pfn || cc->migrate_pfn > end_pfn) {
cc->migrate_pfn = start_pfn;
zone->compact_cached_migrate_pfn = cc->migrate_pfn;
}

/* Clear pageblock skip if there are numerous alloc failures */
if (zone->compact_defer_shift == COMPACT_MAX_DEFER_SHIFT)
Expand Down
4 changes: 4 additions & 0 deletions trunk/mm/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ struct compact_control {
unsigned long migrate_pfn; /* isolate_migratepages search base */
bool sync; /* Synchronous migration */
bool ignore_skip_hint; /* Scan blocks even if marked skip */
bool finished_update_free; /* True when the zone cached pfns are
* no longer being updated
*/
bool finished_update_migrate;

int order; /* order a direct compactor needs */
int migratetype; /* MOVABLE, RECLAIMABLE etc */
Expand Down

0 comments on commit de7720a

Please sign in to comment.