Skip to content

Commit 6f0edbb

Browse files
committed
Merge tag 'mm-hotfixes-stable-2023-08-25-11-07' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull misc fixes from Andrew Morton: "18 hotfixes. 13 are cc:stable and the remainder pertain to post-6.4 issues or aren't considered suitable for a -stable backport" * tag 'mm-hotfixes-stable-2023-08-25-11-07' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: shmem: fix smaps BUG sleeping while atomic selftests: cachestat: catch failing fsync test on tmpfs selftests: cachestat: test for cachestat availability maple_tree: disable mas_wr_append() when other readers are possible madvise:madvise_free_pte_range(): don't use mapcount() against large folio for sharing check madvise:madvise_free_huge_pmd(): don't use mapcount() against large folio for sharing check madvise:madvise_cold_or_pageout_pte_range(): don't use mapcount() against large folio for sharing check mm: multi-gen LRU: don't spin during memcg release mm: memory-failure: fix unexpected return value in soft_offline_page() radix tree: remove unused variable mm: add a call to flush_cache_vmap() in vmap_pfn() selftests/mm: FOLL_LONGTERM need to be updated to 0x100 nilfs2: fix general protection fault in nilfs_lookup_dirty_data_buffers() mm/gup: handle cont-PTE hugetlb pages correctly in gup_must_unshare() via GUP-fast selftests: cgroup: fix test_kmem_basic less than error mm: enable page walking API to lock vmas during the walk smaps: use vm_normal_page_pmd() instead of follow_trans_huge_pmd() mm/gup: reintroduce FOLL_NUMA as FOLL_HONOR_NUMA_FAULT
2 parents 4942fed + e5548f8 commit 6f0edbb

32 files changed

+279
-73
lines changed

