aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c53
1 files changed, 21 insertions, 32 deletions
diff --git a/mm/memory.c b/mm/memory.c
index 1311f26497e6..d176154c243f 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3521,12 +3521,12 @@ static int do_nonlinear_fault(struct mm_struct *mm, struct vm_area_struct *vma,
3521} 3521}
3522 3522
3523int numa_migrate_prep(struct page *page, struct vm_area_struct *vma, 3523int numa_migrate_prep(struct page *page, struct vm_area_struct *vma,
3524 unsigned long addr, int current_nid) 3524 unsigned long addr, int page_nid)
3525{ 3525{
3526 get_page(page); 3526 get_page(page);
3527 3527
3528 count_vm_numa_event(NUMA_HINT_FAULTS); 3528 count_vm_numa_event(NUMA_HINT_FAULTS);
3529 if (current_nid == numa_node_id()) 3529 if (page_nid == numa_node_id())
3530 count_vm_numa_event(NUMA_HINT_FAULTS_LOCAL); 3530 count_vm_numa_event(NUMA_HINT_FAULTS_LOCAL);
3531 3531
3532 return mpol_misplaced(page, vma, addr); 3532 return mpol_misplaced(page, vma, addr);
@@ -3537,7 +3537,7 @@ int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
3537{ 3537{
3538 struct page *page = NULL; 3538 struct page *page = NULL;
3539 spinlock_t *ptl; 3539 spinlock_t *ptl;
3540 int current_nid = -1; 3540 int page_nid = -1;
3541 int target_nid; 3541 int target_nid;
3542 bool migrated = false; 3542 bool migrated = false;
3543 3543
@@ -3567,15 +3567,10 @@ int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
3567 return 0; 3567 return 0;
3568 } 3568 }
3569 3569
3570 current_nid = page_to_nid(page); 3570 page_nid = page_to_nid(page);
3571 target_nid = numa_migrate_prep(page, vma, addr, current_nid); 3571 target_nid = numa_migrate_prep(page, vma, addr, page_nid);
3572 pte_unmap_unlock(ptep, ptl); 3572 pte_unmap_unlock(ptep, ptl);
3573 if (target_nid == -1) { 3573 if (target_nid == -1) {
3574 /*
3575 * Account for the fault against the current node if it not
3576 * being replaced regardless of where the page is located.
3577 */
3578 current_nid = numa_node_id();
3579 put_page(page); 3574 put_page(page);
3580 goto out; 3575 goto out;
3581 } 3576 }
@@ -3583,11 +3578,11 @@ int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
3583 /* Migrate to the requested node */ 3578 /* Migrate to the requested node */
3584 migrated = migrate_misplaced_page(page, target_nid); 3579 migrated = migrate_misplaced_page(page, target_nid);
3585 if (migrated) 3580 if (migrated)
3586 current_nid = target_nid; 3581 page_nid = target_nid;
3587 3582
3588out: 3583out:
3589 if (current_nid != -1) 3584 if (page_nid != -1)
3590 task_numa_fault(current_nid, 1, migrated); 3585 task_numa_fault(page_nid, 1, migrated);
3591 return 0; 3586 return 0;
3592} 3587}
3593 3588
@@ -3602,7 +3597,6 @@ static int do_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
3602 unsigned long offset; 3597 unsigned long offset;
3603 spinlock_t *ptl; 3598 spinlock_t *ptl;
3604 bool numa = false; 3599 bool numa = false;
3605 int local_nid = numa_node_id();
3606 3600
3607 spin_lock(&mm->page_table_lock); 3601 spin_lock(&mm->page_table_lock);
3608 pmd = *pmdp; 3602 pmd = *pmdp;
@@ -3625,9 +3619,10 @@ static int do_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
3625 for (addr = _addr + offset; addr < _addr + PMD_SIZE; pte++, addr += PAGE_SIZE) { 3619 for (addr = _addr + offset; addr < _addr + PMD_SIZE; pte++, addr += PAGE_SIZE) {
3626 pte_t pteval = *pte; 3620 pte_t pteval = *pte;
3627 struct page *page; 3621 struct page *page;
3628 int curr_nid = local_nid; 3622 int page_nid = -1;
3629 int target_nid; 3623 int target_nid;
3630 bool migrated; 3624 bool migrated = false;
3625
3631 if (!pte_present(pteval)) 3626 if (!pte_present(pteval))
3632 continue; 3627 continue;
3633 if (!pte_numa(pteval)) 3628 if (!pte_numa(pteval))
@@ -3649,25 +3644,19 @@ static int do_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
3649 if (unlikely(page_mapcount(page) != 1)) 3644 if (unlikely(page_mapcount(page) != 1))
3650 continue; 3645 continue;
3651 3646
3652 /* 3647 page_nid = page_to_nid(page);
3653 * Note that the NUMA fault is later accounted to either 3648 target_nid = numa_migrate_prep(page, vma, addr, page_nid);
3654 * the node that is currently running or where the page is 3649 pte_unmap_unlock(pte, ptl);
3655 * migrated to. 3650 if (target_nid != -1) {
3656 */ 3651 migrated = migrate_misplaced_page(page, target_nid);
3657 curr_nid = local_nid; 3652 if (migrated)
3658 target_nid = numa_migrate_prep(page, vma, addr, 3653 page_nid = target_nid;
3659 page_to_nid(page)); 3654 } else {
3660 if (target_nid == -1) {
3661 put_page(page); 3655 put_page(page);
3662 continue;
3663 } 3656 }
3664 3657
3665 /* Migrate to the requested node */ 3658 if (page_nid != -1)
3666 pte_unmap_unlock(pte, ptl); 3659 task_numa_fault(page_nid, 1, migrated);
3667 migrated = migrate_misplaced_page(page, target_nid);
3668 if (migrated)
3669 curr_nid = target_nid;
3670 task_numa_fault(curr_nid, 1, migrated);
3671 3660
3672 pte = pte_offset_map_lock(mm, pmdp, addr, &ptl); 3661 pte = pte_offset_map_lock(mm, pmdp, addr, &ptl);
3673 } 3662 }