History

mm/migrate: introduce a standard migration target allocation function

There are some similar functions for migration target allocation. Since there is no fundamental difference, it's better to keep just one rather than keeping all variants. This patch implements base migration target allocation function. In the following patches, variants will be converted to use this function. Changes should be mechanical, but, unfortunately, there are some differences. First, some callers' nodemask is assgined to NULL since NULL nodemask will be considered as all available nodes, that is, &node_states[N_MEMORY]. Second, for hugetlb page allocation, gfp_mask is redefined as regular hugetlb allocation gfp_mask plus __GFP_THISNODE if user provided gfp_mask has it. This is because future caller of this function requires to set this node constaint. Lastly, if provided nodeid is NUMA_NO_NODE, nodeid is set up to the node where migration source lives. It helps to remove simple wrappers for setting up the nodeid. Note that PageHighmem() call in previous function is changed to open-code "is_highmem_idx()" since it provides more readability. [akpm@linux-foundation.org: tweak patch title, per Vlastimil] [akpm@linux-foundation.org: fix typo in comment]

Joonsoo Kim committed 6 years ago

Commit 19fc7be1 parent 9933a0c7 files · +61 −22Browse files

Unified · Split

7 files
  1. include/linux/hugetlb.h +15 −0
  2. include/linux/migrate.h +5 −4
  3. mm/internal.h +7 −0
  4. mm/memory-failure.c +5 −2
  5. mm/memory_hotplug.c +8 −4
  6. mm/migrate.c +16 −10
  7. mm/page_isolation.c +5 −2
