History

Merge branch 'akpm' (patches from Andrew)

Merge misc fixes from Andrew Morton: "10 patches. Subsystems affected by this patch series: ipc, MAINTAINERS, and mm (vmscan, debug, pagemap, kmemleak, and selftests)" * emailed patches from Andrew Morton <akpm@linux-foundation.org>: kselftest/vm: revert "tools/testing/selftests/vm/userfaultfd.c: use swap() to make code cleaner" MAINTAINERS: update rppt's email mm/kmemleak: avoid scanning potential huge holes ipc/sem: do not sleep with a spin lock held mm/pgtable: define pte_index so that preprocessor could recognize it mm/page_table_check: check entries at pmd levels mm/khugepaged: unify collapse pmd clear, flush and free mm/page_table_check: use unsigned long for page counters and cleanup mm/debug_vm_pgtable: remove pte entry from the page table Revert "mm/page_isolation: unset migratetype directly for non Buddy page"

Linus Torvalds committed 4 years ago

Commit f9aaa5b2 parents cff7f22 07d250510 files · +88 −56Browse files

Unified · Split

10 files
  1. MAINTAINERS +1 −1
  2. include/linux/page_table_check.h +19 −0
  3. include/linux/pgtable.h +1 −0
  4. ipc/sem.c +2 −2
  5. mm/debug_vm_pgtable.c +2 −0
  6. mm/khugepaged.c +21 −16
  7. mm/kmemleak.c +7 −6
  8. mm/page_isolation.c +1 −1
  9. mm/page_table_check.c +27 −28
  10. tools/testing/selftests/vm/userfaultfd.c +7 −2
