@@ -40,8 +40,8 @@ extern int migrate_page(struct address_space *mapping,
enum migrate_mode mode);
extern int migrate_pages(struct list_head *l, new_page_t new, free_page_t free,
struct alloc_control *ac, enum migrate_mode mode, int reason);
-extern struct page *new_page_nodemask(struct page *page,
- struct alloc_control *ac);
+extern struct page *alloc_migration_target(struct page *page,
+ struct alloc_control *ac);
extern int isolate_movable_page(struct page *page, isolate_mode_t mode);
extern void putback_movable_page(struct page *page);
@@ -60,7 +60,7 @@ static inline int migrate_pages(struct list_head *l, new_page_t new,
free_page_t free, struct alloc_control *ac,
enum migrate_mode mode, int reason)
{ return -ENOSYS; }
-static inline struct page *new_page_nodemask(struct page *page,
+static inline struct page *alloc_migration_target(struct page *page,
struct alloc_control *ac)
{ return NULL; }
static inline int isolate_movable_page(struct page *page, isolate_mode_t mode)
@@ -1626,9 +1626,10 @@ static struct page *new_page(struct page *p, struct alloc_control *__ac)
struct alloc_control ac = {
.nid = page_to_nid(p),
.nmask = &node_states[N_MEMORY],
+ .gfp_mask = GFP_USER | __GFP_MOVABLE | __GFP_RETRY_MAYFAIL,
};
- return new_page_nodemask(p, &ac);
+ return alloc_migration_target(p, &ac);
}
/*
@@ -1249,7 +1249,8 @@ static struct page *new_node_page(struct page *page, struct alloc_control *__ac)
ac.nid = nid;
ac.nmask = &nmask;
- return new_page_nodemask(page, &ac);
+ ac.gfp_mask = GFP_USER | __GFP_MOVABLE | __GFP_RETRY_MAYFAIL;
+ return alloc_migration_target(page, &ac);
}
static int
@@ -1519,31 +1519,35 @@ int migrate_pages(struct list_head *from, new_page_t get_new_page,
return rc;
}
-struct page *new_page_nodemask(struct page *page, struct alloc_control *ac)
+struct page *alloc_migration_target(struct page *page, struct alloc_control *ac)
{
- gfp_t gfp_mask = GFP_USER | __GFP_MOVABLE | __GFP_RETRY_MAYFAIL;
unsigned int order = 0;
struct page *new_page = NULL;
+ int zidx;
+ /* hugetlb has it's own gfp handling logic */
if (PageHuge(page)) {
struct hstate *h = page_hstate(page);
- struct alloc_control __ac = {
- .nid = ac->nid,
- .nmask = ac->nmask,
- };
- return alloc_huge_page_nodemask(h, &__ac);
+ return alloc_huge_page_nodemask(h, ac);
}
+ ac->__gfp_mask = ac->gfp_mask;
if (PageTransHuge(page)) {
- gfp_mask |= GFP_TRANSHUGE;
+ ac->__gfp_mask |= GFP_TRANSHUGE;
order = HPAGE_PMD_ORDER;
}
+ zidx = zone_idx(page_zone(page));
+ if (is_highmem_idx(zidx) || zidx == ZONE_MOVABLE)
+ ac->__gfp_mask |= __GFP_HIGHMEM;
- if (PageHighMem(page) || (zone_idx(page_zone(page)) == ZONE_MOVABLE))
- gfp_mask |= __GFP_HIGHMEM;
+ if (ac->thisnode)
+ ac->__gfp_mask |= __GFP_THISNODE;
+ if (ac->skip_cma)
+ ac->__gfp_mask &= ~__GFP_MOVABLE;
- new_page = __alloc_pages_nodemask(gfp_mask, order, ac->nid, ac->nmask);
+ new_page = __alloc_pages_nodemask(ac->__gfp_mask, order,
+ ac->nid, ac->nmask);
if (new_page && PageTransHuge(new_page))
prep_transhuge_page(new_page);
@@ -303,7 +303,8 @@ struct page *alloc_migrate_target(struct page *page, struct alloc_control *__ac)
struct alloc_control ac = {
.nid = page_to_nid(page),
.nmask = &node_states[N_MEMORY],
+ .gfp_mask = GFP_USER | __GFP_MOVABLE | __GFP_RETRY_MAYFAIL,
};
- return new_page_nodemask(page, &ac);
+ return alloc_migration_target(page, &ac);
}