aboutsummaryrefslogtreecommitdiffstats
path: root/mm/hugetlb.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/hugetlb.c')
-rw-r--r--mm/hugetlb.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index ac5f044bf514..ea0826ff2663 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -277,12 +277,15 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
277 unsigned long addr; 277 unsigned long addr;
278 278
279 for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) { 279 for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
280 src_pte = huge_pte_offset(src, addr);
281 if (!src_pte)
282 continue;
280 dst_pte = huge_pte_alloc(dst, addr); 283 dst_pte = huge_pte_alloc(dst, addr);
281 if (!dst_pte) 284 if (!dst_pte)
282 goto nomem; 285 goto nomem;
286 spin_lock(&dst->page_table_lock);
283 spin_lock(&src->page_table_lock); 287 spin_lock(&src->page_table_lock);
284 src_pte = huge_pte_offset(src, addr); 288 if (!pte_none(*src_pte)) {
285 if (src_pte && !pte_none(*src_pte)) {
286 entry = *src_pte; 289 entry = *src_pte;
287 ptepage = pte_page(entry); 290 ptepage = pte_page(entry);
288 get_page(ptepage); 291 get_page(ptepage);
@@ -290,6 +293,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
290 set_huge_pte_at(dst, addr, dst_pte, entry); 293 set_huge_pte_at(dst, addr, dst_pte, entry);
291 } 294 }
292 spin_unlock(&src->page_table_lock); 295 spin_unlock(&src->page_table_lock);
296 spin_unlock(&dst->page_table_lock);
293 } 297 }
294 return 0; 298 return 0;
295 299
@@ -354,7 +358,6 @@ int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
354 358
355 hugetlb_prefault_arch_hook(mm); 359 hugetlb_prefault_arch_hook(mm);
356 360
357 spin_lock(&mm->page_table_lock);
358 for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) { 361 for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
359 unsigned long idx; 362 unsigned long idx;
360 pte_t *pte = huge_pte_alloc(mm, addr); 363 pte_t *pte = huge_pte_alloc(mm, addr);
@@ -389,11 +392,12 @@ int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
389 goto out; 392 goto out;
390 } 393 }
391 } 394 }
395 spin_lock(&mm->page_table_lock);
392 add_mm_counter(mm, file_rss, HPAGE_SIZE / PAGE_SIZE); 396 add_mm_counter(mm, file_rss, HPAGE_SIZE / PAGE_SIZE);
393 set_huge_pte_at(mm, addr, pte, make_huge_pte(vma, page)); 397 set_huge_pte_at(mm, addr, pte, make_huge_pte(vma, page));
398 spin_unlock(&mm->page_table_lock);
394 } 399 }
395out: 400out:
396 spin_unlock(&mm->page_table_lock);
397 return ret; 401 return ret;
398} 402}
399 403