aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c73
1 files changed, 35 insertions, 38 deletions
diff --git a/mm/memory.c b/mm/memory.c
index ca0003947115..d176154c243f 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -837,6 +837,8 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm,
837 */ 837 */
838 make_migration_entry_read(&entry); 838 make_migration_entry_read(&entry);
839 pte = swp_entry_to_pte(entry); 839 pte = swp_entry_to_pte(entry);
840 if (pte_swp_soft_dirty(*src_pte))
841 pte = pte_swp_mksoft_dirty(pte);
840 set_pte_at(src_mm, addr, src_pte, pte); 842 set_pte_at(src_mm, addr, src_pte, pte);
841 } 843 }
842 } 844 }
@@ -3519,12 +3521,12 @@ static int do_nonlinear_fault(struct mm_struct *mm, struct vm_area_struct *vma,
3519} 3521}
3520 3522
3521int numa_migrate_prep(struct page *page, struct vm_area_struct *vma, 3523int numa_migrate_prep(struct page *page, struct vm_area_struct *vma,
3522 unsigned long addr, int current_nid) 3524 unsigned long addr, int page_nid)
3523{ 3525{
3524 get_page(page); 3526 get_page(page);
3525 3527
3526 count_vm_numa_event(NUMA_HINT_FAULTS); 3528 count_vm_numa_event(NUMA_HINT_FAULTS);
3527 if (current_nid == numa_node_id()) 3529 if (page_nid == numa_node_id())
3528 count_vm_numa_event(NUMA_HINT_FAULTS_LOCAL); 3530 count_vm_numa_event(NUMA_HINT_FAULTS_LOCAL);
3529 3531
3530 return mpol_misplaced(page, vma, addr); 3532 return mpol_misplaced(page, vma, addr);
@@ -3535,7 +3537,7 @@ int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
3535{ 3537{
3536 struct page *page = NULL; 3538 struct page *page = NULL;
3537 spinlock_t *ptl; 3539 spinlock_t *ptl;
3538 int current_nid = -1; 3540 int page_nid = -1;
3539 int target_nid; 3541 int target_nid;
3540 bool migrated = false; 3542 bool migrated = false;
3541 3543
@@ -3565,15 +3567,10 @@ int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
3565 return 0; 3567 return 0;
3566 } 3568 }
3567 3569
3568 current_nid = page_to_nid(page); 3570 page_nid = page_to_nid(page);
3569 target_nid = numa_migrate_prep(page, vma, addr, current_nid); 3571 target_nid = numa_migrate_prep(page, vma, addr, page_nid);
3570 pte_unmap_unlock(ptep, ptl); 3572 pte_unmap_unlock(ptep, ptl);
3571 if (target_nid == -1) { 3573 if (target_nid == -1) {
3572 /*
3573 * Account for the fault against the current node if it not
3574 * being replaced regardless of where the page is located.
3575 */
3576 current_nid = numa_node_id();
3577 put_page(page); 3574 put_page(page);
3578 goto out; 3575 goto out;
3579 } 3576 }
@@ -3581,11 +3578,11 @@ int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
3581 /* Migrate to the requested node */ 3578 /* Migrate to the requested node */
3582 migrated = migrate_misplaced_page(page, target_nid); 3579 migrated = migrate_misplaced_page(page, target_nid);
3583 if (migrated) 3580 if (migrated)
3584 current_nid = target_nid; 3581 page_nid = target_nid;
3585 3582
3586out: 3583out:
3587 if (current_nid != -1) 3584 if (page_nid != -1)
3588 task_numa_fault(current_nid, 1, migrated); 3585 task_numa_fault(page_nid, 1, migrated);
3589 return 0; 3586 return 0;
3590} 3587}
3591 3588
@@ -3600,7 +3597,6 @@ static int do_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
3600 unsigned long offset; 3597 unsigned long offset;
3601 spinlock_t *ptl; 3598 spinlock_t *ptl;
3602 bool numa = false; 3599 bool numa = false;
3603 int local_nid = numa_node_id();
3604 3600
3605 spin_lock(&mm->page_table_lock); 3601 spin_lock(&mm->page_table_lock);
3606 pmd = *pmdp; 3602 pmd = *pmdp;
@@ -3623,9 +3619,10 @@ static int do_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
3623 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) {
3624 pte_t pteval = *pte; 3620 pte_t pteval = *pte;
3625 struct page *page; 3621 struct page *page;
3626 int curr_nid = local_nid; 3622 int page_nid = -1;
3627 int target_nid; 3623 int target_nid;
3628 bool migrated; 3624 bool migrated = false;
3625
3629 if (!pte_present(pteval)) 3626 if (!pte_present(pteval))
3630 continue; 3627 continue;
3631 if (!pte_numa(pteval)) 3628 if (!pte_numa(pteval))
@@ -3647,25 +3644,19 @@ static int do_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
3647 if (unlikely(page_mapcount(page) != 1)) 3644 if (unlikely(page_mapcount(page) != 1))
3648 continue; 3645 continue;
3649 3646
3650 /* 3647 page_nid = page_to_nid(page);
3651 * Note that the NUMA fault is later accounted to either 3648 target_nid = numa_migrate_prep(page, vma, addr, page_nid);
3652 * the node that is currently running or where the page is 3649 pte_unmap_unlock(pte, ptl);
3653 * migrated to. 3650 if (target_nid != -1) {
3654 */ 3651 migrated = migrate_misplaced_page(page, target_nid);
3655 curr_nid = local_nid; 3652 if (migrated)
3656 target_nid = numa_migrate_prep(page, vma, addr, 3653 page_nid = target_nid;
3657 page_to_nid(page)); 3654 } else {
3658 if (target_nid == -1) {
3659 put_page(page); 3655 put_page(page);
3660 continue;
3661 } 3656 }
3662 3657
3663 /* Migrate to the requested node */ 3658 if (page_nid != -1)
3664 pte_unmap_unlock(pte, ptl); 3659 task_numa_fault(page_nid, 1, migrated);
3665 migrated = migrate_misplaced_page(page, target_nid);
3666 if (migrated)
3667 curr_nid = target_nid;
3668 task_numa_fault(curr_nid, 1, migrated);
3669 3660
3670 pte = pte_offset_map_lock(mm, pmdp, addr, &ptl); 3661 pte = pte_offset_map_lock(mm, pmdp, addr, &ptl);
3671 } 3662 }
@@ -3863,15 +3854,21 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
3863 * space. Kernel faults are handled more gracefully. 3854 * space. Kernel faults are handled more gracefully.
3864 */ 3855 */
3865 if (flags & FAULT_FLAG_USER) 3856 if (flags & FAULT_FLAG_USER)
3866 mem_cgroup_enable_oom(); 3857 mem_cgroup_oom_enable();
3867 3858
3868 ret = __handle_mm_fault(mm, vma, address, flags); 3859 ret = __handle_mm_fault(mm, vma, address, flags);
3869 3860
3870 if (flags & FAULT_FLAG_USER) 3861 if (flags & FAULT_FLAG_USER) {
3871 mem_cgroup_disable_oom(); 3862 mem_cgroup_oom_disable();
3872 3863 /*
3873 if (WARN_ON(task_in_memcg_oom(current) && !(ret & VM_FAULT_OOM))) 3864 * The task may have entered a memcg OOM situation but
3874 mem_cgroup_oom_synchronize(); 3865 * if the allocation error was handled gracefully (no
3866 * VM_FAULT_OOM), there is no need to kill anything.
3867 * Just clean up the OOM state peacefully.
3868 */
3869 if (task_in_memcg_oom(current) && !(ret & VM_FAULT_OOM))
3870 mem_cgroup_oom_synchronize(false);
3871 }
3875 3872
3876 return ret; 3873 return ret;
3877} 3874}