Commit a7d6e4ecdb7648478ddec76d30d87d03d6e22b31
Committed by
Linus Torvalds
1 parent
09f586b35d
Exists in
master
and in
20 other branches
thp: prevent hugepages during args/env copying into the user stack
Transparent hugepages can only be created if rmap is fully functional. So we must prevent hugepages to be created while is_vma_temporary_stack() is true. This also optmizes away some harmless but unnecessary setting of khugepaged_scan.address and it switches some BUG_ON to VM_BUG_ON. Signed-off-by: Andrea Arcangeli <aarcange@redhat.com> Acked-by: Rik van Riel <riel@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 18 additions and 20 deletions Side-by-side Diff
include/linux/huge_mm.h
... | ... | @@ -57,7 +57,8 @@ |
57 | 57 | (transparent_hugepage_flags & \ |
58 | 58 | (1<<TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG) && \ |
59 | 59 | ((__vma)->vm_flags & VM_HUGEPAGE))) && \ |
60 | - !((__vma)->vm_flags & VM_NOHUGEPAGE)) | |
60 | + !((__vma)->vm_flags & VM_NOHUGEPAGE) && \ | |
61 | + !is_vma_temporary_stack(__vma)) | |
61 | 62 | #define transparent_hugepage_defrag(__vma) \ |
62 | 63 | ((transparent_hugepage_flags & \ |
63 | 64 | (1<<TRANSPARENT_HUGEPAGE_DEFRAG_FLAG)) || \ |
mm/huge_memory.c
... | ... | @@ -1811,6 +1811,8 @@ |
1811 | 1811 | /* VM_PFNMAP vmas may have vm_ops null but vm_file set */ |
1812 | 1812 | if (!vma->anon_vma || vma->vm_ops || vma->vm_file) |
1813 | 1813 | goto out; |
1814 | + if (is_vma_temporary_stack(vma)) | |
1815 | + goto out; | |
1814 | 1816 | VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma)); |
1815 | 1817 | |
1816 | 1818 | pgd = pgd_offset(mm, address); |
1817 | 1819 | |
1818 | 1820 | |
1819 | 1821 | |
1820 | 1822 | |
... | ... | @@ -2032,32 +2034,27 @@ |
2032 | 2034 | if ((!(vma->vm_flags & VM_HUGEPAGE) && |
2033 | 2035 | !khugepaged_always()) || |
2034 | 2036 | (vma->vm_flags & VM_NOHUGEPAGE)) { |
2037 | + skip: | |
2035 | 2038 | progress++; |
2036 | 2039 | continue; |
2037 | 2040 | } |
2038 | - | |
2039 | 2041 | /* VM_PFNMAP vmas may have vm_ops null but vm_file set */ |
2040 | - if (!vma->anon_vma || vma->vm_ops || vma->vm_file) { | |
2041 | - khugepaged_scan.address = vma->vm_end; | |
2042 | - progress++; | |
2043 | - continue; | |
2044 | - } | |
2042 | + if (!vma->anon_vma || vma->vm_ops || vma->vm_file) | |
2043 | + goto skip; | |
2044 | + if (is_vma_temporary_stack(vma)) | |
2045 | + goto skip; | |
2046 | + | |
2045 | 2047 | VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma)); |
2046 | 2048 | |
2047 | 2049 | hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; |
2048 | 2050 | hend = vma->vm_end & HPAGE_PMD_MASK; |
2049 | - if (hstart >= hend) { | |
2050 | - progress++; | |
2051 | - continue; | |
2052 | - } | |
2051 | + if (hstart >= hend) | |
2052 | + goto skip; | |
2053 | + if (khugepaged_scan.address > hend) | |
2054 | + goto skip; | |
2053 | 2055 | if (khugepaged_scan.address < hstart) |
2054 | 2056 | khugepaged_scan.address = hstart; |
2055 | - if (khugepaged_scan.address > hend) { | |
2056 | - khugepaged_scan.address = hend + HPAGE_PMD_SIZE; | |
2057 | - progress++; | |
2058 | - continue; | |
2059 | - } | |
2060 | - BUG_ON(khugepaged_scan.address & ~HPAGE_PMD_MASK); | |
2057 | + VM_BUG_ON(khugepaged_scan.address & ~HPAGE_PMD_MASK); | |
2061 | 2058 | |
2062 | 2059 | while (khugepaged_scan.address < hend) { |
2063 | 2060 | int ret; |
... | ... | @@ -2086,7 +2083,7 @@ |
2086 | 2083 | breakouterloop_mmap_sem: |
2087 | 2084 | |
2088 | 2085 | spin_lock(&khugepaged_mm_lock); |
2089 | - BUG_ON(khugepaged_scan.mm_slot != mm_slot); | |
2086 | + VM_BUG_ON(khugepaged_scan.mm_slot != mm_slot); | |
2090 | 2087 | /* |
2091 | 2088 | * Release the current mm_slot if this mm is about to die, or |
2092 | 2089 | * if we scanned all vmas of this mm. |
2093 | 2090 | |
... | ... | @@ -2241,9 +2238,9 @@ |
2241 | 2238 | |
2242 | 2239 | for (;;) { |
2243 | 2240 | mutex_unlock(&khugepaged_mutex); |
2244 | - BUG_ON(khugepaged_thread != current); | |
2241 | + VM_BUG_ON(khugepaged_thread != current); | |
2245 | 2242 | khugepaged_loop(); |
2246 | - BUG_ON(khugepaged_thread != current); | |
2243 | + VM_BUG_ON(khugepaged_thread != current); | |
2247 | 2244 | |
2248 | 2245 | mutex_lock(&khugepaged_mutex); |
2249 | 2246 | if (!khugepaged_enabled()) |