diff options
Diffstat (limited to 'mm/memory.c')
-rw-r--r-- | mm/memory.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/mm/memory.c b/mm/memory.c index 411144f977b1..97839f5c8c30 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -3035,6 +3035,7 @@ static int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3035 | int last_cpupid; | 3035 | int last_cpupid; |
3036 | int target_nid; | 3036 | int target_nid; |
3037 | bool migrated = false; | 3037 | bool migrated = false; |
3038 | bool was_writable = pte_write(pte); | ||
3038 | int flags = 0; | 3039 | int flags = 0; |
3039 | 3040 | ||
3040 | /* A PROT_NONE fault should not end up here */ | 3041 | /* A PROT_NONE fault should not end up here */ |
@@ -3059,6 +3060,8 @@ static int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3059 | /* Make it present again */ | 3060 | /* Make it present again */ |
3060 | pte = pte_modify(pte, vma->vm_page_prot); | 3061 | pte = pte_modify(pte, vma->vm_page_prot); |
3061 | pte = pte_mkyoung(pte); | 3062 | pte = pte_mkyoung(pte); |
3063 | if (was_writable) | ||
3064 | pte = pte_mkwrite(pte); | ||
3062 | set_pte_at(mm, addr, ptep, pte); | 3065 | set_pte_at(mm, addr, ptep, pte); |
3063 | update_mmu_cache(vma, addr, ptep); | 3066 | update_mmu_cache(vma, addr, ptep); |
3064 | 3067 | ||
@@ -3069,16 +3072,14 @@ static int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3069 | } | 3072 | } |
3070 | 3073 | ||
3071 | /* | 3074 | /* |
3072 | * Avoid grouping on DSO/COW pages in specific and RO pages | 3075 | * Avoid grouping on RO pages in general. RO pages shouldn't hurt as |
3073 | * in general, RO pages shouldn't hurt as much anyway since | 3076 | * much anyway since they can be in shared cache state. This misses |
3074 | * they can be in shared cache state. | 3077 | * the case where a mapping is writable but the process never writes |
3075 | * | 3078 | * to it but pte_write gets cleared during protection updates and |
3076 | * FIXME! This checks "pmd_dirty()" as an approximation of | 3079 | * pte_dirty has unpredictable behaviour between PTE scan updates, |
3077 | * "is this a read-only page", since checking "pmd_write()" | 3080 | * background writeback, dirty balancing and application behaviour. |
3078 | * is even more broken. We haven't actually turned this into | ||
3079 | * a writable page, so pmd_write() will always be false. | ||
3080 | */ | 3081 | */ |
3081 | if (!pte_dirty(pte)) | 3082 | if (!(vma->vm_flags & VM_WRITE)) |
3082 | flags |= TNF_NO_GROUP; | 3083 | flags |= TNF_NO_GROUP; |
3083 | 3084 | ||
3084 | /* | 3085 | /* |
@@ -3102,7 +3103,8 @@ static int do_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3102 | if (migrated) { | 3103 | if (migrated) { |
3103 | page_nid = target_nid; | 3104 | page_nid = target_nid; |
3104 | flags |= TNF_MIGRATED; | 3105 | flags |= TNF_MIGRATED; |
3105 | } | 3106 | } else |
3107 | flags |= TNF_MIGRATE_FAIL; | ||
3106 | 3108 | ||
3107 | out: | 3109 | out: |
3108 | if (page_nid != -1) | 3110 | if (page_nid != -1) |