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

merge mm-hotfixes-stable into mm-stable to pick up depended-upon changes

+335 -107
+1
MAINTAINERS
··· 12474 12474 12475 12475 MAPLE TREE 12476 12476 M: Liam R. Howlett <Liam.Howlett@oracle.com> 12477 + L: maple-tree@lists.infradead.org 12477 12478 L: linux-mm@kvack.org 12478 12479 S: Supported 12479 12480 F: Documentation/core-api/maple_tree.rst
+1
arch/powerpc/mm/book3s64/subpage_prot.c
··· 145 145 146 146 static const struct mm_walk_ops subpage_walk_ops = { 147 147 .pmd_entry = subpage_walk_pmd_entry, 148 + .walk_lock = PGWALK_WRLOCK_VERIFY, 148 149 }; 149 150 150 151 static void subpage_mark_vma_nohuge(struct mm_struct *mm, unsigned long addr,
+1
arch/riscv/mm/pageattr.c
··· 102 102 .pmd_entry = pageattr_pmd_entry, 103 103 .pte_entry = pageattr_pte_entry, 104 104 .pte_hole = pageattr_pte_hole, 105 + .walk_lock = PGWALK_RDLOCK, 105 106 }; 106 107 107 108 static int __set_memory(unsigned long addr, int numpages, pgprot_t set_mask,
+5
arch/s390/mm/gmap.c
··· 2514 2514 2515 2515 static const struct mm_walk_ops thp_split_walk_ops = { 2516 2516 .pmd_entry = thp_split_walk_pmd_entry, 2517 + .walk_lock = PGWALK_WRLOCK_VERIFY, 2517 2518 }; 2518 2519 2519 2520 static inline void thp_split_mm(struct mm_struct *mm) ··· 2566 2565 2567 2566 static const struct mm_walk_ops zap_zero_walk_ops = { 2568 2567 .pmd_entry = __zap_zero_pages, 2568 + .walk_lock = PGWALK_WRLOCK, 2569 2569 }; 2570 2570 2571 2571 /* ··· 2657 2655 .hugetlb_entry = __s390_enable_skey_hugetlb, 2658 2656 .pte_entry = __s390_enable_skey_pte, 2659 2657 .pmd_entry = __s390_enable_skey_pmd, 2658 + .walk_lock = PGWALK_WRLOCK, 2660 2659 }; 2661 2660 2662 2661 int s390_enable_skey(void) ··· 2695 2692 2696 2693 static const struct mm_walk_ops reset_cmma_walk_ops = { 2697 2694 .pte_entry = __s390_reset_cmma, 2695 + .walk_lock = PGWALK_WRLOCK, 2698 2696 }; 2699 2697 2700 2698 void s390_reset_cmma(struct mm_struct *mm) ··· 2732 2728 2733 2729 static const struct mm_walk_ops gather_pages_ops = { 2734 2730 .pte_entry = s390_gather_pages, 2731 + .walk_lock = PGWALK_RDLOCK, 2735 2732 }; 2736 2733 2737 2734 /*
+8
fs/nilfs2/inode.c
··· 1101 1101 1102 1102 int __nilfs_mark_inode_dirty(struct inode *inode, int flags) 1103 1103 { 1104 + struct the_nilfs *nilfs = inode->i_sb->s_fs_info; 1104 1105 struct buffer_head *ibh; 1105 1106 int err; 1107 + 1108 + /* 1109 + * Do not dirty inodes after the log writer has been detached 1110 + * and its nilfs_root struct has been freed. 1111 + */ 1112 + if (unlikely(nilfs_purging(nilfs))) 1113 + return 0; 1106 1114 1107 1115 err = nilfs_load_inode_block(inode, &ibh); 1108 1116 if (unlikely(err)) {
+7
fs/nilfs2/segment.c
··· 725 725 struct folio *folio = fbatch.folios[i]; 726 726 727 727 folio_lock(folio); 728 + if (unlikely(folio->mapping != mapping)) { 729 + /* Exclude folios removed from the address space */ 730 + folio_unlock(folio); 731 + continue; 732 + } 728 733 head = folio_buffers(folio); 729 734 if (!head) { 730 735 create_empty_buffers(&folio->page, i_blocksize(inode), 0); ··· 2850 2845 nilfs_segctor_destroy(nilfs->ns_writer); 2851 2846 nilfs->ns_writer = NULL; 2852 2847 } 2848 + set_nilfs_purging(nilfs); 2853 2849 2854 2850 /* Force to free the list of dirty files */ 2855 2851 spin_lock(&nilfs->ns_inode_lock); ··· 2863 2857 up_write(&nilfs->ns_segctor_sem); 2864 2858 2865 2859 nilfs_dispose_list(nilfs, &garbage_list, 1); 2860 + clear_nilfs_purging(nilfs); 2866 2861 }
+2
fs/nilfs2/the_nilfs.h
··· 29 29 THE_NILFS_DISCONTINUED, /* 'next' pointer chain has broken */ 30 30 THE_NILFS_GC_RUNNING, /* gc process is running */ 31 31 THE_NILFS_SB_DIRTY, /* super block is dirty */ 32 + THE_NILFS_PURGING, /* disposing dirty files for cleanup */ 32 33 }; 33 34 34 35 /** ··· 209 208 THE_NILFS_FNS(DISCONTINUED, discontinued) 210 209 THE_NILFS_FNS(GC_RUNNING, gc_running) 211 210 THE_NILFS_FNS(SB_DIRTY, sb_dirty) 211 + THE_NILFS_FNS(PURGING, purging) 212 212 213 213 /* 214 214 * Mount option operations
+27 -3
fs/proc/kcore.c
··· 309 309 310 310 static ssize_t read_kcore_iter(struct kiocb *iocb, struct iov_iter *iter) 311 311 { 312 + struct file *file = iocb->ki_filp; 313 + char *buf = file->private_data; 312 314 loff_t *fpos = &iocb->ki_pos; 313 315 size_t phdrs_offset, notes_offset, data_offset; 314 316 size_t page_offline_frozen = 1; ··· 557 555 case KCORE_VMEMMAP: 558 556 case KCORE_TEXT: 559 557 /* 560 - * We use _copy_to_iter() to bypass usermode hardening 561 - * which would otherwise prevent this operation. 558 + * Sadly we must use a bounce buffer here to be able to 559 + * make use of copy_from_kernel_nofault(), as these 560 + * memory regions might not always be mapped on all 561 + * architectures. 562 562 */ 563 - if (_copy_to_iter((char *)start, tsz, iter) != tsz) { 563 + if (copy_from_kernel_nofault(buf, (void *)start, tsz)) { 564 + if (iov_iter_zero(tsz, iter) != tsz) { 565 + ret = -EFAULT; 566 + goto out; 567 + } 568 + /* 569 + * We know the bounce buffer is safe to copy from, so 570 + * use _copy_to_iter() directly. 571 + */ 572 + } else if (_copy_to_iter(buf, tsz, iter) != tsz) { 564 573 ret = -EFAULT; 565 574 goto out; 566 575 } ··· 608 595 if (ret) 609 596 return ret; 610 597 598 + filp->private_data = kmalloc(PAGE_SIZE, GFP_KERNEL); 599 + if (!filp->private_data) 600 + return -ENOMEM; 601 + 611 602 if (kcore_need_update) 612 603 kcore_update_ram(); 613 604 if (i_size_read(inode) != proc_root_kcore->size) { ··· 622 605 return 0; 623 606 } 624 607 608 + static int release_kcore(struct inode *inode, struct file *file) 609 + { 610 + kfree(file->private_data); 611 + return 0; 612 + } 613 + 625 614 static const struct proc_ops kcore_proc_ops = { 626 615 .proc_read_iter = read_kcore_iter, 627 616 .proc_open = open_kcore, 617 + .proc_release = release_kcore, 628 618 .proc_lseek = default_llseek, 629 619 }; 630 620
+6 -2
fs/proc/task_mmu.c
··· 571 571 bool migration = false; 572 572 573 573 if (pmd_present(*pmd)) { 574 - /* FOLL_DUMP will return -EFAULT on huge zero page */ 575 - page = follow_trans_huge_pmd(vma, addr, pmd, FOLL_DUMP); 574 + page = vm_normal_page_pmd(vma, addr, *pmd); 576 575 } else if (unlikely(thp_migration_supported() && is_swap_pmd(*pmd))) { 577 576 swp_entry_t entry = pmd_to_swp_entry(*pmd); 578 577 ··· 741 742 static const struct mm_walk_ops smaps_walk_ops = { 742 743 .pmd_entry = smaps_pte_range, 743 744 .hugetlb_entry = smaps_hugetlb_range, 745 + .walk_lock = PGWALK_RDLOCK, 744 746 }; 745 747 746 748 static const struct mm_walk_ops smaps_shmem_walk_ops = { 747 749 .pmd_entry = smaps_pte_range, 748 750 .hugetlb_entry = smaps_hugetlb_range, 749 751 .pte_hole = smaps_pte_hole, 752 + .walk_lock = PGWALK_RDLOCK, 750 753 }; 751 754 752 755 /* ··· 1230 1229 static const struct mm_walk_ops clear_refs_walk_ops = { 1231 1230 .pmd_entry = clear_refs_pte_range, 1232 1231 .test_walk = clear_refs_test_walk, 1232 + .walk_lock = PGWALK_WRLOCK, 1233 1233 }; 1234 1234 1235 1235 static ssize_t clear_refs_write(struct file *file, const char __user *buf, ··· 1608 1606 .pmd_entry = pagemap_pmd_range, 1609 1607 .pte_hole = pagemap_pte_hole, 1610 1608 .hugetlb_entry = pagemap_hugetlb_range, 1609 + .walk_lock = PGWALK_RDLOCK, 1611 1610 }; 1612 1611 1613 1612 /* ··· 1922 1919 static const struct mm_walk_ops show_numa_ops = { 1923 1920 .hugetlb_entry = gather_hugetlb_stats, 1924 1921 .pmd_entry = gather_pte_stats, 1922 + .walk_lock = PGWALK_RDLOCK, 1925 1923 }; 1926 1924 1927 1925 /*
-3
include/linux/huge_mm.h
··· 25 25 #endif 26 26 27 27 vm_fault_t do_huge_pmd_wp_page(struct vm_fault *vmf); 28 - struct page *follow_trans_huge_pmd(struct vm_area_struct *vma, 29 - unsigned long addr, pmd_t *pmd, 30 - unsigned int flags); 31 28 bool madvise_free_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, 32 29 pmd_t *pmd, unsigned long addr, unsigned long next); 33 30 int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, pmd_t *pmd,
+15 -6
include/linux/mm.h
··· 3496 3496 * Indicates whether GUP can follow a PROT_NONE mapped page, or whether 3497 3497 * a (NUMA hinting) fault is required. 3498 3498 */ 3499 - static inline bool gup_can_follow_protnone(unsigned int flags) 3499 + static inline bool gup_can_follow_protnone(struct vm_area_struct *vma, 3500 + unsigned int flags) 3500 3501 { 3501 3502 /* 3502 - * FOLL_FORCE has to be able to make progress even if the VMA is 3503 - * inaccessible. Further, FOLL_FORCE access usually does not represent 3504 - * application behaviour and we should avoid triggering NUMA hinting 3505 - * faults. 3503 + * If callers don't want to honor NUMA hinting faults, no need to 3504 + * determine if we would actually have to trigger a NUMA hinting fault. 3506 3505 */ 3507 - return flags & FOLL_FORCE; 3506 + if (!(flags & FOLL_HONOR_NUMA_FAULT)) 3507 + return true; 3508 + 3509 + /* 3510 + * NUMA hinting faults don't apply in inaccessible (PROT_NONE) VMAs. 3511 + * 3512 + * Requiring a fault here even for inaccessible VMAs would mean that 3513 + * FOLL_FORCE cannot make any progress, because handle_mm_fault() 3514 + * refuses to process NUMA hinting faults in inaccessible VMAs. 3515 + */ 3516 + return !vma_is_accessible(vma); 3508 3517 } 3509 3518 3510 3519 typedef int (*pte_fn_t)(pte_t *pte, unsigned long addr, void *data);
+9
include/linux/mm_types.h
··· 1356 1356 FOLL_PCI_P2PDMA = 1 << 10, 1357 1357 /* allow interrupts from generic signals */ 1358 1358 FOLL_INTERRUPTIBLE = 1 << 11, 1359 + /* 1360 + * Always honor (trigger) NUMA hinting faults. 1361 + * 1362 + * FOLL_WRITE implicitly honors NUMA hinting faults because a 1363 + * PROT_NONE-mapped page is not writable (exceptions with FOLL_FORCE 1364 + * apply). get_user_pages_fast_only() always implicitly honors NUMA 1365 + * hinting faults. 1366 + */ 1367 + FOLL_HONOR_NUMA_FAULT = 1 << 12, 1359 1368 1360 1369 /* See also internal only FOLL flags in mm/internal.h */ 1361 1370 };
+11
include/linux/pagewalk.h
··· 6 6 7 7 struct mm_walk; 8 8 9 + /* Locking requirement during a page walk. */ 10 + enum page_walk_lock { 11 + /* mmap_lock should be locked for read to stabilize the vma tree */ 12 + PGWALK_RDLOCK = 0, 13 + /* vma will be write-locked during the walk */ 14 + PGWALK_WRLOCK = 1, 15 + /* vma is expected to be already write-locked during the walk */ 16 + PGWALK_WRLOCK_VERIFY = 2, 17 + }; 18 + 9 19 /** 10 20 * struct mm_walk_ops - callbacks for walk_page_range 11 21 * @pgd_entry: if set, called for each non-empty PGD (top-level) entry ··· 76 66 int (*pre_vma)(unsigned long start, unsigned long end, 77 67 struct mm_walk *walk); 78 68 void (*post_vma)(struct mm_walk *walk); 69 + enum page_walk_lock walk_lock; 79 70 }; 80 71 81 72 /*
-1
lib/radix-tree.c
··· 1136 1136 void __rcu **radix_tree_iter_resume(void __rcu **slot, 1137 1137 struct radix_tree_iter *iter) 1138 1138 { 1139 - slot++; 1140 1139 iter->index = __radix_tree_iter_add(iter, 1); 1141 1140 iter->next_index = iter->index; 1142 1141 iter->tags = 0;
+1 -1
lib/scatterlist.c
··· 1148 1148 1149 1149 failed: 1150 1150 while (sgtable->nents > sgtable->orig_nents) 1151 - put_page(sg_page(&sgtable->sgl[--sgtable->nents])); 1151 + unpin_user_page(sg_page(&sgtable->sgl[--sgtable->nents])); 1152 1152 return res; 1153 1153 } 1154 1154
+5 -3
mm/compaction.c
··· 933 933 934 934 /* 935 935 * Check if the pageblock has already been marked skipped. 936 - * Only the aligned PFN is checked as the caller isolates 936 + * Only the first PFN is checked as the caller isolates 937 937 * COMPACT_CLUSTER_MAX at a time so the second call must 938 938 * not falsely conclude that the block should be skipped. 939 939 */ 940 - if (!valid_page && pageblock_aligned(low_pfn)) { 940 + if (!valid_page && (pageblock_aligned(low_pfn) || 941 + low_pfn == cc->zone->zone_start_pfn)) { 941 942 if (!isolation_suitable(cc, page)) { 942 943 low_pfn = end_pfn; 943 944 folio = NULL; ··· 2031 2030 * before making it "skip" so other compaction instances do 2032 2031 * not scan the same block. 2033 2032 */ 2034 - if (pageblock_aligned(low_pfn) && 2033 + if ((pageblock_aligned(low_pfn) || 2034 + low_pfn == cc->zone->zone_start_pfn) && 2035 2035 !fast_find_block && !isolation_suitable(cc, page)) 2036 2036 continue; 2037 2037
+1
mm/damon/core.c
··· 273 273 return NULL; 274 274 filter->type = type; 275 275 filter->matching = matching; 276 + INIT_LIST_HEAD(&filter->list); 276 277 return filter; 277 278 } 278 279
+2
mm/damon/vaddr.c
··· 389 389 static const struct mm_walk_ops damon_mkold_ops = { 390 390 .pmd_entry = damon_mkold_pmd_entry, 391 391 .hugetlb_entry = damon_mkold_hugetlb_entry, 392 + .walk_lock = PGWALK_RDLOCK, 392 393 }; 393 394 394 395 static void damon_va_mkold(struct mm_struct *mm, unsigned long addr) ··· 533 532 static const struct mm_walk_ops damon_young_ops = { 534 533 .pmd_entry = damon_young_pmd_entry, 535 534 .hugetlb_entry = damon_young_hugetlb_entry, 535 + .walk_lock = PGWALK_RDLOCK, 536 536 }; 537 537 538 538 static bool damon_va_young(struct mm_struct *mm, unsigned long addr,
+24 -6
mm/gup.c
··· 597 597 pte = ptep_get(ptep); 598 598 if (!pte_present(pte)) 599 599 goto no_page; 600 - if (pte_protnone(pte) && !gup_can_follow_protnone(flags)) 600 + if (pte_protnone(pte) && !gup_can_follow_protnone(vma, flags)) 601 601 goto no_page; 602 602 603 603 page = vm_normal_page(vma, address, pte); ··· 714 714 if (likely(!pmd_trans_huge(pmdval))) 715 715 return follow_page_pte(vma, address, pmd, flags, &ctx->pgmap); 716 716 717 - if (pmd_protnone(pmdval) && !gup_can_follow_protnone(flags)) 717 + if (pmd_protnone(pmdval) && !gup_can_follow_protnone(vma, flags)) 718 718 return no_page_table(vma, flags); 719 719 720 720 ptl = pmd_lock(mm, pmd); ··· 844 844 if (WARN_ON_ONCE(foll_flags & FOLL_PIN)) 845 845 return NULL; 846 846 847 + /* 848 + * We never set FOLL_HONOR_NUMA_FAULT because callers don't expect 849 + * to fail on PROT_NONE-mapped pages. 850 + */ 847 851 page = follow_page_mask(vma, address, foll_flags, &ctx); 848 852 if (ctx.pgmap) 849 853 put_dev_pagemap(ctx.pgmap); ··· 2244 2240 gup_flags |= FOLL_UNLOCKABLE; 2245 2241 } 2246 2242 2243 + /* 2244 + * For now, always trigger NUMA hinting faults. Some GUP users like 2245 + * KVM require the hint to be as the calling context of GUP is 2246 + * functionally similar to a memory reference from task context. 2247 + */ 2248 + gup_flags |= FOLL_HONOR_NUMA_FAULT; 2249 + 2247 2250 /* FOLL_GET and FOLL_PIN are mutually exclusive. */ 2248 2251 if (WARN_ON_ONCE((gup_flags & (FOLL_PIN | FOLL_GET)) == 2249 2252 (FOLL_PIN | FOLL_GET))) ··· 2575 2564 struct page *page; 2576 2565 struct folio *folio; 2577 2566 2578 - if (pte_protnone(pte) && !gup_can_follow_protnone(flags)) 2567 + /* 2568 + * Always fallback to ordinary GUP on PROT_NONE-mapped pages: 2569 + * pte_access_permitted() better should reject these pages 2570 + * either way: otherwise, GUP-fast might succeed in 2571 + * cases where ordinary GUP would fail due to VMA access 2572 + * permissions. 2573 + */ 2574 + if (pte_protnone(pte)) 2579 2575 goto pte_unmap; 2580 2576 2581 2577 if (!pte_access_permitted(pte, flags & FOLL_WRITE)) ··· 3001 2983 3002 2984 if (unlikely(pmd_trans_huge(pmd) || pmd_huge(pmd) || 3003 2985 pmd_devmap(pmd))) { 3004 - if (pmd_protnone(pmd) && 3005 - !gup_can_follow_protnone(flags)) 2986 + /* See gup_pte_range() */ 2987 + if (pmd_protnone(pmd)) 3006 2988 return 0; 3007 2989 3008 2990 if (!gup_huge_pmd(pmd, pmdp, addr, next, flags, ··· 3182 3164 if (WARN_ON_ONCE(gup_flags & ~(FOLL_WRITE | FOLL_LONGTERM | 3183 3165 FOLL_FORCE | FOLL_PIN | FOLL_GET | 3184 3166 FOLL_FAST_ONLY | FOLL_NOFAULT | 3185 - FOLL_PCI_P2PDMA))) 3167 + FOLL_PCI_P2PDMA | FOLL_HONOR_NUMA_FAULT))) 3186 3168 return -EINVAL; 3187 3169 3188 3170 if (gup_flags & FOLL_PIN)
+1
mm/hmm.c
··· 562 562 .pte_hole = hmm_vma_walk_hole, 563 563 .hugetlb_entry = hmm_vma_walk_hugetlb_entry, 564 564 .test_walk = hmm_vma_walk_test, 565 + .walk_lock = PGWALK_RDLOCK, 565 566 }; 566 567 567 568 /**
+1 -2
mm/huge_memory.c
··· 1467 1467 if ((flags & FOLL_DUMP) && is_huge_zero_pmd(*pmd)) 1468 1468 return ERR_PTR(-EFAULT); 1469 1469 1470 - /* Full NUMA hinting faults to serialise migration in fault paths */ 1471 - if (pmd_protnone(*pmd) && !gup_can_follow_protnone(flags)) 1470 + if (pmd_protnone(*pmd) && !gup_can_follow_protnone(vma, flags)) 1472 1471 return NULL; 1473 1472 1474 1473 if (!pmd_write(*pmd) && gup_must_unshare(vma, flags, page))
+51 -24
mm/hugetlb.c
··· 1580 1580 unsigned int order) { } 1581 1581 #endif 1582 1582 1583 + static inline void __clear_hugetlb_destructor(struct hstate *h, 1584 + struct folio *folio) 1585 + { 1586 + lockdep_assert_held(&hugetlb_lock); 1587 + 1588 + /* 1589 + * Very subtle 1590 + * 1591 + * For non-gigantic pages set the destructor to the normal compound 1592 + * page dtor. This is needed in case someone takes an additional 1593 + * temporary ref to the page, and freeing is delayed until they drop 1594 + * their reference. 1595 + * 1596 + * For gigantic pages set the destructor to the null dtor. This 1597 + * destructor will never be called. Before freeing the gigantic 1598 + * page destroy_compound_gigantic_folio will turn the folio into a 1599 + * simple group of pages. After this the destructor does not 1600 + * apply. 1601 + * 1602 + */ 1603 + if (hstate_is_gigantic(h)) 1604 + folio_set_compound_dtor(folio, NULL_COMPOUND_DTOR); 1605 + else 1606 + folio_set_compound_dtor(folio, COMPOUND_PAGE_DTOR); 1607 + } 1608 + 1583 1609 /* 1584 - * Remove hugetlb folio from lists, and update dtor so that the folio appears 1585 - * as just a compound page. 1610 + * Remove hugetlb folio from lists. 1611 + * If vmemmap exists for the folio, update dtor so that the folio appears 1612 + * as just a compound page. Otherwise, wait until after allocating vmemmap 1613 + * to update dtor. 1586 1614 * 1587 1615 * A reference is held on the folio, except in the case of demote. 1588 1616 * ··· 1641 1613 } 1642 1614 1643 1615 /* 1644 - * Very subtle 1645 - * 1646 - * For non-gigantic pages set the destructor to the normal compound 1647 - * page dtor. This is needed in case someone takes an additional 1648 - * temporary ref to the page, and freeing is delayed until they drop 1649 - * their reference. 1650 - * 1651 - * For gigantic pages set the destructor to the null dtor. This 1652 - * destructor will never be called. Before freeing the gigantic 1653 - * page destroy_compound_gigantic_folio will turn the folio into a 1654 - * simple group of pages. After this the destructor does not 1655 - * apply. 1656 - * 1657 - * This handles the case where more than one ref is held when and 1658 - * after update_and_free_hugetlb_folio is called. 1659 - * 1660 - * In the case of demote we do not ref count the page as it will soon 1661 - * be turned into a page of smaller size. 1616 + * We can only clear the hugetlb destructor after allocating vmemmap 1617 + * pages. Otherwise, someone (memory error handling) may try to write 1618 + * to tail struct pages. 1619 + */ 1620 + if (!folio_test_hugetlb_vmemmap_optimized(folio)) 1621 + __clear_hugetlb_destructor(h, folio); 1622 + 1623 + /* 1624 + * In the case of demote we do not ref count the page as it will soon 1625 + * be turned into a page of smaller size. 1662 1626 */ 1663 1627 if (!demote) 1664 1628 folio_ref_unfreeze(folio, 1); 1665 - if (hstate_is_gigantic(h)) 1666 - folio_set_compound_dtor(folio, NULL_COMPOUND_DTOR); 1667 - else 1668 - folio_set_compound_dtor(folio, COMPOUND_PAGE_DTOR); 1669 1629 1670 1630 h->nr_huge_pages--; 1671 1631 h->nr_huge_pages_node[nid]--; ··· 1722 1706 { 1723 1707 int i; 1724 1708 struct page *subpage; 1709 + bool clear_dtor = folio_test_hugetlb_vmemmap_optimized(folio); 1725 1710 1726 1711 if (hstate_is_gigantic(h) && !gigantic_page_runtime_supported()) 1727 1712 return; ··· 1752 1735 */ 1753 1736 if (unlikely(folio_test_hwpoison(folio))) 1754 1737 folio_clear_hugetlb_hwpoison(folio); 1738 + 1739 + /* 1740 + * If vmemmap pages were allocated above, then we need to clear the 1741 + * hugetlb destructor under the hugetlb lock. 1742 + */ 1743 + if (clear_dtor) { 1744 + spin_lock_irq(&hugetlb_lock); 1745 + __clear_hugetlb_destructor(h, folio); 1746 + spin_unlock_irq(&hugetlb_lock); 1747 + } 1755 1748 1756 1749 for (i = 0; i < pages_per_huge_page(h); i++) { 1757 1750 subpage = folio_page(folio, i);
+17
mm/internal.h
··· 941 941 struct folio *try_grab_folio(struct page *page, int refs, unsigned int flags); 942 942 int __must_check try_grab_page(struct page *page, unsigned int flags); 943 943 944 + /* 945 + * mm/huge_memory.c 946 + */ 947 + struct page *follow_trans_huge_pmd(struct vm_area_struct *vma, 948 + unsigned long addr, pmd_t *pmd, 949 + unsigned int flags); 950 + 944 951 enum { 945 952 /* mark page accessed */ 946 953 FOLL_TOUCH = 1 << 16, ··· 1020 1013 /* Paired with a memory barrier in page_try_share_anon_rmap(). */ 1021 1014 if (IS_ENABLED(CONFIG_HAVE_FAST_GUP)) 1022 1015 smp_rmb(); 1016 + 1017 + /* 1018 + * During GUP-fast we might not get called on the head page for a 1019 + * hugetlb page that is mapped using cont-PTE, because GUP-fast does 1020 + * not work with the abstracted hugetlb PTEs that always point at the 1021 + * head page. For hugetlb, PageAnonExclusive only applies on the head 1022 + * page (as it cannot be partially COW-shared), so lookup the head page. 1023 + */ 1024 + if (unlikely(!PageHead(page) && PageHuge(page))) 1025 + page = compound_head(page); 1023 1026 1024 1027 /* 1025 1028 * Note that PageKsm() pages cannot be exclusive, and consequently,
+18 -9
mm/ksm.c
··· 462 462 463 463 static const struct mm_walk_ops break_ksm_ops = { 464 464 .pmd_entry = break_ksm_pmd_entry, 465 + .walk_lock = PGWALK_RDLOCK, 466 + }; 467 + 468 + static const struct mm_walk_ops break_ksm_lock_vma_ops = { 469 + .pmd_entry = break_ksm_pmd_entry, 470 + .walk_lock = PGWALK_WRLOCK, 465 471 }; 466 472 467 473 /* ··· 483 477 * of the process that owns 'vma'. We also do not want to enforce 484 478 * protection keys here anyway. 485 479 */ 486 - static int break_ksm(struct vm_area_struct *vma, unsigned long addr) 480 + static int break_ksm(struct vm_area_struct *vma, unsigned long addr, bool lock_vma) 487 481 { 488 482 vm_fault_t ret = 0; 483 + const struct mm_walk_ops *ops = lock_vma ? 484 + &break_ksm_lock_vma_ops : &break_ksm_ops; 489 485 490 486 do { 491 487 int ksm_page; 492 488 493 489 cond_resched(); 494 - ksm_page = walk_page_range_vma(vma, addr, addr + 1, 495 - &break_ksm_ops, NULL); 490 + ksm_page = walk_page_range_vma(vma, addr, addr + 1, ops, NULL); 496 491 if (WARN_ON_ONCE(ksm_page < 0)) 497 492 return ksm_page; 498 493 if (!ksm_page) ··· 579 572 mmap_read_lock(mm); 580 573 vma = find_mergeable_vma(mm, addr); 581 574 if (vma) 582 - break_ksm(vma, addr); 575 + break_ksm(vma, addr, false); 583 576 mmap_read_unlock(mm); 584 577 } 585 578 ··· 885 878 * in cmp_and_merge_page on one of the rmap_items we would be removing. 886 879 */ 887 880 static int unmerge_ksm_pages(struct vm_area_struct *vma, 888 - unsigned long start, unsigned long end) 881 + unsigned long start, unsigned long end, bool lock_vma) 889 882 { 890 883 unsigned long addr; 891 884 int err = 0; ··· 896 889 if (signal_pending(current)) 897 890 err = -ERESTARTSYS; 898 891 else 899 - err = break_ksm(vma, addr); 892 + err = break_ksm(vma, addr, lock_vma); 900 893 } 901 894 return err; 902 895 } ··· 1043 1036 if (!(vma->vm_flags & VM_MERGEABLE) || !vma->anon_vma) 1044 1037 continue; 1045 1038 err = unmerge_ksm_pages(vma, 1046 - vma->vm_start, vma->vm_end); 1039 + vma->vm_start, vma->vm_end, false); 1047 1040 if (err) 1048 1041 goto error; 1049 1042 } ··· 2553 2546 return 0; 2554 2547 2555 2548 if (vma->anon_vma) { 2556 - err = unmerge_ksm_pages(vma, vma->vm_start, vma->vm_end); 2549 + err = unmerge_ksm_pages(vma, vma->vm_start, vma->vm_end, true); 2557 2550 if (err) 2558 2551 return err; 2559 2552 } ··· 2691 2684 return 0; /* just ignore the advice */ 2692 2685 2693 2686 if (vma->anon_vma) { 2694 - err = unmerge_ksm_pages(vma, start, end); 2687 + err = unmerge_ksm_pages(vma, start, end, true); 2695 2688 if (err) 2696 2689 return err; 2697 2690 } ··· 2807 2800 anon_vma->root == vma->anon_vma->root) { 2808 2801 return page; /* still no need to copy it */ 2809 2802 } 2803 + if (PageHWPoison(page)) 2804 + return ERR_PTR(-EHWPOISON); 2810 2805 if (!PageUptodate(page)) 2811 2806 return page; /* let do_swap_page report the error */ 2812 2807
+3
mm/madvise.c
··· 232 232 233 233 static const struct mm_walk_ops swapin_walk_ops = { 234 234 .pmd_entry = swapin_walk_pmd_entry, 235 + .walk_lock = PGWALK_RDLOCK, 235 236 }; 236 237 237 238 static void shmem_swapin_range(struct vm_area_struct *vma, ··· 538 537 539 538 static const struct mm_walk_ops cold_walk_ops = { 540 539 .pmd_entry = madvise_cold_or_pageout_pte_range, 540 + .walk_lock = PGWALK_RDLOCK, 541 541 }; 542 542 543 543 static void madvise_cold_page_range(struct mmu_gather *tlb, ··· 762 760 763 761 static const struct mm_walk_ops madvise_free_walk_ops = { 764 762 .pmd_entry = madvise_free_pte_range, 763 + .walk_lock = PGWALK_RDLOCK, 765 764 }; 766 765 767 766 static int madvise_free_single_vma(struct vm_area_struct *vma,
+2
mm/memcontrol.c
··· 6013 6013 6014 6014 static const struct mm_walk_ops precharge_walk_ops = { 6015 6015 .pmd_entry = mem_cgroup_count_precharge_pte_range, 6016 + .walk_lock = PGWALK_RDLOCK, 6016 6017 }; 6017 6018 6018 6019 static unsigned long mem_cgroup_count_precharge(struct mm_struct *mm) ··· 6293 6292 6294 6293 static const struct mm_walk_ops charge_walk_ops = { 6295 6294 .pmd_entry = mem_cgroup_move_charge_pte_range, 6295 + .walk_lock = PGWALK_RDLOCK, 6296 6296 }; 6297 6297 6298 6298 static void mem_cgroup_move_charge(void)
+24 -17
mm/memory-failure.c
··· 827 827 static const struct mm_walk_ops hwp_walk_ops = { 828 828 .pmd_entry = hwpoison_pte_range, 829 829 .hugetlb_entry = hwpoison_hugetlb_range, 830 + .walk_lock = PGWALK_RDLOCK, 830 831 }; 831 832 832 833 /* ··· 2501 2500 { 2502 2501 struct folio *folio; 2503 2502 struct page *p; 2504 - int ret = -EBUSY; 2503 + int ret = -EBUSY, ghp; 2505 2504 unsigned long count = 1; 2506 2505 bool huge = false; 2507 2506 static DEFINE_RATELIMIT_STATE(unpoison_rs, DEFAULT_RATELIMIT_INTERVAL, ··· 2534 2533 goto unlock_mutex; 2535 2534 } 2536 2535 2536 + if (folio_test_slab(folio) || PageTable(&folio->page) || folio_test_reserved(folio)) 2537 + goto unlock_mutex; 2538 + 2539 + /* 2540 + * Note that folio->_mapcount is overloaded in SLAB, so the simple test 2541 + * in folio_mapped() has to be done after folio_test_slab() is checked. 2542 + */ 2537 2543 if (folio_mapped(folio)) { 2538 2544 unpoison_pr_info("Unpoison: Someone maps the hwpoison page %#lx\n", 2539 2545 pfn, &unpoison_rs); ··· 2553 2545 goto unlock_mutex; 2554 2546 } 2555 2547 2556 - if (folio_test_slab(folio) || PageTable(&folio->page) || folio_test_reserved(folio)) 2557 - goto unlock_mutex; 2558 - 2559 - ret = get_hwpoison_page(p, MF_UNPOISON); 2560 - if (!ret) { 2548 + ghp = get_hwpoison_page(p, MF_UNPOISON); 2549 + if (!ghp) { 2561 2550 if (PageHuge(p)) { 2562 2551 huge = true; 2563 2552 count = folio_free_raw_hwp(folio, false); 2564 - if (count == 0) { 2565 - ret = -EBUSY; 2553 + if (count == 0) 2566 2554 goto unlock_mutex; 2567 - } 2568 2555 } 2569 2556 ret = folio_test_clear_hwpoison(folio) ? 0 : -EBUSY; 2570 - } else if (ret < 0) { 2571 - if (ret == -EHWPOISON) { 2557 + } else if (ghp < 0) { 2558 + if (ghp == -EHWPOISON) { 2572 2559 ret = put_page_back_buddy(p) ? 0 : -EBUSY; 2573 - } else 2560 + } else { 2561 + ret = ghp; 2574 2562 unpoison_pr_info("Unpoison: failed to grab page %#lx\n", 2575 2563 pfn, &unpoison_rs); 2564 + } 2576 2565 } else { 2577 2566 if (PageHuge(p)) { 2578 2567 huge = true; 2579 2568 count = folio_free_raw_hwp(folio, false); 2580 2569 if (count == 0) { 2581 - ret = -EBUSY; 2582 2570 folio_put(folio); 2583 2571 goto unlock_mutex; 2584 2572 } ··· 2775 2771 if (ret > 0) { 2776 2772 ret = soft_offline_in_use_page(page); 2777 2773 } else if (ret == 0) { 2778 - if (!page_handle_poison(page, true, false) && try_again) { 2779 - try_again = false; 2780 - flags &= ~MF_COUNT_INCREASED; 2781 - goto retry; 2774 + if (!page_handle_poison(page, true, false)) { 2775 + if (try_again) { 2776 + try_again = false; 2777 + flags &= ~MF_COUNT_INCREASED; 2778 + goto retry; 2779 + } 2780 + ret = -EBUSY; 2782 2781 } 2783 2782 } 2784 2783
+14 -8
mm/mempolicy.c
··· 718 718 .hugetlb_entry = queue_folios_hugetlb, 719 719 .pmd_entry = queue_folios_pte_range, 720 720 .test_walk = queue_pages_test_walk, 721 + .walk_lock = PGWALK_RDLOCK, 722 + }; 723 + 724 + static const struct mm_walk_ops queue_pages_lock_vma_walk_ops = { 725 + .hugetlb_entry = queue_folios_hugetlb, 726 + .pmd_entry = queue_folios_pte_range, 727 + .test_walk = queue_pages_test_walk, 728 + .walk_lock = PGWALK_WRLOCK, 721 729 }; 722 730 723 731 /* ··· 746 738 static int 747 739 queue_pages_range(struct mm_struct *mm, unsigned long start, unsigned long end, 748 740 nodemask_t *nodes, unsigned long flags, 749 - struct list_head *pagelist) 741 + struct list_head *pagelist, bool lock_vma) 750 742 { 751 743 int err; 752 744 struct queue_pages qp = { ··· 757 749 .end = end, 758 750 .first = NULL, 759 751 }; 752 + const struct mm_walk_ops *ops = lock_vma ? 753 + &queue_pages_lock_vma_walk_ops : &queue_pages_walk_ops; 760 754 761 - err = walk_page_range(mm, start, end, &queue_pages_walk_ops, &qp); 755 + err = walk_page_range(mm, start, end, ops, &qp); 762 756 763 757 if (!qp.first) 764 758 /* whole range in hole */ ··· 1088 1078 vma = find_vma(mm, 0); 1089 1079 VM_BUG_ON(!(flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL))); 1090 1080 queue_pages_range(mm, vma->vm_start, mm->task_size, &nmask, 1091 - flags | MPOL_MF_DISCONTIG_OK, &pagelist); 1081 + flags | MPOL_MF_DISCONTIG_OK, &pagelist, false); 1092 1082 1093 1083 if (!list_empty(&pagelist)) { 1094 1084 err = migrate_pages(&pagelist, alloc_migration_target, NULL, ··· 1331 1321 * Lock the VMAs before scanning for pages to migrate, to ensure we don't 1332 1322 * miss a concurrently inserted page. 1333 1323 */ 1334 - vma_iter_init(&vmi, mm, start); 1335 - for_each_vma_range(vmi, vma, end) 1336 - vma_start_write(vma); 1337 - 1338 1324 ret = queue_pages_range(mm, start, end, nmask, 1339 - flags | MPOL_MF_INVERT, &pagelist); 1325 + flags | MPOL_MF_INVERT, &pagelist, true); 1340 1326 1341 1327 if (ret < 0) { 1342 1328 err = ret;
+1
mm/migrate_device.c
··· 279 279 static const struct mm_walk_ops migrate_vma_walk_ops = { 280 280 .pmd_entry = migrate_vma_collect_pmd, 281 281 .pte_hole = migrate_vma_collect_hole, 282 + .walk_lock = PGWALK_RDLOCK, 282 283 }; 283 284 284 285 /*
+1
mm/mincore.c
··· 176 176 .pmd_entry = mincore_pte_range, 177 177 .pte_hole = mincore_unmapped_range, 178 178 .hugetlb_entry = mincore_hugetlb, 179 + .walk_lock = PGWALK_RDLOCK, 179 180 }; 180 181 181 182 /*
+1
mm/mlock.c
··· 371 371 { 372 372 static const struct mm_walk_ops mlock_walk_ops = { 373 373 .pmd_entry = mlock_pte_range, 374 + .walk_lock = PGWALK_WRLOCK_VERIFY, 374 375 }; 375 376 376 377 /*
+1
mm/mprotect.c
··· 568 568 .pte_entry = prot_none_pte_entry, 569 569 .hugetlb_entry = prot_none_hugetlb_entry, 570 570 .test_walk = prot_none_test, 571 + .walk_lock = PGWALK_WRLOCK, 571 572 }; 572 573 573 574 int
+33 -3
mm/pagewalk.c
··· 400 400 return err; 401 401 } 402 402 403 + static inline void process_mm_walk_lock(struct mm_struct *mm, 404 + enum page_walk_lock walk_lock) 405 + { 406 + if (walk_lock == PGWALK_RDLOCK) 407 + mmap_assert_locked(mm); 408 + else 409 + mmap_assert_write_locked(mm); 410 + } 411 + 412 + static inline void process_vma_walk_lock(struct vm_area_struct *vma, 413 + enum page_walk_lock walk_lock) 414 + { 415 + #ifdef CONFIG_PER_VMA_LOCK 416 + switch (walk_lock) { 417 + case PGWALK_WRLOCK: 418 + vma_start_write(vma); 419 + break; 420 + case PGWALK_WRLOCK_VERIFY: 421 + vma_assert_write_locked(vma); 422 + break; 423 + case PGWALK_RDLOCK: 424 + /* PGWALK_RDLOCK is handled by process_mm_walk_lock */ 425 + break; 426 + } 427 + #endif 428 + } 429 + 403 430 /** 404 431 * walk_page_range - walk page table with caller specific callbacks 405 432 * @mm: mm_struct representing the target process of page table walk ··· 486 459 if (!walk.mm) 487 460 return -EINVAL; 488 461 489 - mmap_assert_locked(walk.mm); 462 + process_mm_walk_lock(walk.mm, ops->walk_lock); 490 463 491 464 vma = find_vma(walk.mm, start); 492 465 do { ··· 501 474 if (ops->pte_hole) 502 475 err = ops->pte_hole(start, next, -1, &walk); 503 476 } else { /* inside vma */ 477 + process_vma_walk_lock(vma, ops->walk_lock); 504 478 walk.vma = vma; 505 479 next = min(end, vma->vm_end); 506 480 vma = find_vma(mm, vma->vm_end); ··· 577 549 if (start < vma->vm_start || end > vma->vm_end) 578 550 return -EINVAL; 579 551 580 - mmap_assert_locked(walk.mm); 552 + process_mm_walk_lock(walk.mm, ops->walk_lock); 553 + process_vma_walk_lock(vma, ops->walk_lock); 581 554 return __walk_page_range(start, end, &walk); 582 555 } 583 556 ··· 595 566 if (!walk.mm) 596 567 return -EINVAL; 597 568 598 - mmap_assert_locked(walk.mm); 569 + process_mm_walk_lock(walk.mm, ops->walk_lock); 570 + process_vma_walk_lock(vma, ops->walk_lock); 599 571 return __walk_page_range(vma->vm_start, vma->vm_end, &walk); 600 572 } 601 573
+4 -4
mm/swapfile.c
··· 1745 1745 struct page *swapcache; 1746 1746 spinlock_t *ptl; 1747 1747 pte_t *pte, new_pte, old_pte; 1748 - bool hwposioned = false; 1748 + bool hwpoisoned = PageHWPoison(page); 1749 1749 int ret = 1; 1750 1750 1751 1751 swapcache = page; ··· 1753 1753 if (unlikely(!page)) 1754 1754 return -ENOMEM; 1755 1755 else if (unlikely(PTR_ERR(page) == -EHWPOISON)) 1756 - hwposioned = true; 1756 + hwpoisoned = true; 1757 1757 1758 1758 pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); 1759 1759 if (unlikely(!pte || !pte_same_as_swp(ptep_get(pte), ··· 1764 1764 1765 1765 old_pte = ptep_get(pte); 1766 1766 1767 - if (unlikely(hwposioned || !PageUptodate(page))) { 1767 + if (unlikely(hwpoisoned || !PageUptodate(page))) { 1768 1768 swp_entry_t swp_entry; 1769 1769 1770 1770 dec_mm_counter(vma->vm_mm, MM_SWAPENTS); 1771 - if (hwposioned) { 1771 + if (hwpoisoned) { 1772 1772 swp_entry = make_hwpoison_entry(swapcache); 1773 1773 page = swapcache; 1774 1774 } else {
+4
mm/vmalloc.c
··· 2979 2979 free_vm_area(area); 2980 2980 return NULL; 2981 2981 } 2982 + 2983 + flush_cache_vmap((unsigned long)area->addr, 2984 + (unsigned long)area->addr + count * PAGE_SIZE); 2985 + 2982 2986 return area->addr; 2983 2987 } 2984 2988 EXPORT_SYMBOL_GPL(vmap_pfn);
+9 -5
mm/vmscan.c
··· 4284 4284 static const struct mm_walk_ops mm_walk_ops = { 4285 4285 .test_walk = should_skip_vma, 4286 4286 .p4d_entry = walk_pud_range, 4287 + .walk_lock = PGWALK_RDLOCK, 4287 4288 }; 4288 4289 4289 4290 int err; ··· 4856 4855 4857 4856 spin_lock_irq(&pgdat->memcg_lru.lock); 4858 4857 4859 - VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list)); 4858 + if (hlist_nulls_unhashed(&lruvec->lrugen.list)) 4859 + goto unlock; 4860 4860 4861 4861 gen = lruvec->lrugen.gen; 4862 4862 4863 - hlist_nulls_del_rcu(&lruvec->lrugen.list); 4863 + hlist_nulls_del_init_rcu(&lruvec->lrugen.list); 4864 4864 pgdat->memcg_lru.nr_memcgs[gen]--; 4865 4865 4866 4866 if (!pgdat->memcg_lru.nr_memcgs[gen] && gen == get_memcg_gen(pgdat->memcg_lru.seq)) 4867 4867 WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1); 4868 - 4868 + unlock: 4869 4869 spin_unlock_irq(&pgdat->memcg_lru.lock); 4870 4870 } 4871 4871 } ··· 5448 5446 rcu_read_lock(); 5449 5447 5450 5448 hlist_nulls_for_each_entry_rcu(lrugen, pos, &pgdat->memcg_lru.fifo[gen][bin], list) { 5451 - if (op) 5449 + if (op) { 5452 5450 lru_gen_rotate_memcg(lruvec, op); 5451 + op = 0; 5452 + } 5453 5453 5454 5454 mem_cgroup_put(memcg); 5455 5455 ··· 5459 5455 memcg = lruvec_memcg(lruvec); 5460 5456 5461 5457 if (!mem_cgroup_tryget(memcg)) { 5462 - op = 0; 5458 + lru_gen_release_memcg(memcg); 5463 5459 memcg = NULL; 5464 5460 continue; 5465 5461 }
+9 -5
mm/zsmalloc.c
··· 1777 1777 1778 1778 static bool zs_page_isolate(struct page *page, isolate_mode_t mode) 1779 1779 { 1780 + struct zs_pool *pool; 1780 1781 struct zspage *zspage; 1781 1782 1782 1783 /* ··· 1787 1786 VM_BUG_ON_PAGE(PageIsolated(page), page); 1788 1787 1789 1788 zspage = get_zspage(page); 1790 - migrate_write_lock(zspage); 1789 + pool = zspage->pool; 1790 + spin_lock(&pool->lock); 1791 1791 inc_zspage_isolation(zspage); 1792 - migrate_write_unlock(zspage); 1792 + spin_unlock(&pool->lock); 1793 1793 1794 1794 return true; 1795 1795 } ··· 1856 1854 kunmap_atomic(s_addr); 1857 1855 1858 1856 replace_sub_page(class, zspage, newpage, page); 1857 + dec_zspage_isolation(zspage); 1859 1858 /* 1860 1859 * Since we complete the data copy and set up new zspage structure, 1861 1860 * it's okay to release the pool's lock. 1862 1861 */ 1863 1862 spin_unlock(&pool->lock); 1864 - dec_zspage_isolation(zspage); 1865 1863 migrate_write_unlock(zspage); 1866 1864 1867 1865 get_page(newpage); ··· 1878 1876 1879 1877 static void zs_page_putback(struct page *page) 1880 1878 { 1879 + struct zs_pool *pool; 1881 1880 struct zspage *zspage; 1882 1881 1883 1882 VM_BUG_ON_PAGE(!PageIsolated(page), page); 1884 1883 1885 1884 zspage = get_zspage(page); 1886 - migrate_write_lock(zspage); 1885 + pool = zspage->pool; 1886 + spin_lock(&pool->lock); 1887 1887 dec_zspage_isolation(zspage); 1888 - migrate_write_unlock(zspage); 1888 + spin_unlock(&pool->lock); 1889 1889 } 1890 1890 1891 1891 static const struct movable_operations zsmalloc_mops = {
+1 -1
tools/testing/radix-tree/regression1.c
··· 177 177 nr_threads = 2; 178 178 pthread_barrier_init(&worker_barrier, NULL, nr_threads); 179 179 180 - threads = malloc(nr_threads * sizeof(pthread_t *)); 180 + threads = malloc(nr_threads * sizeof(*threads)); 181 181 182 182 for (i = 0; i < nr_threads; i++) { 183 183 arg = i;
+6 -2
tools/testing/selftests/cgroup/test_kmem.c
··· 70 70 goto cleanup; 71 71 72 72 cg_write(cg, "memory.high", "1M"); 73 + 74 + /* wait for RCU freeing */ 75 + sleep(1); 76 + 73 77 slab1 = cg_read_key_long(cg, "memory.stat", "slab "); 74 - if (slab1 <= 0) 78 + if (slab1 < 0) 75 79 goto cleanup; 76 80 77 81 current = cg_read_long(cg, "memory.current"); 78 - if (current <= 0) 82 + if (current < 0) 79 83 goto cleanup; 80 84 81 85 if (slab1 < slab0 / 2 && current < slab0 / 2)
+7 -2
tools/testing/selftests/mm/hmm-tests.c
··· 57 57 58 58 #define ALIGN(x, a) (((x) + (a - 1)) & (~((a) - 1))) 59 59 /* Just the flags we need, copied from mm.h: */ 60 - #define FOLL_WRITE 0x01 /* check pte is writable */ 61 - #define FOLL_LONGTERM 0x10000 /* mapping lifetime is indefinite */ 62 60 61 + #ifndef FOLL_WRITE 62 + #define FOLL_WRITE 0x01 /* check pte is writable */ 63 + #endif 64 + 65 + #ifndef FOLL_LONGTERM 66 + #define FOLL_LONGTERM 0x100 /* mapping lifetime is indefinite */ 67 + #endif 63 68 FIXTURE(hmm) 64 69 { 65 70 int fd;
+1
tools/testing/selftests/mm/ksm_tests.c
··· 831 831 printf("Size must be greater than 0\n"); 832 832 return KSFT_FAIL; 833 833 } 834 + break; 834 835 case 't': 835 836 { 836 837 int tmp = atoi(optarg);