diff options
Diffstat (limited to 'mm/memory.c')
-rw-r--r-- | mm/memory.c | 53 |
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 | ||
3523 | int numa_migrate_prep(struct page *page, struct vm_area_struct *vma, | 3523 | int 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 | ||
3588 | out: | 3583 | out: |
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 | } |