include/linux/hugetlb.h+15−0
@@ -703,6 +703,16 @@ static inline gfp_t htlb_alloc_mask(struct hstate *h) · 702 unmodified lines
703 return GFP_HIGHUSER;703 return GFP_HIGHUSER;
704}704}
705 705
706static inline gfp_t htlb_modify_alloc_mask(struct hstate *h, gfp_t gfp_mask)
707{
708 gfp_t modified_mask = htlb_alloc_mask(h);
709
710 /* Some callers might want to enforce node */
711 modified_mask |= (gfp_mask & __GFP_THISNODE);
712
713 return modified_mask;
714}
715
706static inline spinlock_t *huge_pte_lockptr(struct hstate *h,716static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
707 struct mm_struct *mm, pte_t *pte)717 struct mm_struct *mm, pte_t *pte)
708{718{
@@ -890,6 +900,11 @@ static inline gfp_t htlb_alloc_mask(struct hstate *h) · 181 unmodified lines
890 return 0;900 return 0;
891}901}
892 902
903static inline gfp_t htlb_modify_alloc_mask(struct hstate *h, gfp_t gfp_mask)
904{
905 return 0;
906}
907
893static inline spinlock_t *huge_pte_lockptr(struct hstate *h,908static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
894 struct mm_struct *mm, pte_t *pte)909 struct mm_struct *mm, pte_t *pte)
895{910{
include/linux/migrate.h+5−4
@@ -10,6 +10,8 @@ · 9 unmodified lines
10typedef struct page *new_page_t(struct page *page, unsigned long private);10typedef struct page *new_page_t(struct page *page, unsigned long private);
11typedef void free_page_t(struct page *page, unsigned long private);11typedef void free_page_t(struct page *page, unsigned long private);
12 12
13struct migration_target_control;
14
13/*15/*
14 * Return values from addresss_space_operations.migratepage():16 * Return values from addresss_space_operations.migratepage():
15 * - negative errno on page migration failure;17 * - negative errno on page migration failure;
@@ -39,8 +41,7 @@ extern int migrate_page(struct address_space *mapping, · 23 unmodified lines
39 enum migrate_mode mode);41 enum migrate_mode mode);
40extern int migrate_pages(struct list_head *l, new_page_t new, free_page_t free,42extern int migrate_pages(struct list_head *l, new_page_t new, free_page_t free,
41 unsigned long private, enum migrate_mode mode, int reason);43 unsigned long private, enum migrate_mode mode, int reason);
42extern struct page *new_page_nodemask(struct page *page,44extern struct page *alloc_migration_target(struct page *page, unsigned long private);
43 int preferred_nid, nodemask_t *nodemask);
44extern int isolate_movable_page(struct page *page, isolate_mode_t mode);45extern int isolate_movable_page(struct page *page, isolate_mode_t mode);
45extern void putback_movable_page(struct page *page);46extern void putback_movable_page(struct page *page);
46 47
@@ -59,8 +60,8 @@ static inline int migrate_pages(struct list_head *l, new_page_t new, · 12 unmodified lines
59 free_page_t free, unsigned long private, enum migrate_mode mode,60 free_page_t free, unsigned long private, enum migrate_mode mode,
60 int reason)61 int reason)
61 { return -ENOSYS; }62 { return -ENOSYS; }
62static inline struct page *new_page_nodemask(struct page *page,63static inline struct page *alloc_migration_target(struct page *page,
63 int preferred_nid, nodemask_t *nodemask)64 unsigned long private)
64 { return NULL; }65 { return NULL; }
65static inline int isolate_movable_page(struct page *page, isolate_mode_t mode)66static inline int isolate_movable_page(struct page *page, isolate_mode_t mode)
66 { return -EBUSY; }67 { return -EBUSY; }
mm/internal.h+7−0
@@ -614,4 +614,11 @@ static inline bool is_migrate_highatomic_page(struct page *page) · 613 unmodified lines
614 614
615void setup_zone_pageset(struct zone *zone);615void setup_zone_pageset(struct zone *zone);
616extern struct page *alloc_new_node_page(struct page *page, unsigned long node);616extern struct page *alloc_new_node_page(struct page *page, unsigned long node);
617
618struct migration_target_control {
619 int nid; /* preferred node id */
620 nodemask_t *nmask;
621 gfp_t gfp_mask;
622};
623
617#endif /* __MM_INTERNAL_H */624#endif /* __MM_INTERNAL_H */
mm/memory-failure.c+5−2
@@ -1648,9 +1648,12 @@ EXPORT_SYMBOL(unpoison_memory); · 1647 unmodified lines
1648 1648
1649static struct page *new_page(struct page *p, unsigned long private)1649static struct page *new_page(struct page *p, unsigned long private)
1650{1650{
1651 int nid = page_to_nid(p);1651 struct migration_target_control mtc = {
1652 .nid = page_to_nid(p),
1653 .gfp_mask = GFP_USER | __GFP_MOVABLE | __GFP_RETRY_MAYFAIL,
1654 };
1652 1655
1653 return new_page_nodemask(p, nid, &node_states[N_MEMORY]);1656 return alloc_migration_target(p, (unsigned long)&mtc);
1654}1657}
1655 1658
1656/*1659/*
mm/memory_hotplug.c+8−4
@@ -1276,19 +1276,23 @@ found: · 1275 unmodified lines
1276 1276
1277static struct page *new_node_page(struct page *page, unsigned long private)1277static struct page *new_node_page(struct page *page, unsigned long private)
1278{1278{
1279 int nid = page_to_nid(page);
1280 nodemask_t nmask = node_states[N_MEMORY];1279 nodemask_t nmask = node_states[N_MEMORY];
1280 struct migration_target_control mtc = {
1281 .nid = page_to_nid(page),
1282 .nmask = &nmask,
1283 .gfp_mask = GFP_USER | __GFP_MOVABLE | __GFP_RETRY_MAYFAIL,
1284 };
1281 1285
1282 /*1286 /*
1283 * try to allocate from a different node but reuse this node if there1287 * try to allocate from a different node but reuse this node if there
1284 * are no other online nodes to be used (e.g. we are offlining a part1288 * are no other online nodes to be used (e.g. we are offlining a part
1285 * of the only existing node)1289 * of the only existing node)
1286 */1290 */
1287 node_clear(nid, nmask);1291 node_clear(mtc.nid, nmask);
1288 if (nodes_empty(nmask))1292 if (nodes_empty(nmask))
1289 node_set(nid, nmask);1293 node_set(mtc.nid, nmask);
1290 1294
1291 return new_page_nodemask(page, nid, &nmask);1295 return alloc_migration_target(page, (unsigned long)&mtc);
1292}1296}
1293 1297
1294static int1298static int
mm/migrate.c+16−10
@@ -1538,19 +1538,26 @@ out: · 1537 unmodified lines
1538 return rc;1538 return rc;
1539}1539}
1540 1540
1541struct page *new_page_nodemask(struct page *page,1541struct page *alloc_migration_target(struct page *page, unsigned long private)
1542 int preferred_nid, nodemask_t *nodemask)
1543{1542{
1544 gfp_t gfp_mask = GFP_USER | __GFP_MOVABLE | __GFP_RETRY_MAYFAIL;1543 struct migration_target_control *mtc;
1544 gfp_t gfp_mask;
1545 unsigned int order = 0;1545 unsigned int order = 0;
1546 struct page *new_page = NULL;1546 struct page *new_page = NULL;
1547 int nid;
1548 int zidx;
1549
1550 mtc = (struct migration_target_control *)private;
1551 gfp_mask = mtc->gfp_mask;
1552 nid = mtc->nid;
1553 if (nid == NUMA_NO_NODE)
1554 nid = page_to_nid(page);
1547 1555
1548 if (PageHuge(page)) {1556 if (PageHuge(page)) {
1549 struct hstate *h = page_hstate(compound_head(page));1557 struct hstate *h = page_hstate(compound_head(page));
1550 1558
1551 gfp_mask = htlb_alloc_mask(h);1559 gfp_mask = htlb_modify_alloc_mask(h, gfp_mask);
1552 return alloc_huge_page_nodemask(h, preferred_nid,1560 return alloc_huge_page_nodemask(h, nid, mtc->nmask, gfp_mask);
1553 nodemask, gfp_mask);
1554 }1561 }
1555 1562
1556 if (PageTransHuge(page)) {1563 if (PageTransHuge(page)) {
@@ -1562,12 +1569,11 @@ struct page *new_page_nodemask(struct page *page, · 5 unmodified lines
1562 gfp_mask |= GFP_TRANSHUGE;1569 gfp_mask |= GFP_TRANSHUGE;
1563 order = HPAGE_PMD_ORDER;1570 order = HPAGE_PMD_ORDER;
1564 }1571 }
1565 1572 zidx = zone_idx(page_zone(page));
1566 if (PageHighMem(page) || (zone_idx(page_zone(page)) == ZONE_MOVABLE))1573 if (is_highmem_idx(zidx) || zidx == ZONE_MOVABLE)
1567 gfp_mask |= __GFP_HIGHMEM;1574 gfp_mask |= __GFP_HIGHMEM;
1568 1575
1569 new_page = __alloc_pages_nodemask(gfp_mask, order,1576 new_page = __alloc_pages_nodemask(gfp_mask, order, nid, mtc->nmask);
1570 preferred_nid, nodemask);
1571 1577
1572 if (new_page && PageTransHuge(new_page))1578 if (new_page && PageTransHuge(new_page))
1573 prep_transhuge_page(new_page);1579 prep_transhuge_page(new_page);
mm/page_isolation.c+5−2
@@ -309,7 +309,10 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn, · 308 unmodified lines
309 309
310struct page *alloc_migrate_target(struct page *page, unsigned long private)310struct page *alloc_migrate_target(struct page *page, unsigned long private)
311{311{
312 int nid = page_to_nid(page);312 struct migration_target_control mtc = {
313 .nid = page_to_nid(page),
314 .gfp_mask = GFP_USER | __GFP_MOVABLE | __GFP_RETRY_MAYFAIL,
315 };
313 316
314 return new_page_nodemask(page, nid, &node_states[N_MEMORY]);317 return alloc_migration_target(page, (unsigned long)&mtc);
315}318}