arch/powerpc/mm/book3s64/subpage_prot.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ static int subpage_walk_pmd_entry(pmd_t *pmd, unsigned long addr,
145145

146146
static const struct mm_walk_ops subpage_walk_ops = {
147147
.pmd_entry = subpage_walk_pmd_entry,
148+
.walk_lock = PGWALK_WRLOCK_VERIFY,
148149
};
149150

150151
static void subpage_mark_vma_nohuge(struct mm_struct *mm, unsigned long addr,

arch/riscv/mm/pageattr.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ static const struct mm_walk_ops pageattr_ops = {
102102
.pmd_entry = pageattr_pmd_entry,
103103
.pte_entry = pageattr_pte_entry,
104104
.pte_hole = pageattr_pte_hole,
105+
.walk_lock = PGWALK_RDLOCK,
105106
};
106107

107108
static int __set_memory(unsigned long addr, int numpages, pgprot_t set_mask,

arch/s390/mm/gmap.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2514,6 +2514,7 @@ static int thp_split_walk_pmd_entry(pmd_t *pmd, unsigned long addr,
25142514

25152515
static const struct mm_walk_ops thp_split_walk_ops = {
25162516
.pmd_entry = thp_split_walk_pmd_entry,
2517+
.walk_lock = PGWALK_WRLOCK_VERIFY,
25172518
};
25182519

25192520
static inline void thp_split_mm(struct mm_struct *mm)
@@ -2565,6 +2566,7 @@ static int __zap_zero_pages(pmd_t *pmd, unsigned long start,
25652566

25662567
static const struct mm_walk_ops zap_zero_walk_ops = {
25672568
.pmd_entry = __zap_zero_pages,
2569+
.walk_lock = PGWALK_WRLOCK,
25682570
};
25692571

25702572
/*
@@ -2655,6 +2657,7 @@ static const struct mm_walk_ops enable_skey_walk_ops = {
26552657
.hugetlb_entry = __s390_enable_skey_hugetlb,
26562658
.pte_entry = __s390_enable_skey_pte,
26572659
.pmd_entry = __s390_enable_skey_pmd,
2660+
.walk_lock = PGWALK_WRLOCK,
26582661
};
26592662

26602663
int s390_enable_skey(void)
@@ -2692,6 +2695,7 @@ static int __s390_reset_cmma(pte_t *pte, unsigned long addr,
26922695

26932696
static const struct mm_walk_ops reset_cmma_walk_ops = {
26942697
.pte_entry = __s390_reset_cmma,
2698+
.walk_lock = PGWALK_WRLOCK,
26952699
};
26962700

26972701
void s390_reset_cmma(struct mm_struct *mm)
@@ -2728,6 +2732,7 @@ static int s390_gather_pages(pte_t *ptep, unsigned long addr,
27282732

27292733
static const struct mm_walk_ops gather_pages_ops = {
27302734
.pte_entry = s390_gather_pages,
2735+
.walk_lock = PGWALK_RDLOCK,
27312736
};
27322737

27332738
/*

fs/nilfs2/segment.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,11 @@ static size_t nilfs_lookup_dirty_data_buffers(struct inode *inode,
725725
struct folio *folio = fbatch.folios[i];
726726

727727
folio_lock(folio);
728+
if (unlikely(folio->mapping != mapping)) {
729+
/* Exclude folios removed from the address space */
730+
folio_unlock(folio);
731+
continue;
732+
}
728733
head = folio_buffers(folio);
729734
if (!head) {
730735
create_empty_buffers(&folio->page, i_blocksize(inode), 0);

fs/proc/task_mmu.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -587,8 +587,7 @@ static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr,
587587
bool migration = false;
588588

589589
if (pmd_present(*pmd)) {
590-
/* FOLL_DUMP will return -EFAULT on huge zero page */
591-
page = follow_trans_huge_pmd(vma, addr, pmd, FOLL_DUMP);
590+
page = vm_normal_page_pmd(vma, addr, *pmd);
592591
} else if (unlikely(thp_migration_supported() && is_swap_pmd(*pmd))) {
593592
swp_entry_t entry = pmd_to_swp_entry(*pmd);
594593

@@ -758,12 +757,14 @@ static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask,
758757
static const struct mm_walk_ops smaps_walk_ops = {
759758
.pmd_entry = smaps_pte_range,
760759
.hugetlb_entry = smaps_hugetlb_range,
760+
.walk_lock = PGWALK_RDLOCK,
761761
};
762762

763763
static const struct mm_walk_ops smaps_shmem_walk_ops = {
764764
.pmd_entry = smaps_pte_range,
765765
.hugetlb_entry = smaps_hugetlb_range,
766766
.pte_hole = smaps_pte_hole,
767+
.walk_lock = PGWALK_RDLOCK,
767768
};
768769

769770
/*
@@ -1245,6 +1246,7 @@ static int clear_refs_test_walk(unsigned long start, unsigned long end,
12451246
static const struct mm_walk_ops clear_refs_walk_ops = {
12461247
.pmd_entry = clear_refs_pte_range,
12471248
.test_walk = clear_refs_test_walk,
1249+
.walk_lock = PGWALK_WRLOCK,
12481250
};
12491251

12501252
static ssize_t clear_refs_write(struct file *file, const char __user *buf,
@@ -1622,6 +1624,7 @@ static const struct mm_walk_ops pagemap_ops = {
16221624
.pmd_entry = pagemap_pmd_range,
16231625
.pte_hole = pagemap_pte_hole,
16241626
.hugetlb_entry = pagemap_hugetlb_range,
1627+
.walk_lock = PGWALK_RDLOCK,
16251628
};
16261629

16271630
/*
@@ -1935,6 +1938,7 @@ static int gather_hugetlb_stats(pte_t *pte, unsigned long hmask,
19351938
static const struct mm_walk_ops show_numa_ops = {
19361939
.hugetlb_entry = gather_hugetlb_stats,
19371940
.pmd_entry = gather_pte_stats,
1941+
.walk_lock = PGWALK_RDLOCK,
19381942
};
19391943

19401944
/*

include/linux/huge_mm.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ static inline void huge_pud_set_accessed(struct vm_fault *vmf, pud_t orig_pud)
2525
#endif
2626

2727
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);
3128
bool madvise_free_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
3229
pmd_t *pmd, unsigned long addr, unsigned long next);
3330
int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma, pmd_t *pmd,

include/linux/mm.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3421,15 +3421,24 @@ static inline int vm_fault_to_errno(vm_fault_t vm_fault, int foll_flags)
34213421
* Indicates whether GUP can follow a PROT_NONE mapped page, or whether
34223422
* a (NUMA hinting) fault is required.
34233423
*/
3424-
static inline bool gup_can_follow_protnone(unsigned int flags)
3424+
static inline bool gup_can_follow_protnone(struct vm_area_struct *vma,
3425+
unsigned int flags)
34253426
{
34263427
/*
3427-
* FOLL_FORCE has to be able to make progress even if the VMA is
3428-
* inaccessible. Further, FOLL_FORCE access usually does not represent
3429-
* application behaviour and we should avoid triggering NUMA hinting
3430-
* faults.
3428+
* If callers don't want to honor NUMA hinting faults, no need to
3429+
* determine if we would actually have to trigger a NUMA hinting fault.
34313430
*/
3432-
return flags & FOLL_FORCE;
3431+
if (!(flags & FOLL_HONOR_NUMA_FAULT))
3432+
return true;
3433+
3434+
/*
3435+
* NUMA hinting faults don't apply in inaccessible (PROT_NONE) VMAs.
3436+
*
3437+
* Requiring a fault here even for inaccessible VMAs would mean that
3438+
* FOLL_FORCE cannot make any progress, because handle_mm_fault()
3439+
* refuses to process NUMA hinting faults in inaccessible VMAs.
3440+
*/
3441+
return !vma_is_accessible(vma);
34333442
}
34343443

34353444
typedef int (*pte_fn_t)(pte_t *pte, unsigned long addr, void *data);

include/linux/mm_types.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,6 +1286,15 @@ enum {
12861286
FOLL_PCI_P2PDMA = 1 << 10,
12871287
/* allow interrupts from generic signals */
12881288
FOLL_INTERRUPTIBLE = 1 << 11,
1289+
/*
1290+
* Always honor (trigger) NUMA hinting faults.
1291+
*
1292+
* FOLL_WRITE implicitly honors NUMA hinting faults because a
1293+
* PROT_NONE-mapped page is not writable (exceptions with FOLL_FORCE
1294+
* apply). get_user_pages_fast_only() always implicitly honors NUMA
1295+
* hinting faults.
1296+
*/
1297+
FOLL_HONOR_NUMA_FAULT = 1 << 12,
12891298

12901299
/* See also internal only FOLL flags in mm/internal.h */
12911300
};

include/linux/pagewalk.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@
66

77
struct mm_walk;
88

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+
919
/**
1020
* struct mm_walk_ops - callbacks for walk_page_range
1121
* @pgd_entry: if set, called for each non-empty PGD (top-level) entry
@@ -66,6 +76,7 @@ struct mm_walk_ops {
6676
int (*pre_vma)(unsigned long start, unsigned long end,
6777
struct mm_walk *walk);
6878
void (*post_vma)(struct mm_walk *walk);
79+
enum page_walk_lock walk_lock;
6980
};
7081

7182
/*

lib/maple_tree.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4265,6 +4265,10 @@ static inline unsigned char mas_wr_new_end(struct ma_wr_state *wr_mas)
42654265
* mas_wr_append: Attempt to append
42664266
* @wr_mas: the maple write state
42674267
*
4268+
* This is currently unsafe in rcu mode since the end of the node may be cached
4269+
* by readers while the node contents may be updated which could result in
4270+
* inaccurate information.
4271+
*
42684272
* Return: True if appended, false otherwise
42694273
*/
42704274
static inline bool mas_wr_append(struct ma_wr_state *wr_mas)
@@ -4274,6 +4278,9 @@ static inline bool mas_wr_append(struct ma_wr_state *wr_mas)
42744278
struct ma_state *mas = wr_mas->mas;
42754279
unsigned char node_pivots = mt_pivots[wr_mas->type];
42764280

4281+
if (mt_in_rcu(mas->tree))
4282+
return false;
4283+
42774284
if (mas->offset != wr_mas->node_end)
42784285
return false;
42794286

0 commit comments

Comments
 (0)