Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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"

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