diff options
Diffstat (limited to 'mm/memory.c')
-rw-r--r-- | mm/memory.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/mm/memory.c b/mm/memory.c index c57efa25cdbb..eba846bcf124 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -3547,6 +3547,7 @@ int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3547 | int last_cpupid; | 3547 | int last_cpupid; |
3548 | int target_nid; | 3548 | int target_nid; |
3549 | bool migrated = false; | 3549 | bool migrated = false; |
3550 | int flags = 0; | ||
3550 | 3551 | ||
3551 | /* | 3552 | /* |
3552 | * The "pte" at this point cannot be used safely without | 3553 | * The "pte" at this point cannot be used safely without |
@@ -3575,6 +3576,14 @@ int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3575 | } | 3576 | } |
3576 | BUG_ON(is_zero_pfn(page_to_pfn(page))); | 3577 | BUG_ON(is_zero_pfn(page_to_pfn(page))); |
3577 | 3578 | ||
3579 | /* | ||
3580 | * Avoid grouping on DSO/COW pages in specific and RO pages | ||
3581 | * in general, RO pages shouldn't hurt as much anyway since | ||
3582 | * they can be in shared cache state. | ||
3583 | */ | ||
3584 | if (!pte_write(pte)) | ||
3585 | flags |= TNF_NO_GROUP; | ||
3586 | |||
3578 | last_cpupid = page_cpupid_last(page); | 3587 | last_cpupid = page_cpupid_last(page); |
3579 | page_nid = page_to_nid(page); | 3588 | page_nid = page_to_nid(page); |
3580 | target_nid = numa_migrate_prep(page, vma, addr, page_nid); | 3589 | target_nid = numa_migrate_prep(page, vma, addr, page_nid); |
@@ -3586,12 +3595,14 @@ int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3586 | 3595 | ||
3587 | /* Migrate to the requested node */ | 3596 | /* Migrate to the requested node */ |
3588 | migrated = migrate_misplaced_page(page, vma, target_nid); | 3597 | migrated = migrate_misplaced_page(page, vma, target_nid); |
3589 | if (migrated) | 3598 | if (migrated) { |
3590 | page_nid = target_nid; | 3599 | page_nid = target_nid; |
3600 | flags |= TNF_MIGRATED; | ||
3601 | } | ||
3591 | 3602 | ||
3592 | out: | 3603 | out: |
3593 | if (page_nid != -1) | 3604 | if (page_nid != -1) |
3594 | task_numa_fault(last_cpupid, page_nid, 1, migrated); | 3605 | task_numa_fault(last_cpupid, page_nid, 1, flags); |
3595 | return 0; | 3606 | return 0; |
3596 | } | 3607 | } |
3597 | 3608 | ||
@@ -3632,6 +3643,7 @@ static int do_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3632 | int page_nid = -1; | 3643 | int page_nid = -1; |
3633 | int target_nid; | 3644 | int target_nid; |
3634 | bool migrated = false; | 3645 | bool migrated = false; |
3646 | int flags = 0; | ||
3635 | 3647 | ||
3636 | if (!pte_present(pteval)) | 3648 | if (!pte_present(pteval)) |
3637 | continue; | 3649 | continue; |
@@ -3651,20 +3663,30 @@ static int do_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3651 | if (unlikely(!page)) | 3663 | if (unlikely(!page)) |
3652 | continue; | 3664 | continue; |
3653 | 3665 | ||
3666 | /* | ||
3667 | * Avoid grouping on DSO/COW pages in specific and RO pages | ||
3668 | * in general, RO pages shouldn't hurt as much anyway since | ||
3669 | * they can be in shared cache state. | ||
3670 | */ | ||
3671 | if (!pte_write(pteval)) | ||
3672 | flags |= TNF_NO_GROUP; | ||
3673 | |||
3654 | last_cpupid = page_cpupid_last(page); | 3674 | last_cpupid = page_cpupid_last(page); |
3655 | page_nid = page_to_nid(page); | 3675 | page_nid = page_to_nid(page); |
3656 | target_nid = numa_migrate_prep(page, vma, addr, page_nid); | 3676 | target_nid = numa_migrate_prep(page, vma, addr, page_nid); |
3657 | pte_unmap_unlock(pte, ptl); | 3677 | pte_unmap_unlock(pte, ptl); |
3658 | if (target_nid != -1) { | 3678 | if (target_nid != -1) { |
3659 | migrated = migrate_misplaced_page(page, vma, target_nid); | 3679 | migrated = migrate_misplaced_page(page, vma, target_nid); |
3660 | if (migrated) | 3680 | if (migrated) { |
3661 | page_nid = target_nid; | 3681 | page_nid = target_nid; |
3682 | flags |= TNF_MIGRATED; | ||
3683 | } | ||
3662 | } else { | 3684 | } else { |
3663 | put_page(page); | 3685 | put_page(page); |
3664 | } | 3686 | } |
3665 | 3687 | ||
3666 | if (page_nid != -1) | 3688 | if (page_nid != -1) |
3667 | task_numa_fault(last_cpupid, page_nid, 1, migrated); | 3689 | task_numa_fault(last_cpupid, page_nid, 1, flags); |
3668 | 3690 | ||
3669 | pte = pte_offset_map_lock(mm, pmdp, addr, &ptl); | 3691 | pte = pte_offset_map_lock(mm, pmdp, addr, &ptl); |
3670 | } | 3692 | } |