summaryrefslogtreecommitdiffstats
path: root/mm/migrate.c
diff options
context:
space:
mode:
authorNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>2017-09-08 19:11:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-08 21:26:45 -0400
commite8db67eb0ded3797085f032c84b5d8248f412de3 (patch)
tree8c0d7a943ae3ba6075fc98e3d2c1d832edb3e338 /mm/migrate.c
parentc8633798497ce894c22ab083eb884c8294c537b2 (diff)
mm: migrate: move_pages() supports thp migration
This patch enables thp migration for move_pages(2). Link: http://lkml.kernel.org/r/20170717193955.20207-10-zi.yan@sent.com Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> Signed-off-by: Zi Yan <zi.yan@cs.rutgers.edu> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Anshuman Khandual <khandual@linux.vnet.ibm.com> Cc: Dave Hansen <dave.hansen@intel.com> Cc: David Nellans <dnellans@nvidia.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Mel Gorman <mgorman@techsingularity.net> Cc: Minchan Kim <minchan@kernel.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Michal Hocko <mhocko@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/migrate.c')
-rw-r--r--mm/migrate.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/mm/migrate.c b/mm/migrate.c
index bf5366a2176b..1088cef6ef8b 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -185,8 +185,8 @@ void putback_movable_pages(struct list_head *l)
185 unlock_page(page); 185 unlock_page(page);
186 put_page(page); 186 put_page(page);
187 } else { 187 } else {
188 dec_node_page_state(page, NR_ISOLATED_ANON + 188 mod_node_page_state(page_pgdat(page), NR_ISOLATED_ANON +
189 page_is_file_cache(page)); 189 page_is_file_cache(page), -hpage_nr_pages(page));
190 putback_lru_page(page); 190 putback_lru_page(page);
191 } 191 }
192 } 192 }
@@ -1146,8 +1146,8 @@ out:
1146 * as __PageMovable 1146 * as __PageMovable
1147 */ 1147 */
1148 if (likely(!__PageMovable(page))) 1148 if (likely(!__PageMovable(page)))
1149 dec_node_page_state(page, NR_ISOLATED_ANON + 1149 mod_node_page_state(page_pgdat(page), NR_ISOLATED_ANON +
1150 page_is_file_cache(page)); 1150 page_is_file_cache(page), -hpage_nr_pages(page));
1151 } 1151 }
1152 1152
1153 /* 1153 /*
@@ -1421,7 +1421,17 @@ static struct page *new_page_node(struct page *p, unsigned long private,
1421 if (PageHuge(p)) 1421 if (PageHuge(p))
1422 return alloc_huge_page_node(page_hstate(compound_head(p)), 1422 return alloc_huge_page_node(page_hstate(compound_head(p)),
1423 pm->node); 1423 pm->node);
1424 else 1424 else if (thp_migration_supported() && PageTransHuge(p)) {
1425 struct page *thp;
1426
1427 thp = alloc_pages_node(pm->node,
1428 (GFP_TRANSHUGE | __GFP_THISNODE) & ~__GFP_RECLAIM,
1429 HPAGE_PMD_ORDER);
1430 if (!thp)
1431 return NULL;
1432 prep_transhuge_page(thp);
1433 return thp;
1434 } else
1425 return __alloc_pages_node(pm->node, 1435 return __alloc_pages_node(pm->node,
1426 GFP_HIGHUSER_MOVABLE | __GFP_THISNODE, 0); 1436 GFP_HIGHUSER_MOVABLE | __GFP_THISNODE, 0);
1427} 1437}
@@ -1448,6 +1458,8 @@ static int do_move_page_to_node_array(struct mm_struct *mm,
1448 for (pp = pm; pp->node != MAX_NUMNODES; pp++) { 1458 for (pp = pm; pp->node != MAX_NUMNODES; pp++) {
1449 struct vm_area_struct *vma; 1459 struct vm_area_struct *vma;
1450 struct page *page; 1460 struct page *page;
1461 struct page *head;
1462 unsigned int follflags;
1451 1463
1452 err = -EFAULT; 1464 err = -EFAULT;
1453 vma = find_vma(mm, pp->addr); 1465 vma = find_vma(mm, pp->addr);
@@ -1455,8 +1467,10 @@ static int do_move_page_to_node_array(struct mm_struct *mm,
1455 goto set_status; 1467 goto set_status;
1456 1468
1457 /* FOLL_DUMP to ignore special (like zero) pages */ 1469 /* FOLL_DUMP to ignore special (like zero) pages */
1458 page = follow_page(vma, pp->addr, 1470 follflags = FOLL_GET | FOLL_DUMP;
1459 FOLL_GET | FOLL_SPLIT | FOLL_DUMP); 1471 if (!thp_migration_supported())
1472 follflags |= FOLL_SPLIT;
1473 page = follow_page(vma, pp->addr, follflags);
1460 1474
1461 err = PTR_ERR(page); 1475 err = PTR_ERR(page);
1462 if (IS_ERR(page)) 1476 if (IS_ERR(page))
@@ -1466,7 +1480,6 @@ static int do_move_page_to_node_array(struct mm_struct *mm,
1466 if (!page) 1480 if (!page)
1467 goto set_status; 1481 goto set_status;
1468 1482
1469 pp->page = page;
1470 err = page_to_nid(page); 1483 err = page_to_nid(page);
1471 1484
1472 if (err == pp->node) 1485 if (err == pp->node)
@@ -1481,16 +1494,22 @@ static int do_move_page_to_node_array(struct mm_struct *mm,
1481 goto put_and_set; 1494 goto put_and_set;
1482 1495
1483 if (PageHuge(page)) { 1496 if (PageHuge(page)) {
1484 if (PageHead(page)) 1497 if (PageHead(page)) {
1485 isolate_huge_page(page, &pagelist); 1498 isolate_huge_page(page, &pagelist);
1499 err = 0;
1500 pp->page = page;
1501 }
1486 goto put_and_set; 1502 goto put_and_set;
1487 } 1503 }
1488 1504
1489 err = isolate_lru_page(page); 1505 pp->page = compound_head(page);
1506 head = compound_head(page);
1507 err = isolate_lru_page(head);
1490 if (!err) { 1508 if (!err) {
1491 list_add_tail(&page->lru, &pagelist); 1509 list_add_tail(&head->lru, &pagelist);
1492 inc_node_page_state(page, NR_ISOLATED_ANON + 1510 mod_node_page_state(page_pgdat(head),
1493 page_is_file_cache(page)); 1511 NR_ISOLATED_ANON + page_is_file_cache(head),
1512 hpage_nr_pages(head));
1494 } 1513 }
1495put_and_set: 1514put_and_set:
1496 /* 1515 /*