diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/huge_memory.c | 43 | ||||
-rw-r--r-- | mm/memory.c | 21 | ||||
-rw-r--r-- | mm/mlock.c | 5 | ||||
-rw-r--r-- | mm/mmap.c | 11 | ||||
-rw-r--r-- | mm/oom_kill.c | 9 | ||||
-rw-r--r-- | mm/slub.c | 4 |
6 files changed, 49 insertions, 44 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 470dcda10add..83326ad66d9b 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
@@ -1408,6 +1408,9 @@ out: | |||
1408 | return ret; | 1408 | return ret; |
1409 | } | 1409 | } |
1410 | 1410 | ||
1411 | #define VM_NO_THP (VM_SPECIAL|VM_INSERTPAGE|VM_MIXEDMAP|VM_SAO| \ | ||
1412 | VM_HUGETLB|VM_SHARED|VM_MAYSHARE) | ||
1413 | |||
1411 | int hugepage_madvise(struct vm_area_struct *vma, | 1414 | int hugepage_madvise(struct vm_area_struct *vma, |
1412 | unsigned long *vm_flags, int advice) | 1415 | unsigned long *vm_flags, int advice) |
1413 | { | 1416 | { |
@@ -1416,11 +1419,7 @@ int hugepage_madvise(struct vm_area_struct *vma, | |||
1416 | /* | 1419 | /* |
1417 | * Be somewhat over-protective like KSM for now! | 1420 | * Be somewhat over-protective like KSM for now! |
1418 | */ | 1421 | */ |
1419 | if (*vm_flags & (VM_HUGEPAGE | | 1422 | if (*vm_flags & (VM_HUGEPAGE | VM_NO_THP)) |
1420 | VM_SHARED | VM_MAYSHARE | | ||
1421 | VM_PFNMAP | VM_IO | VM_DONTEXPAND | | ||
1422 | VM_RESERVED | VM_HUGETLB | VM_INSERTPAGE | | ||
1423 | VM_MIXEDMAP | VM_SAO)) | ||
1424 | return -EINVAL; | 1423 | return -EINVAL; |
1425 | *vm_flags &= ~VM_NOHUGEPAGE; | 1424 | *vm_flags &= ~VM_NOHUGEPAGE; |
1426 | *vm_flags |= VM_HUGEPAGE; | 1425 | *vm_flags |= VM_HUGEPAGE; |
@@ -1436,11 +1435,7 @@ int hugepage_madvise(struct vm_area_struct *vma, | |||
1436 | /* | 1435 | /* |
1437 | * Be somewhat over-protective like KSM for now! | 1436 | * Be somewhat over-protective like KSM for now! |
1438 | */ | 1437 | */ |
1439 | if (*vm_flags & (VM_NOHUGEPAGE | | 1438 | if (*vm_flags & (VM_NOHUGEPAGE | VM_NO_THP)) |
1440 | VM_SHARED | VM_MAYSHARE | | ||
1441 | VM_PFNMAP | VM_IO | VM_DONTEXPAND | | ||
1442 | VM_RESERVED | VM_HUGETLB | VM_INSERTPAGE | | ||
1443 | VM_MIXEDMAP | VM_SAO)) | ||
1444 | return -EINVAL; | 1439 | return -EINVAL; |
1445 | *vm_flags &= ~VM_HUGEPAGE; | 1440 | *vm_flags &= ~VM_HUGEPAGE; |
1446 | *vm_flags |= VM_NOHUGEPAGE; | 1441 | *vm_flags |= VM_NOHUGEPAGE; |
@@ -1574,10 +1569,14 @@ int khugepaged_enter_vma_merge(struct vm_area_struct *vma) | |||
1574 | * page fault if needed. | 1569 | * page fault if needed. |
1575 | */ | 1570 | */ |
1576 | return 0; | 1571 | return 0; |
1577 | if (vma->vm_file || vma->vm_ops) | 1572 | if (vma->vm_ops) |
1578 | /* khugepaged not yet working on file or special mappings */ | 1573 | /* khugepaged not yet working on file or special mappings */ |
1579 | return 0; | 1574 | return 0; |
1580 | VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma)); | 1575 | /* |
1576 | * If is_pfn_mapping() is true is_learn_pfn_mapping() must be | ||
1577 | * true too, verify it here. | ||
1578 | */ | ||
1579 | VM_BUG_ON(is_linear_pfn_mapping(vma) || vma->vm_flags & VM_NO_THP); | ||
1581 | hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; | 1580 | hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; |
1582 | hend = vma->vm_end & HPAGE_PMD_MASK; | 1581 | hend = vma->vm_end & HPAGE_PMD_MASK; |
1583 | if (hstart < hend) | 1582 | if (hstart < hend) |
@@ -1828,12 +1827,15 @@ static void collapse_huge_page(struct mm_struct *mm, | |||
1828 | (vma->vm_flags & VM_NOHUGEPAGE)) | 1827 | (vma->vm_flags & VM_NOHUGEPAGE)) |
1829 | goto out; | 1828 | goto out; |
1830 | 1829 | ||
1831 | /* VM_PFNMAP vmas may have vm_ops null but vm_file set */ | 1830 | if (!vma->anon_vma || vma->vm_ops) |
1832 | if (!vma->anon_vma || vma->vm_ops || vma->vm_file) | ||
1833 | goto out; | 1831 | goto out; |
1834 | if (is_vma_temporary_stack(vma)) | 1832 | if (is_vma_temporary_stack(vma)) |
1835 | goto out; | 1833 | goto out; |
1836 | VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma)); | 1834 | /* |
1835 | * If is_pfn_mapping() is true is_learn_pfn_mapping() must be | ||
1836 | * true too, verify it here. | ||
1837 | */ | ||
1838 | VM_BUG_ON(is_linear_pfn_mapping(vma) || vma->vm_flags & VM_NO_THP); | ||
1837 | 1839 | ||
1838 | pgd = pgd_offset(mm, address); | 1840 | pgd = pgd_offset(mm, address); |
1839 | if (!pgd_present(*pgd)) | 1841 | if (!pgd_present(*pgd)) |
@@ -2066,13 +2068,16 @@ static unsigned int khugepaged_scan_mm_slot(unsigned int pages, | |||
2066 | progress++; | 2068 | progress++; |
2067 | continue; | 2069 | continue; |
2068 | } | 2070 | } |
2069 | /* VM_PFNMAP vmas may have vm_ops null but vm_file set */ | 2071 | if (!vma->anon_vma || vma->vm_ops) |
2070 | if (!vma->anon_vma || vma->vm_ops || vma->vm_file) | ||
2071 | goto skip; | 2072 | goto skip; |
2072 | if (is_vma_temporary_stack(vma)) | 2073 | if (is_vma_temporary_stack(vma)) |
2073 | goto skip; | 2074 | goto skip; |
2074 | 2075 | /* | |
2075 | VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma)); | 2076 | * If is_pfn_mapping() is true is_learn_pfn_mapping() |
2077 | * must be true too, verify it here. | ||
2078 | */ | ||
2079 | VM_BUG_ON(is_linear_pfn_mapping(vma) || | ||
2080 | vma->vm_flags & VM_NO_THP); | ||
2076 | 2081 | ||
2077 | hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; | 2082 | hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; |
2078 | hend = vma->vm_end & HPAGE_PMD_MASK; | 2083 | hend = vma->vm_end & HPAGE_PMD_MASK; |
diff --git a/mm/memory.c b/mm/memory.c index ce22a250926f..61e66f026563 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -1359,7 +1359,7 @@ split_fallthrough: | |||
1359 | */ | 1359 | */ |
1360 | mark_page_accessed(page); | 1360 | mark_page_accessed(page); |
1361 | } | 1361 | } |
1362 | if (flags & FOLL_MLOCK) { | 1362 | if ((flags & FOLL_MLOCK) && (vma->vm_flags & VM_LOCKED)) { |
1363 | /* | 1363 | /* |
1364 | * The preliminary mapping check is mainly to avoid the | 1364 | * The preliminary mapping check is mainly to avoid the |
1365 | * pointless overhead of lock_page on the ZERO_PAGE | 1365 | * pointless overhead of lock_page on the ZERO_PAGE |
@@ -1412,9 +1412,8 @@ no_page_table: | |||
1412 | 1412 | ||
1413 | static inline int stack_guard_page(struct vm_area_struct *vma, unsigned long addr) | 1413 | static inline int stack_guard_page(struct vm_area_struct *vma, unsigned long addr) |
1414 | { | 1414 | { |
1415 | return (vma->vm_flags & VM_GROWSDOWN) && | 1415 | return stack_guard_page_start(vma, addr) || |
1416 | (vma->vm_start == addr) && | 1416 | stack_guard_page_end(vma, addr+PAGE_SIZE); |
1417 | !vma_stack_continue(vma->vm_prev, addr); | ||
1418 | } | 1417 | } |
1419 | 1418 | ||
1420 | /** | 1419 | /** |
@@ -1551,13 +1550,6 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
1551 | continue; | 1550 | continue; |
1552 | } | 1551 | } |
1553 | 1552 | ||
1554 | /* | ||
1555 | * If we don't actually want the page itself, | ||
1556 | * and it's the stack guard page, just skip it. | ||
1557 | */ | ||
1558 | if (!pages && stack_guard_page(vma, start)) | ||
1559 | goto next_page; | ||
1560 | |||
1561 | do { | 1553 | do { |
1562 | struct page *page; | 1554 | struct page *page; |
1563 | unsigned int foll_flags = gup_flags; | 1555 | unsigned int foll_flags = gup_flags; |
@@ -1574,6 +1566,11 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
1574 | int ret; | 1566 | int ret; |
1575 | unsigned int fault_flags = 0; | 1567 | unsigned int fault_flags = 0; |
1576 | 1568 | ||
1569 | /* For mlock, just skip the stack guard page. */ | ||
1570 | if (foll_flags & FOLL_MLOCK) { | ||
1571 | if (stack_guard_page(vma, start)) | ||
1572 | goto next_page; | ||
1573 | } | ||
1577 | if (foll_flags & FOLL_WRITE) | 1574 | if (foll_flags & FOLL_WRITE) |
1578 | fault_flags |= FAULT_FLAG_WRITE; | 1575 | fault_flags |= FAULT_FLAG_WRITE; |
1579 | if (nonblocking) | 1576 | if (nonblocking) |
@@ -3396,7 +3393,7 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
3396 | * run pte_offset_map on the pmd, if an huge pmd could | 3393 | * run pte_offset_map on the pmd, if an huge pmd could |
3397 | * materialize from under us from a different thread. | 3394 | * materialize from under us from a different thread. |
3398 | */ | 3395 | */ |
3399 | if (unlikely(__pte_alloc(mm, vma, pmd, address))) | 3396 | if (unlikely(pmd_none(*pmd)) && __pte_alloc(mm, vma, pmd, address)) |
3400 | return VM_FAULT_OOM; | 3397 | return VM_FAULT_OOM; |
3401 | /* if an huge pmd materialized from under us just retry later */ | 3398 | /* if an huge pmd materialized from under us just retry later */ |
3402 | if (unlikely(pmd_trans_huge(*pmd))) | 3399 | if (unlikely(pmd_trans_huge(*pmd))) |
diff --git a/mm/mlock.c b/mm/mlock.c index 6b55e3efe0df..516b2c2ddd5a 100644 --- a/mm/mlock.c +++ b/mm/mlock.c | |||
@@ -162,7 +162,7 @@ static long __mlock_vma_pages_range(struct vm_area_struct *vma, | |||
162 | VM_BUG_ON(end > vma->vm_end); | 162 | VM_BUG_ON(end > vma->vm_end); |
163 | VM_BUG_ON(!rwsem_is_locked(&mm->mmap_sem)); | 163 | VM_BUG_ON(!rwsem_is_locked(&mm->mmap_sem)); |
164 | 164 | ||
165 | gup_flags = FOLL_TOUCH; | 165 | gup_flags = FOLL_TOUCH | FOLL_MLOCK; |
166 | /* | 166 | /* |
167 | * We want to touch writable mappings with a write fault in order | 167 | * We want to touch writable mappings with a write fault in order |
168 | * to break COW, except for shared mappings because these don't COW | 168 | * to break COW, except for shared mappings because these don't COW |
@@ -178,9 +178,6 @@ static long __mlock_vma_pages_range(struct vm_area_struct *vma, | |||
178 | if (vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)) | 178 | if (vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)) |
179 | gup_flags |= FOLL_FORCE; | 179 | gup_flags |= FOLL_FORCE; |
180 | 180 | ||
181 | if (vma->vm_flags & VM_LOCKED) | ||
182 | gup_flags |= FOLL_MLOCK; | ||
183 | |||
184 | return __get_user_pages(current, mm, addr, nr_pages, gup_flags, | 181 | return __get_user_pages(current, mm, addr, nr_pages, gup_flags, |
185 | NULL, NULL, nonblocking); | 182 | NULL, NULL, nonblocking); |
186 | } | 183 | } |
@@ -1767,10 +1767,13 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address) | |||
1767 | size = address - vma->vm_start; | 1767 | size = address - vma->vm_start; |
1768 | grow = (address - vma->vm_end) >> PAGE_SHIFT; | 1768 | grow = (address - vma->vm_end) >> PAGE_SHIFT; |
1769 | 1769 | ||
1770 | error = acct_stack_growth(vma, size, grow); | 1770 | error = -ENOMEM; |
1771 | if (!error) { | 1771 | if (vma->vm_pgoff + (size >> PAGE_SHIFT) >= vma->vm_pgoff) { |
1772 | vma->vm_end = address; | 1772 | error = acct_stack_growth(vma, size, grow); |
1773 | perf_event_mmap(vma); | 1773 | if (!error) { |
1774 | vma->vm_end = address; | ||
1775 | perf_event_mmap(vma); | ||
1776 | } | ||
1774 | } | 1777 | } |
1775 | } | 1778 | } |
1776 | vma_unlock_anon_vma(vma); | 1779 | vma_unlock_anon_vma(vma); |
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 83fb72c108b7..f52e85c80e8d 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -172,10 +172,13 @@ unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *mem, | |||
172 | 172 | ||
173 | /* | 173 | /* |
174 | * The baseline for the badness score is the proportion of RAM that each | 174 | * The baseline for the badness score is the proportion of RAM that each |
175 | * task's rss and swap space use. | 175 | * task's rss, pagetable and swap space use. |
176 | */ | 176 | */ |
177 | points = (get_mm_rss(p->mm) + get_mm_counter(p->mm, MM_SWAPENTS)) * 1000 / | 177 | points = get_mm_rss(p->mm) + p->mm->nr_ptes; |
178 | totalpages; | 178 | points += get_mm_counter(p->mm, MM_SWAPENTS); |
179 | |||
180 | points *= 1000; | ||
181 | points /= totalpages; | ||
179 | task_unlock(p); | 182 | task_unlock(p); |
180 | 183 | ||
181 | /* | 184 | /* |
@@ -1940,7 +1940,7 @@ redo: | |||
1940 | * Since this is without lock semantics the protection is only against | 1940 | * Since this is without lock semantics the protection is only against |
1941 | * code executing on this cpu *not* from access by other cpus. | 1941 | * code executing on this cpu *not* from access by other cpus. |
1942 | */ | 1942 | */ |
1943 | if (unlikely(!this_cpu_cmpxchg_double( | 1943 | if (unlikely(!irqsafe_cpu_cmpxchg_double( |
1944 | s->cpu_slab->freelist, s->cpu_slab->tid, | 1944 | s->cpu_slab->freelist, s->cpu_slab->tid, |
1945 | object, tid, | 1945 | object, tid, |
1946 | get_freepointer(s, object), next_tid(tid)))) { | 1946 | get_freepointer(s, object), next_tid(tid)))) { |
@@ -2145,7 +2145,7 @@ redo: | |||
2145 | set_freepointer(s, object, c->freelist); | 2145 | set_freepointer(s, object, c->freelist); |
2146 | 2146 | ||
2147 | #ifdef CONFIG_CMPXCHG_LOCAL | 2147 | #ifdef CONFIG_CMPXCHG_LOCAL |
2148 | if (unlikely(!this_cpu_cmpxchg_double( | 2148 | if (unlikely(!irqsafe_cpu_cmpxchg_double( |
2149 | s->cpu_slab->freelist, s->cpu_slab->tid, | 2149 | s->cpu_slab->freelist, s->cpu_slab->tid, |
2150 | c->freelist, tid, | 2150 | c->freelist, tid, |
2151 | object, next_tid(tid)))) { | 2151 | object, next_tid(tid)))) { |