diff options
-rw-r--r-- | mm/huge_memory.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 90eef404ec2e..615d9743a3cb 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
@@ -1771,12 +1771,9 @@ static void collapse_huge_page(struct mm_struct *mm, | |||
1771 | 1771 | ||
1772 | VM_BUG_ON(address & ~HPAGE_PMD_MASK); | 1772 | VM_BUG_ON(address & ~HPAGE_PMD_MASK); |
1773 | #ifndef CONFIG_NUMA | 1773 | #ifndef CONFIG_NUMA |
1774 | up_read(&mm->mmap_sem); | ||
1774 | VM_BUG_ON(!*hpage); | 1775 | VM_BUG_ON(!*hpage); |
1775 | new_page = *hpage; | 1776 | new_page = *hpage; |
1776 | if (unlikely(mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL))) { | ||
1777 | up_read(&mm->mmap_sem); | ||
1778 | return; | ||
1779 | } | ||
1780 | #else | 1777 | #else |
1781 | VM_BUG_ON(*hpage); | 1778 | VM_BUG_ON(*hpage); |
1782 | /* | 1779 | /* |
@@ -1791,22 +1788,26 @@ static void collapse_huge_page(struct mm_struct *mm, | |||
1791 | */ | 1788 | */ |
1792 | new_page = alloc_hugepage_vma(khugepaged_defrag(), vma, address, | 1789 | new_page = alloc_hugepage_vma(khugepaged_defrag(), vma, address, |
1793 | node, __GFP_OTHER_NODE); | 1790 | node, __GFP_OTHER_NODE); |
1791 | |||
1792 | /* | ||
1793 | * After allocating the hugepage, release the mmap_sem read lock in | ||
1794 | * preparation for taking it in write mode. | ||
1795 | */ | ||
1796 | up_read(&mm->mmap_sem); | ||
1794 | if (unlikely(!new_page)) { | 1797 | if (unlikely(!new_page)) { |
1795 | up_read(&mm->mmap_sem); | ||
1796 | count_vm_event(THP_COLLAPSE_ALLOC_FAILED); | 1798 | count_vm_event(THP_COLLAPSE_ALLOC_FAILED); |
1797 | *hpage = ERR_PTR(-ENOMEM); | 1799 | *hpage = ERR_PTR(-ENOMEM); |
1798 | return; | 1800 | return; |
1799 | } | 1801 | } |
1802 | #endif | ||
1803 | |||
1800 | count_vm_event(THP_COLLAPSE_ALLOC); | 1804 | count_vm_event(THP_COLLAPSE_ALLOC); |
1801 | if (unlikely(mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL))) { | 1805 | if (unlikely(mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL))) { |
1802 | up_read(&mm->mmap_sem); | 1806 | #ifdef CONFIG_NUMA |
1803 | put_page(new_page); | 1807 | put_page(new_page); |
1808 | #endif | ||
1804 | return; | 1809 | return; |
1805 | } | 1810 | } |
1806 | #endif | ||
1807 | |||
1808 | /* after allocating the hugepage upgrade to mmap_sem write mode */ | ||
1809 | up_read(&mm->mmap_sem); | ||
1810 | 1811 | ||
1811 | /* | 1812 | /* |
1812 | * Prevent all access to pagetables with the exception of | 1813 | * Prevent all access to pagetables with the exception of |