diff options
Diffstat (limited to 'mm/migrate.c')
-rw-r--r-- | mm/migrate.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/mm/migrate.c b/mm/migrate.c index c04692774e88..dfc8300ecbb2 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -445,6 +445,8 @@ int migrate_huge_page_move_mapping(struct address_space *mapping, | |||
445 | */ | 445 | */ |
446 | void migrate_page_copy(struct page *newpage, struct page *page) | 446 | void migrate_page_copy(struct page *newpage, struct page *page) |
447 | { | 447 | { |
448 | int cpupid; | ||
449 | |||
448 | if (PageHuge(page) || PageTransHuge(page)) | 450 | if (PageHuge(page) || PageTransHuge(page)) |
449 | copy_huge_page(newpage, page); | 451 | copy_huge_page(newpage, page); |
450 | else | 452 | else |
@@ -481,6 +483,13 @@ void migrate_page_copy(struct page *newpage, struct page *page) | |||
481 | __set_page_dirty_nobuffers(newpage); | 483 | __set_page_dirty_nobuffers(newpage); |
482 | } | 484 | } |
483 | 485 | ||
486 | /* | ||
487 | * Copy NUMA information to the new page, to prevent over-eager | ||
488 | * future migrations of this same page. | ||
489 | */ | ||
490 | cpupid = page_cpupid_xchg_last(page, -1); | ||
491 | page_cpupid_xchg_last(newpage, cpupid); | ||
492 | |||
484 | mlock_migrate_page(newpage, page); | 493 | mlock_migrate_page(newpage, page); |
485 | ksm_migrate_page(newpage, page); | 494 | ksm_migrate_page(newpage, page); |
486 | /* | 495 | /* |
@@ -1500,7 +1509,7 @@ static struct page *alloc_misplaced_dst_page(struct page *page, | |||
1500 | __GFP_NOWARN) & | 1509 | __GFP_NOWARN) & |
1501 | ~GFP_IOFS, 0); | 1510 | ~GFP_IOFS, 0); |
1502 | if (newpage) | 1511 | if (newpage) |
1503 | page_nid_xchg_last(newpage, page_nid_last(page)); | 1512 | page_cpupid_xchg_last(newpage, page_cpupid_last(page)); |
1504 | 1513 | ||
1505 | return newpage; | 1514 | return newpage; |
1506 | } | 1515 | } |
@@ -1601,7 +1610,8 @@ int numamigrate_isolate_page(pg_data_t *pgdat, struct page *page) | |||
1601 | * node. Caller is expected to have an elevated reference count on | 1610 | * node. Caller is expected to have an elevated reference count on |
1602 | * the page that will be dropped by this function before returning. | 1611 | * the page that will be dropped by this function before returning. |
1603 | */ | 1612 | */ |
1604 | int migrate_misplaced_page(struct page *page, int node) | 1613 | int migrate_misplaced_page(struct page *page, struct vm_area_struct *vma, |
1614 | int node) | ||
1605 | { | 1615 | { |
1606 | pg_data_t *pgdat = NODE_DATA(node); | 1616 | pg_data_t *pgdat = NODE_DATA(node); |
1607 | int isolated; | 1617 | int isolated; |
@@ -1609,10 +1619,11 @@ int migrate_misplaced_page(struct page *page, int node) | |||
1609 | LIST_HEAD(migratepages); | 1619 | LIST_HEAD(migratepages); |
1610 | 1620 | ||
1611 | /* | 1621 | /* |
1612 | * Don't migrate pages that are mapped in multiple processes. | 1622 | * Don't migrate file pages that are mapped in multiple processes |
1613 | * TODO: Handle false sharing detection instead of this hammer | 1623 | * with execute permissions as they are probably shared libraries. |
1614 | */ | 1624 | */ |
1615 | if (page_mapcount(page) != 1) | 1625 | if (page_mapcount(page) != 1 && page_is_file_cache(page) && |
1626 | (vma->vm_flags & VM_EXEC)) | ||
1616 | goto out; | 1627 | goto out; |
1617 | 1628 | ||
1618 | /* | 1629 | /* |
@@ -1663,13 +1674,6 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm, | |||
1663 | int page_lru = page_is_file_cache(page); | 1674 | int page_lru = page_is_file_cache(page); |
1664 | 1675 | ||
1665 | /* | 1676 | /* |
1666 | * Don't migrate pages that are mapped in multiple processes. | ||
1667 | * TODO: Handle false sharing detection instead of this hammer | ||
1668 | */ | ||
1669 | if (page_mapcount(page) != 1) | ||
1670 | goto out_dropref; | ||
1671 | |||
1672 | /* | ||
1673 | * Rate-limit the amount of data that is being migrated to a node. | 1677 | * Rate-limit the amount of data that is being migrated to a node. |
1674 | * Optimal placement is no good if the memory bus is saturated and | 1678 | * Optimal placement is no good if the memory bus is saturated and |
1675 | * all the time is being spent migrating! | 1679 | * all the time is being spent migrating! |
@@ -1682,7 +1686,7 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm, | |||
1682 | if (!new_page) | 1686 | if (!new_page) |
1683 | goto out_fail; | 1687 | goto out_fail; |
1684 | 1688 | ||
1685 | page_nid_xchg_last(new_page, page_nid_last(page)); | 1689 | page_cpupid_xchg_last(new_page, page_cpupid_last(page)); |
1686 | 1690 | ||
1687 | isolated = numamigrate_isolate_page(pgdat, page); | 1691 | isolated = numamigrate_isolate_page(pgdat, page); |
1688 | if (!isolated) { | 1692 | if (!isolated) { |