[PATCH 075/166] migrate: consolidate MPOL_MF_SW_YOUNG behaviors

From: Fengguang Wu
Date: Sat Sep 29 2018 - 22:50:58 EST


- if page already in target node: SetPageReferenced
- otherwise: change_prot_numa

Signed-off-by: Fengguang Wu <fengguang.wu@xxxxxxxxx>
---
arch/x86/kvm/Kconfig | 1 +
mm/migrate.c | 65 +++++++++++++++++++++++++++++++---------------------
2 files changed, 40 insertions(+), 26 deletions(-)

diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index 4c6dec47fac6..c103373536fc 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -100,6 +100,7 @@ config KVM_EPT_IDLE
tristate "KVM EPT idle page tracking"
depends on KVM_INTEL
depends on PROC_PAGE_MONITOR
+ depends on NUMA_BALANCING
---help---
Provides support for walking EPT to get the A bits on Intel
processors equipped with the VT extensions.
diff --git a/mm/migrate.c b/mm/migrate.c
index d933f6966601..d944f031c9ea 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1500,6 +1500,8 @@ static int add_page_for_migration(struct mm_struct *mm, unsigned long addr,
{
struct vm_area_struct *vma;
struct page *page;
+ unsigned long end;
+ unsigned int page_nid;
unsigned int follflags;
int err;
bool migrate_all = flags & MPOL_MF_MOVE_ALL;
@@ -1522,49 +1524,60 @@ static int add_page_for_migration(struct mm_struct *mm, unsigned long addr,
if (!page)
goto out;

- err = 0;
- if (page_to_nid(page) == node)
- goto out_putpage;
+ page_nid = page_to_nid(page);

err = -EACCES;
if (page_mapcount(page) > 1 && !migrate_all)
goto out_putpage;

- if (flags & MPOL_MF_SW_YOUNG) {
- unsigned long start, end;
- unsigned long nr_pte_updates = 0;
-
- start = max(addr, vma->vm_start);
-
- /* TODO: if huge page */
- end = ALIGN(addr + (1 << PAGE_SHIFT), PAGE_SIZE);
- end = min(end, vma->vm_end);
- nr_pte_updates = change_prot_numa(vma, start, end);
-
- err = 0;
- goto out_putpage;
- }
-
+ err = 0;
if (PageHuge(page)) {
- if (PageHead(page)) {
- /* Check if the page is software young. */
- if (flags & MPOL_MF_SW_YOUNG)
+ if (!PageHead(page)) {
+ err = -EACCES;
+ goto out_putpage;
+ }
+ if (flags & MPOL_MF_SW_YOUNG) {
+ if (page_nid == node)
SetPageReferenced(page);
- isolate_huge_page(page, pagelist);
- err = 0;
+ else if (PageAnon(page)) {
+ end = addr + (hpage_nr_pages(page) << PAGE_SHIFT);
+ if (end <= vma->vm_end)
+ change_prot_numa(vma, addr, end);
+ }
+ goto out_putpage;
}
+ if (page_nid == node)
+ goto out_putpage;
+ isolate_huge_page(page, pagelist);
} else {
struct page *head;

head = compound_head(page);
+
+ if (flags & MPOL_MF_SW_YOUNG) {
+ if (page_nid == node)
+ SetPageReferenced(head);
+ else {
+ unsigned long size;
+ size = hpage_nr_pages(head) << PAGE_SHIFT;
+ end = addr + size;
+ if (unlikely(addr & (size - 1)))
+ err = -EXDEV;
+ else if (likely(end <= vma->vm_end))
+ change_prot_numa(vma, addr, end);
+ else
+ err = -ERANGE;
+ }
+ goto out_putpage;
+ }
+ if (page_nid == node)
+ goto out_putpage;
+
err = isolate_lru_page(head);
if (err)
goto out_putpage;

err = 0;
- /* Check if the page is software young. */
- if (flags & MPOL_MF_SW_YOUNG)
- SetPageReferenced(head);
list_add_tail(&head->lru, pagelist);
mod_node_page_state(page_pgdat(head),
NR_ISOLATED_ANON + page_is_file_cache(head),
--
2.15.0


--sbnmklyntwize2li
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0076-mempolicy-force-NUMA-balancing.patch"