diff options
Diffstat (limited to 'mm/hugetlb.c')
-rw-r--r-- | mm/hugetlb.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 827bb02a43a4..ef6963b577fd 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -372,8 +372,10 @@ retry_locked: | |||
372 | spin_unlock(&resv->lock); | 372 | spin_unlock(&resv->lock); |
373 | 373 | ||
374 | trg = kmalloc(sizeof(*trg), GFP_KERNEL); | 374 | trg = kmalloc(sizeof(*trg), GFP_KERNEL); |
375 | if (!trg) | 375 | if (!trg) { |
376 | kfree(nrg); | ||
376 | return -ENOMEM; | 377 | return -ENOMEM; |
378 | } | ||
377 | 379 | ||
378 | spin_lock(&resv->lock); | 380 | spin_lock(&resv->lock); |
379 | list_add(&trg->link, &resv->region_cache); | 381 | list_add(&trg->link, &resv->region_cache); |
@@ -483,8 +485,16 @@ static long region_del(struct resv_map *resv, long f, long t) | |||
483 | retry: | 485 | retry: |
484 | spin_lock(&resv->lock); | 486 | spin_lock(&resv->lock); |
485 | list_for_each_entry_safe(rg, trg, head, link) { | 487 | list_for_each_entry_safe(rg, trg, head, link) { |
486 | if (rg->to <= f) | 488 | /* |
489 | * Skip regions before the range to be deleted. file_region | ||
490 | * ranges are normally of the form [from, to). However, there | ||
491 | * may be a "placeholder" entry in the map which is of the form | ||
492 | * (from, to) with from == to. Check for placeholder entries | ||
493 | * at the beginning of the range to be deleted. | ||
494 | */ | ||
495 | if (rg->to <= f && (rg->to != rg->from || rg->to != f)) | ||
487 | continue; | 496 | continue; |
497 | |||
488 | if (rg->from >= t) | 498 | if (rg->from >= t) |
489 | break; | 499 | break; |
490 | 500 | ||
@@ -1886,7 +1896,10 @@ struct page *alloc_huge_page(struct vm_area_struct *vma, | |||
1886 | page = __alloc_buddy_huge_page_with_mpol(h, vma, addr); | 1896 | page = __alloc_buddy_huge_page_with_mpol(h, vma, addr); |
1887 | if (!page) | 1897 | if (!page) |
1888 | goto out_uncharge_cgroup; | 1898 | goto out_uncharge_cgroup; |
1889 | 1899 | if (!avoid_reserve && vma_has_reserves(vma, gbl_chg)) { | |
1900 | SetPagePrivate(page); | ||
1901 | h->resv_huge_pages--; | ||
1902 | } | ||
1890 | spin_lock(&hugetlb_lock); | 1903 | spin_lock(&hugetlb_lock); |
1891 | list_move(&page->lru, &h->hugepage_activelist); | 1904 | list_move(&page->lru, &h->hugepage_activelist); |
1892 | /* Fall through */ | 1905 | /* Fall through */ |
@@ -3693,12 +3706,12 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3693 | } else if (unlikely(is_hugetlb_entry_hwpoisoned(entry))) | 3706 | } else if (unlikely(is_hugetlb_entry_hwpoisoned(entry))) |
3694 | return VM_FAULT_HWPOISON_LARGE | | 3707 | return VM_FAULT_HWPOISON_LARGE | |
3695 | VM_FAULT_SET_HINDEX(hstate_index(h)); | 3708 | VM_FAULT_SET_HINDEX(hstate_index(h)); |
3709 | } else { | ||
3710 | ptep = huge_pte_alloc(mm, address, huge_page_size(h)); | ||
3711 | if (!ptep) | ||
3712 | return VM_FAULT_OOM; | ||
3696 | } | 3713 | } |
3697 | 3714 | ||
3698 | ptep = huge_pte_alloc(mm, address, huge_page_size(h)); | ||
3699 | if (!ptep) | ||
3700 | return VM_FAULT_OOM; | ||
3701 | |||
3702 | mapping = vma->vm_file->f_mapping; | 3715 | mapping = vma->vm_file->f_mapping; |
3703 | idx = vma_hugecache_offset(h, vma, address); | 3716 | idx = vma_hugecache_offset(h, vma, address); |
3704 | 3717 | ||