aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/huge_memory.c43
-rw-r--r--mm/memory.c21
-rw-r--r--mm/mlock.c5
-rw-r--r--mm/mmap.c11
-rw-r--r--mm/oom_kill.c9
-rw-r--r--mm/slub.c4
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
1411int hugepage_madvise(struct vm_area_struct *vma, 1414int 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
1413static inline int stack_guard_page(struct vm_area_struct *vma, unsigned long addr) 1413static 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}
diff --git a/mm/mmap.c b/mm/mmap.c
index e27e0cf0de03..772140c53ab1 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -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 /*
diff --git a/mm/slub.c b/mm/slub.c
index 94d2a33a866e..9d2e5e46bf09 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -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)))) {