diff options
Diffstat (limited to 'mm/huge_memory.c')
-rw-r--r-- | mm/huge_memory.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 5723b551c023..d79f7a55bf6f 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
@@ -1147,7 +1147,7 @@ out: | |||
1147 | } | 1147 | } |
1148 | 1148 | ||
1149 | int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, | 1149 | int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, |
1150 | unsigned long addr, pgprot_t newprot) | 1150 | unsigned long addr, pgprot_t newprot, int prot_numa) |
1151 | { | 1151 | { |
1152 | struct mm_struct *mm = vma->vm_mm; | 1152 | struct mm_struct *mm = vma->vm_mm; |
1153 | int ret = 0; | 1153 | int ret = 0; |
@@ -1155,7 +1155,17 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, | |||
1155 | if (__pmd_trans_huge_lock(pmd, vma) == 1) { | 1155 | if (__pmd_trans_huge_lock(pmd, vma) == 1) { |
1156 | pmd_t entry; | 1156 | pmd_t entry; |
1157 | entry = pmdp_get_and_clear(mm, addr, pmd); | 1157 | entry = pmdp_get_and_clear(mm, addr, pmd); |
1158 | entry = pmd_modify(entry, newprot); | 1158 | if (!prot_numa) |
1159 | entry = pmd_modify(entry, newprot); | ||
1160 | else { | ||
1161 | struct page *page = pmd_page(*pmd); | ||
1162 | |||
1163 | /* only check non-shared pages */ | ||
1164 | if (page_mapcount(page) == 1 && | ||
1165 | !pmd_numa(*pmd)) { | ||
1166 | entry = pmd_mknuma(entry); | ||
1167 | } | ||
1168 | } | ||
1159 | set_pmd_at(mm, addr, pmd, entry); | 1169 | set_pmd_at(mm, addr, pmd, entry); |
1160 | spin_unlock(&vma->vm_mm->page_table_lock); | 1170 | spin_unlock(&vma->vm_mm->page_table_lock); |
1161 | ret = 1; | 1171 | ret = 1; |