MAINTAINERS+1−1
@@ -12399,7 +12399,7 @@ F: include/uapi/linux/membarrier.h · 12398 unmodified lines
12399F: kernel/sched/membarrier.c12399F: kernel/sched/membarrier.c
12400 12400
12401MEMBLOCK12401MEMBLOCK
12402M: Mike Rapoport <rppt@linux.ibm.com>12402M: Mike Rapoport <rppt@kernel.org>
12403L: linux-mm@kvack.org12403L: linux-mm@kvack.org
12404S: Maintained12404S: Maintained
12405F: Documentation/core-api/boot-time-mm.rst12405F: Documentation/core-api/boot-time-mm.rst
include/linux/page_table_check.h+19−0
@@ -26,6 +26,9 @@ void __page_table_check_pmd_set(struct mm_struct *mm, unsigned long addr, · 25 unmodified lines
26 pmd_t *pmdp, pmd_t pmd);26 pmd_t *pmdp, pmd_t pmd);
27void __page_table_check_pud_set(struct mm_struct *mm, unsigned long addr,27void __page_table_check_pud_set(struct mm_struct *mm, unsigned long addr,
28 pud_t *pudp, pud_t pud);28 pud_t *pudp, pud_t pud);
29void __page_table_check_pte_clear_range(struct mm_struct *mm,
30 unsigned long addr,
31 pmd_t pmd);
29 32
30static inline void page_table_check_alloc(struct page *page, unsigned int order)33static inline void page_table_check_alloc(struct page *page, unsigned int order)
31{34{
@@ -100,6 +103,16 @@ static inline void page_table_check_pud_set(struct mm_struct *mm, · 68 unmodified lines
100 __page_table_check_pud_set(mm, addr, pudp, pud);103 __page_table_check_pud_set(mm, addr, pudp, pud);
101}104}
102 105
106static inline void page_table_check_pte_clear_range(struct mm_struct *mm,
107 unsigned long addr,
108 pmd_t pmd)
109{
110 if (static_branch_likely(&page_table_check_disabled))
111 return;
112
113 __page_table_check_pte_clear_range(mm, addr, pmd);
114}
115
103#else116#else
104 117
105static inline void page_table_check_alloc(struct page *page, unsigned int order)118static inline void page_table_check_alloc(struct page *page, unsigned int order)
@@ -143,5 +156,11 @@ static inline void page_table_check_pud_set(struct mm_struct *mm, · 37 unmodified lines
143{156{
144}157}
145 158
159static inline void page_table_check_pte_clear_range(struct mm_struct *mm,
160 unsigned long addr,
161 pmd_t pmd)
162{
163}
164
146#endif /* CONFIG_PAGE_TABLE_CHECK */165#endif /* CONFIG_PAGE_TABLE_CHECK */
147#endif /* __LINUX_PAGE_TABLE_CHECK_H */166#endif /* __LINUX_PAGE_TABLE_CHECK_H */
include/linux/pgtable.h+1−0
@@ -62,6 +62,7 @@ static inline unsigned long pte_index(unsigned long address) · 61 unmodified lines
62{62{
63 return (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);63 return (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
64}64}
65#define pte_index pte_index
65 66
66#ifndef pmd_index67#ifndef pmd_index
67static inline unsigned long pmd_index(unsigned long address)68static inline unsigned long pmd_index(unsigned long address)
ipc/sem.c+2−2
@@ -1964,6 +1964,7 @@ static struct sem_undo *find_alloc_undo(struct ipc_namespace *ns, int semid) · 1963 unmodified lines
1964 */1964 */
1965 un = lookup_undo(ulp, semid);1965 un = lookup_undo(ulp, semid);
1966 if (un) {1966 if (un) {
1967 spin_unlock(&ulp->lock);
1967 kvfree(new);1968 kvfree(new);
1968 goto success;1969 goto success;
1969 }1970 }
@@ -1976,9 +1977,8 @@ static struct sem_undo *find_alloc_undo(struct ipc_namespace *ns, int semid) · 6 unmodified lines
1976 ipc_assert_locked_object(&sma->sem_perm);1977 ipc_assert_locked_object(&sma->sem_perm);
1977 list_add(&new->list_id, &sma->list_id);1978 list_add(&new->list_id, &sma->list_id);
1978 un = new;1979 un = new;
1979
1980success:
1981 spin_unlock(&ulp->lock);1980 spin_unlock(&ulp->lock);
1981success:
1982 sem_unlock(sma, -1);1982 sem_unlock(sma, -1);
1983out:1983out:
1984 return un;1984 return un;
mm/debug_vm_pgtable.c+2−0
@@ -171,6 +171,8 @@ static void __init pte_advanced_tests(struct pgtable_debug_args *args) · 170 unmodified lines
171 ptep_test_and_clear_young(args->vma, args->vaddr, args->ptep);171 ptep_test_and_clear_young(args->vma, args->vaddr, args->ptep);
172 pte = ptep_get(args->ptep);172 pte = ptep_get(args->ptep);
173 WARN_ON(pte_young(pte));173 WARN_ON(pte_young(pte));
174
175 ptep_get_and_clear_full(args->mm, args->vaddr, args->ptep, 1);
174}176}
175 177
176static void __init pte_savedwrite_tests(struct pgtable_debug_args *args)178static void __init pte_savedwrite_tests(struct pgtable_debug_args *args)
mm/khugepaged.c+21−16
@@ -16,6 +16,7 @@ · 15 unmodified lines
16#include <linux/hashtable.h>16#include <linux/hashtable.h>
17#include <linux/userfaultfd_k.h>17#include <linux/userfaultfd_k.h>
18#include <linux/page_idle.h>18#include <linux/page_idle.h>
19#include <linux/page_table_check.h>
19#include <linux/swapops.h>20#include <linux/swapops.h>
20#include <linux/shmem_fs.h>21#include <linux/shmem_fs.h>
21 22
@@ -1416,6 +1417,21 @@ static int khugepaged_add_pte_mapped_thp(struct mm_struct *mm, · 1394 unmodified lines
1416 return 0;1417 return 0;
1417}1418}
1418 1419
1420static void collapse_and_free_pmd(struct mm_struct *mm, struct vm_area_struct *vma,
1421 unsigned long addr, pmd_t *pmdp)
1422{
1423 spinlock_t *ptl;
1424 pmd_t pmd;
1425
1426 mmap_assert_write_locked(mm);
1427 ptl = pmd_lock(vma->vm_mm, pmdp);
1428 pmd = pmdp_collapse_flush(vma, addr, pmdp);
1429 spin_unlock(ptl);
1430 mm_dec_nr_ptes(mm);
1431 page_table_check_pte_clear_range(mm, addr, pmd);
1432 pte_free(mm, pmd_pgtable(pmd));
1433}
1434
1419/**1435/**
1420 * collapse_pte_mapped_thp - Try to collapse a pte-mapped THP for mm at1436 * collapse_pte_mapped_thp - Try to collapse a pte-mapped THP for mm at
1421 * address haddr.1437 * address haddr.
@@ -1433,7 +1449,7 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr) · 11 unmodified lines
1433 struct vm_area_struct *vma = find_vma(mm, haddr);1449 struct vm_area_struct *vma = find_vma(mm, haddr);
1434 struct page *hpage;1450 struct page *hpage;
1435 pte_t *start_pte, *pte;1451 pte_t *start_pte, *pte;
1436 pmd_t *pmd, _pmd;1452 pmd_t *pmd;
1437 spinlock_t *ptl;1453 spinlock_t *ptl;
1438 int count = 0;1454 int count = 0;
1439 int i;1455 int i;
@@ -1509,12 +1525,7 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr) · 69 unmodified lines
1509 }1525 }
1510 1526
1511 /* step 4: collapse pmd */1527 /* step 4: collapse pmd */
1512 ptl = pmd_lock(vma->vm_mm, pmd);1528 collapse_and_free_pmd(mm, vma, haddr, pmd);
1513 _pmd = pmdp_collapse_flush(vma, haddr, pmd);
1514 spin_unlock(ptl);
1515 mm_dec_nr_ptes(mm);
1516 pte_free(mm, pmd_pgtable(_pmd));
1517
1518drop_hpage:1529drop_hpage:
1519 unlock_page(hpage);1530 unlock_page(hpage);
1520 put_page(hpage);1531 put_page(hpage);
@@ -1552,7 +1563,7 @@ static void retract_page_tables(struct address_space *mapping, pgoff_t pgoff) · 31 unmodified lines
1552 struct vm_area_struct *vma;1563 struct vm_area_struct *vma;
1553 struct mm_struct *mm;1564 struct mm_struct *mm;
1554 unsigned long addr;1565 unsigned long addr;
1555 pmd_t *pmd, _pmd;1566 pmd_t *pmd;
1556 1567
1557 i_mmap_lock_write(mapping);1568 i_mmap_lock_write(mapping);
1558 vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {1569 vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
@@ -1591,14 +1602,8 @@ static void retract_page_tables(struct address_space *mapping, pgoff_t pgoff) · 32 unmodified lines
1591 * reverse order. Trylock is a way to avoid deadlock.1602 * reverse order. Trylock is a way to avoid deadlock.
1592 */1603 */
1593 if (mmap_write_trylock(mm)) {1604 if (mmap_write_trylock(mm)) {
1594 if (!khugepaged_test_exit(mm)) {1605 if (!khugepaged_test_exit(mm))
1595 spinlock_t *ptl = pmd_lock(mm, pmd);1606 collapse_and_free_pmd(mm, vma, addr, pmd);
1596 /* assume page table is clear */
1597 _pmd = pmdp_collapse_flush(vma, addr, pmd);
1598 spin_unlock(ptl);
1599 mm_dec_nr_ptes(mm);
1600 pte_free(mm, pmd_pgtable(_pmd));
1601 }
1602 mmap_write_unlock(mm);1607 mmap_write_unlock(mm);
1603 } else {1608 } else {
1604 /* Try again later */1609 /* Try again later */
mm/kmemleak.c+7−6
@@ -1410,7 +1410,8 @@ static void kmemleak_scan(void) · 1409 unmodified lines
1410{1410{
1411 unsigned long flags;1411 unsigned long flags;
1412 struct kmemleak_object *object;1412 struct kmemleak_object *object;
1413 int i;1413 struct zone *zone;
1414 int __maybe_unused i;
1414 int new_leaks = 0;1415 int new_leaks = 0;
1415 1416
1416 jiffies_last_scan = jiffies;1417 jiffies_last_scan = jiffies;
@@ -1450,9 +1451,9 @@ static void kmemleak_scan(void) · 33 unmodified lines
1450 * Struct page scanning for each node.1451 * Struct page scanning for each node.
1451 */1452 */
1452 get_online_mems();1453 get_online_mems();
1453 for_each_online_node(i) {1454 for_each_populated_zone(zone) {
1454 unsigned long start_pfn = node_start_pfn(i);1455 unsigned long start_pfn = zone->zone_start_pfn;
1455 unsigned long end_pfn = node_end_pfn(i);1456 unsigned long end_pfn = zone_end_pfn(zone);
1456 unsigned long pfn;1457 unsigned long pfn;
1457 1458
1458 for (pfn = start_pfn; pfn < end_pfn; pfn++) {1459 for (pfn = start_pfn; pfn < end_pfn; pfn++) {
@@ -1461,8 +1462,8 @@ static void kmemleak_scan(void) · 2 unmodified lines
1461 if (!page)1462 if (!page)
1462 continue;1463 continue;
1463 1464
1464 /* only scan pages belonging to this node */1465 /* only scan pages belonging to this zone */
1465 if (page_to_nid(page) != i)1466 if (page_zone(page) != zone)
1466 continue;1467 continue;
1467 /* only scan if page is in use */1468 /* only scan if page is in use */
1468 if (page_count(page) == 0)1469 if (page_count(page) == 0)
mm/page_isolation.c+1−1
@@ -115,7 +115,7 @@ static void unset_migratetype_isolate(struct page *page, unsigned migratetype) · 114 unmodified lines
115 * onlining - just onlined memory won't immediately be considered for115 * onlining - just onlined memory won't immediately be considered for
116 * allocation.116 * allocation.
117 */117 */
118 if (!isolated_page && PageBuddy(page)) {118 if (!isolated_page) {
119 nr_pages = move_freepages_block(zone, page, migratetype, NULL);119 nr_pages = move_freepages_block(zone, page, migratetype, NULL);
120 __mod_zone_freepage_state(zone, nr_pages, migratetype);120 __mod_zone_freepage_state(zone, nr_pages, migratetype);
121 }121 }
mm/page_table_check.c+27−28
@@ -86,8 +86,8 @@ static void page_table_check_clear(struct mm_struct *mm, unsigned long addr, · 85 unmodified lines
86{86{
87 struct page_ext *page_ext;87 struct page_ext *page_ext;
88 struct page *page;88 struct page *page;
89 unsigned long i;
89 bool anon;90 bool anon;
90 int i;
91 91
92 if (!pfn_valid(pfn))92 if (!pfn_valid(pfn))
93 return;93 return;
@@ -121,8 +121,8 @@ static void page_table_check_set(struct mm_struct *mm, unsigned long addr, · 27 unmodified lines
121{121{
122 struct page_ext *page_ext;122 struct page_ext *page_ext;
123 struct page *page;123 struct page *page;
124 unsigned long i;
124 bool anon;125 bool anon;
125 int i;
126 126
127 if (!pfn_valid(pfn))127 if (!pfn_valid(pfn))
128 return;128 return;
@@ -152,10 +152,10 @@ static void page_table_check_set(struct mm_struct *mm, unsigned long addr, · 23 unmodified lines
152void __page_table_check_zero(struct page *page, unsigned int order)152void __page_table_check_zero(struct page *page, unsigned int order)
153{153{
154 struct page_ext *page_ext = lookup_page_ext(page);154 struct page_ext *page_ext = lookup_page_ext(page);
155 int i;155 unsigned long i;
156 156
157 BUG_ON(!page_ext);157 BUG_ON(!page_ext);
158 for (i = 0; i < (1 << order); i++) {158 for (i = 0; i < (1ul << order); i++) {
159 struct page_table_check *ptc = get_page_table_check(page_ext);159 struct page_table_check *ptc = get_page_table_check(page_ext);
160 160
161 BUG_ON(atomic_read(&ptc->anon_map_count));161 BUG_ON(atomic_read(&ptc->anon_map_count));
@@ -206,17 +206,10 @@ EXPORT_SYMBOL(__page_table_check_pud_clear); · 44 unmodified lines
206void __page_table_check_pte_set(struct mm_struct *mm, unsigned long addr,206void __page_table_check_pte_set(struct mm_struct *mm, unsigned long addr,
207 pte_t *ptep, pte_t pte)207 pte_t *ptep, pte_t pte)
208{208{
209 pte_t old_pte;
210
211 if (&init_mm == mm)209 if (&init_mm == mm)
212 return;210 return;
213 211
214 old_pte = *ptep;212 __page_table_check_pte_clear(mm, addr, *ptep);
215 if (pte_user_accessible_page(old_pte)) {
216 page_table_check_clear(mm, addr, pte_pfn(old_pte),
217 PAGE_SIZE >> PAGE_SHIFT);
218 }
219
220 if (pte_user_accessible_page(pte)) {213 if (pte_user_accessible_page(pte)) {
221 page_table_check_set(mm, addr, pte_pfn(pte),214 page_table_check_set(mm, addr, pte_pfn(pte),
222 PAGE_SIZE >> PAGE_SHIFT,215 PAGE_SIZE >> PAGE_SHIFT,
@@ -228,17 +221,10 @@ EXPORT_SYMBOL(__page_table_check_pte_set); · 5 unmodified lines
228void __page_table_check_pmd_set(struct mm_struct *mm, unsigned long addr,221void __page_table_check_pmd_set(struct mm_struct *mm, unsigned long addr,
229 pmd_t *pmdp, pmd_t pmd)222 pmd_t *pmdp, pmd_t pmd)
230{223{
231 pmd_t old_pmd;
232
233 if (&init_mm == mm)224 if (&init_mm == mm)
234 return;225 return;
235 226
236 old_pmd = *pmdp;227 __page_table_check_pmd_clear(mm, addr, *pmdp);
237 if (pmd_user_accessible_page(old_pmd)) {
238 page_table_check_clear(mm, addr, pmd_pfn(old_pmd),
239 PMD_PAGE_SIZE >> PAGE_SHIFT);
240 }
241
242 if (pmd_user_accessible_page(pmd)) {228 if (pmd_user_accessible_page(pmd)) {
243 page_table_check_set(mm, addr, pmd_pfn(pmd),229 page_table_check_set(mm, addr, pmd_pfn(pmd),
244 PMD_PAGE_SIZE >> PAGE_SHIFT,230 PMD_PAGE_SIZE >> PAGE_SHIFT,
@@ -250,17 +236,10 @@ EXPORT_SYMBOL(__page_table_check_pmd_set); · 5 unmodified lines
250void __page_table_check_pud_set(struct mm_struct *mm, unsigned long addr,236void __page_table_check_pud_set(struct mm_struct *mm, unsigned long addr,
251 pud_t *pudp, pud_t pud)237 pud_t *pudp, pud_t pud)
252{238{
253 pud_t old_pud;
254
255 if (&init_mm == mm)239 if (&init_mm == mm)
256 return;240 return;
257 241
258 old_pud = *pudp;242 __page_table_check_pud_clear(mm, addr, *pudp);
259 if (pud_user_accessible_page(old_pud)) {
260 page_table_check_clear(mm, addr, pud_pfn(old_pud),
261 PUD_PAGE_SIZE >> PAGE_SHIFT);
262 }
263
264 if (pud_user_accessible_page(pud)) {243 if (pud_user_accessible_page(pud)) {
265 page_table_check_set(mm, addr, pud_pfn(pud),244 page_table_check_set(mm, addr, pud_pfn(pud),
266 PUD_PAGE_SIZE >> PAGE_SHIFT,245 PUD_PAGE_SIZE >> PAGE_SHIFT,
@@ -268,3 +247,23 @@ void __page_table_check_pud_set(struct mm_struct *mm, unsigned long addr, · 1 unmodified line
268 }247 }
269}248}
270EXPORT_SYMBOL(__page_table_check_pud_set);249EXPORT_SYMBOL(__page_table_check_pud_set);
250
251void __page_table_check_pte_clear_range(struct mm_struct *mm,
252 unsigned long addr,
253 pmd_t pmd)
254{
255 if (&init_mm == mm)
256 return;
257
258 if (!pmd_bad(pmd) && !pmd_leaf(pmd)) {
259 pte_t *ptep = pte_offset_map(&pmd, addr);
260 unsigned long i;
261
262 pte_unmap(ptep);
263 for (i = 0; i < PTRS_PER_PTE; i++) {
264 __page_table_check_pte_clear(mm, addr, *ptep);
265 addr += PAGE_SIZE;
266 ptep++;
267 }
268 }
269}
tools/testing/selftests/vm/userfaultfd.c+7−2
@@ -1417,6 +1417,7 @@ static void userfaultfd_pagemap_test(unsigned int test_pgsize) · 1416 unmodified lines
1417static int userfaultfd_stress(void)1417static int userfaultfd_stress(void)
1418{1418{
1419 void *area;1419 void *area;
1420 char *tmp_area;
1420 unsigned long nr;1421 unsigned long nr;
1421 struct uffdio_register uffdio_register;1422 struct uffdio_register uffdio_register;
1422 struct uffd_stats uffd_stats[nr_cpus];1423 struct uffd_stats uffd_stats[nr_cpus];
@@ -1527,9 +1528,13 @@ static int userfaultfd_stress(void) · 104 unmodified lines
1527 count_verify[nr], nr);1528 count_verify[nr], nr);
1528 1529
1529 /* prepare next bounce */1530 /* prepare next bounce */
1530 swap(area_src, area_dst);1531 tmp_area = area_src;
1532 area_src = area_dst;
1533 area_dst = tmp_area;
1531 1534
1532 swap(area_src_alias, area_dst_alias);1535 tmp_area = area_src_alias;
1536 area_src_alias = area_dst_alias;
1537 area_dst_alias = tmp_area;
1533 1538
1534 uffd_stats_report(uffd_stats, nr_cpus);1539 uffd_stats_report(uffd_stats, nr_cpus);
1535 }1540 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t