Skip to content

Commit

Permalink
Merge tag 'mm-hotfixes-stable-2025-01-04-18-02' of git://git.kernel.o…
Browse files Browse the repository at this point in the history
…rg/pub/scm/linux/kernel/git/akpm/mm

Pull hotfixes from Andrew Morton:
 "25 hotfixes.  16 are cc:stable.  18 are MM and 7 are non-MM.

  The usual bunch of singletons and two doubletons - please see the
  relevant changelogs for details"

* tag 'mm-hotfixes-stable-2025-01-04-18-02' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (25 commits)
  MAINTAINERS: change Arınç _NAL's name and email address
  scripts/sorttable: fix orc_sort_cmp() to maintain symmetry and transitivity
  mm/util: make memdup_user_nul() similar to memdup_user()
  mm, madvise: fix potential workingset node list_lru leaks
  mm/damon/core: fix ignored quota goals and filters of newly committed schemes
  mm/damon/core: fix new damon_target objects leaks on damon_commit_targets()
  mm/list_lru: fix false warning of negative counter
  vmstat: disable vmstat_work on vmstat_cpu_down_prep()
  mm: shmem: fix the update of 'shmem_falloc->nr_unswapped'
  mm: shmem: fix incorrect index alignment for within_size policy
  percpu: remove intermediate variable in PERCPU_PTR()
  mm: zswap: fix race between [de]compression and CPU hotunplug
  ocfs2: fix slab-use-after-free due to dangling pointer dqi_priv
  fs/proc/task_mmu: fix pagemap flags with PMD THP entries on 32bit
  kcov: mark in_softirq_really() as __always_inline
  docs: mm: fix the incorrect 'FileHugeMapped' field
  mailmap: modify the entry for Mathieu Othacehe
  mm/kmemleak: fix sleeping function called from invalid context at print message
  mm: hugetlb: independent PMD page table shared count
  maple_tree: reload mas before the second call for mas_empty_area
  ...
  • Loading branch information
Linus Torvalds committed Jan 5, 2025
2 parents 7a5b6fc + e740492 commit 5635d8b
Show file tree
Hide file tree
Showing 29 changed files with 212 additions and 69 deletions.
2 changes: 1 addition & 1 deletion .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ Martin Kepplinger <martink@posteo.de> <martin.kepplinger@ginzinger.com>
Martin Kepplinger <martink@posteo.de> <martin.kepplinger@puri.sm>
Martin Kepplinger <martink@posteo.de> <martin.kepplinger@theobroma-systems.com>
Martyna Szapar-Mudlaw <martyna.szapar-mudlaw@linux.intel.com> <martyna.szapar-mudlaw@intel.com>
Mathieu Othacehe <m.othacehe@gmail.com> <othacehe@gnu.org>
Mathieu Othacehe <othacehe@gnu.org> <m.othacehe@gmail.com>
Mat Martineau <martineau@kernel.org> <mathew.j.martineau@linux.intel.com>
Mat Martineau <martineau@kernel.org> <mathewm@codeaurora.org>
Matthew Wilcox <willy@infradead.org> <matthew.r.wilcox@intel.com>
Expand Down
2 changes: 1 addition & 1 deletion Documentation/admin-guide/mm/transhuge.rst
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ AnonHugePmdMapped).
The number of file transparent huge pages mapped to userspace is available
by reading ShmemPmdMapped and ShmemHugePages fields in ``/proc/meminfo``.
To identify what applications are mapping file transparent huge pages, it
is necessary to read ``/proc/PID/smaps`` and count the FileHugeMapped fields
is necessary to read ``/proc/PID/smaps`` and count the FilePmdMapped fields
for each mapping.

Note that reading the smaps file is expensive and reading it
Expand Down
6 changes: 3 additions & 3 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -14756,7 +14756,7 @@ F: drivers/memory/mtk-smi.c
F: include/soc/mediatek/smi.h

MEDIATEK SWITCH DRIVER
M: Arınç ÜNAL <arinc.unal@arinc9.com>
M: Chester A. Unal <chester.a.unal@arinc9.com>
M: Daniel Golle <daniel@makrotopia.org>
M: DENG Qingfang <dqfext@gmail.com>
M: Sean Wang <sean.wang@mediatek.com>
Expand Down Expand Up @@ -18460,7 +18460,7 @@ F: Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml
F: drivers/pinctrl/mediatek/

PIN CONTROLLER - MEDIATEK MIPS
M: Arınç ÜNAL <arinc.unal@arinc9.com>
M: Chester A. Unal <chester.a.unal@arinc9.com>
M: Sergio Paracuellos <sergio.paracuellos@gmail.com>
L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
L: linux-mips@vger.kernel.org
Expand Down Expand Up @@ -19504,7 +19504,7 @@ S: Maintained
F: arch/mips/ralink

RALINK MT7621 MIPS ARCHITECTURE
M: Arınç ÜNAL <arinc.unal@arinc9.com>
M: Chester A. Unal <chester.a.unal@arinc9.com>
M: Sergio Paracuellos <sergio.paracuellos@gmail.com>
L: linux-mips@vger.kernel.org
S: Maintained
Expand Down
2 changes: 1 addition & 1 deletion fs/ocfs2/quota_global.c
Original file line number Diff line number Diff line change
Expand Up @@ -893,7 +893,7 @@ static int ocfs2_get_next_id(struct super_block *sb, struct kqid *qid)
int status = 0;

trace_ocfs2_get_next_id(from_kqid(&init_user_ns, *qid), type);
if (!sb_has_quota_loaded(sb, type)) {
if (!sb_has_quota_active(sb, type)) {
status = -ESRCH;
goto out;
}
Expand Down
1 change: 1 addition & 0 deletions fs/ocfs2/quota_local.c
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,7 @@ static int ocfs2_local_free_info(struct super_block *sb, int type)
brelse(oinfo->dqi_libh);
brelse(oinfo->dqi_lqi_bh);
kfree(oinfo);
info->dqi_priv = NULL;
return status;
}

Expand Down
2 changes: 1 addition & 1 deletion fs/proc/task_mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1810,7 +1810,7 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end,
}

for (; addr != end; addr += PAGE_SIZE, idx++) {
unsigned long cur_flags = flags;
u64 cur_flags = flags;
pagemap_entry_t pme;

if (folio && (flags & PM_PRESENT) &&
Expand Down
14 changes: 14 additions & 0 deletions include/linux/memfd.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifdef CONFIG_MEMFD_CREATE
extern long memfd_fcntl(struct file *file, unsigned int cmd, unsigned int arg);
struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx);
unsigned int *memfd_file_seals_ptr(struct file *file);
#else
static inline long memfd_fcntl(struct file *f, unsigned int c, unsigned int a)
{
Expand All @@ -16,6 +17,19 @@ static inline struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx)
{
return ERR_PTR(-EINVAL);
}

static inline unsigned int *memfd_file_seals_ptr(struct file *file)
{
return NULL;
}
#endif

/* Retrieve memfd seals associated with the file, if any. */
static inline unsigned int memfd_file_seals(struct file *file)
{
unsigned int *sealsp = memfd_file_seals_ptr(file);

return sealsp ? *sealsp : 0;
}

#endif /* __LINUX_MEMFD_H */
59 changes: 41 additions & 18 deletions include/linux/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -3125,6 +3125,7 @@ static inline bool pagetable_pmd_ctor(struct ptdesc *ptdesc)
if (!pmd_ptlock_init(ptdesc))
return false;
__folio_set_pgtable(folio);
ptdesc_pmd_pts_init(ptdesc);
lruvec_stat_add_folio(folio, NR_PAGETABLE);
return true;
}
Expand Down Expand Up @@ -4101,6 +4102,37 @@ void mem_dump_obj(void *object);
static inline void mem_dump_obj(void *object) {}
#endif

static inline bool is_write_sealed(int seals)
{
return seals & (F_SEAL_WRITE | F_SEAL_FUTURE_WRITE);
}

/**
* is_readonly_sealed - Checks whether write-sealed but mapped read-only,
* in which case writes should be disallowing moving
* forwards.
* @seals: the seals to check
* @vm_flags: the VMA flags to check
*
* Returns whether readonly sealed, in which case writess should be disallowed
* going forward.
*/
static inline bool is_readonly_sealed(int seals, vm_flags_t vm_flags)
{
/*
* Since an F_SEAL_[FUTURE_]WRITE sealed memfd can be mapped as
* MAP_SHARED and read-only, take care to not allow mprotect to
* revert protections on such mappings. Do this only for shared
* mappings. For private mappings, don't need to mask
* VM_MAYWRITE as we still want them to be COW-writable.
*/
if (is_write_sealed(seals) &&
((vm_flags & (VM_SHARED | VM_WRITE)) == VM_SHARED))
return true;

return false;
}

/**
* seal_check_write - Check for F_SEAL_WRITE or F_SEAL_FUTURE_WRITE flags and
* handle them.
Expand All @@ -4112,24 +4144,15 @@ static inline void mem_dump_obj(void *object) {}
*/
static inline int seal_check_write(int seals, struct vm_area_struct *vma)
{
if (seals & (F_SEAL_WRITE | F_SEAL_FUTURE_WRITE)) {
/*
* New PROT_WRITE and MAP_SHARED mmaps are not allowed when
* write seals are active.
*/
if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_WRITE))
return -EPERM;

/*
* Since an F_SEAL_[FUTURE_]WRITE sealed memfd can be mapped as
* MAP_SHARED and read-only, take care to not allow mprotect to
* revert protections on such mappings. Do this only for shared
* mappings. For private mappings, don't need to mask
* VM_MAYWRITE as we still want them to be COW-writable.
*/
if (vma->vm_flags & VM_SHARED)
vm_flags_clear(vma, VM_MAYWRITE);
}
if (!is_write_sealed(seals))
return 0;

/*
* New PROT_WRITE and MAP_SHARED mmaps are not allowed when
* write seals are active.
*/
if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_WRITE))
return -EPERM;

return 0;
}
Expand Down
30 changes: 30 additions & 0 deletions include/linux/mm_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,7 @@ FOLIO_MATCH(compound_head, _head_2a);
* @pt_index: Used for s390 gmap.
* @pt_mm: Used for x86 pgds.
* @pt_frag_refcount: For fragmented page table tracking. Powerpc only.
* @pt_share_count: Used for HugeTLB PMD page table share count.
* @_pt_pad_2: Padding to ensure proper alignment.
* @ptl: Lock for the page table.
* @__page_type: Same as page->page_type. Unused for page tables.
Expand All @@ -471,6 +472,9 @@ struct ptdesc {
pgoff_t pt_index;
struct mm_struct *pt_mm;
atomic_t pt_frag_refcount;
#ifdef CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING
atomic_t pt_share_count;
#endif
};

union {
Expand Down Expand Up @@ -516,6 +520,32 @@ static_assert(sizeof(struct ptdesc) <= sizeof(struct page));
const struct page *: (const struct ptdesc *)(p), \
struct page *: (struct ptdesc *)(p)))

#ifdef CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING
static inline void ptdesc_pmd_pts_init(struct ptdesc *ptdesc)
{
atomic_set(&ptdesc->pt_share_count, 0);
}

static inline void ptdesc_pmd_pts_inc(struct ptdesc *ptdesc)
{
atomic_inc(&ptdesc->pt_share_count);
}

static inline void ptdesc_pmd_pts_dec(struct ptdesc *ptdesc)
{
atomic_dec(&ptdesc->pt_share_count);
}

static inline int ptdesc_pmd_pts_count(struct ptdesc *ptdesc)
{
return atomic_read(&ptdesc->pt_share_count);
}
#else
static inline void ptdesc_pmd_pts_init(struct ptdesc *ptdesc)
{
}
#endif

/*
* Used for sizing the vmemmap region on some architectures
*/
Expand Down
5 changes: 1 addition & 4 deletions include/linux/percpu-defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,7 @@ do { \
} while (0)

#define PERCPU_PTR(__p) \
({ \
unsigned long __pcpu_ptr = (__force unsigned long)(__p); \
(typeof(*(__p)) __force __kernel *)(__pcpu_ptr); \
})
(typeof(*(__p)) __force __kernel *)((__force unsigned long)(__p))

#ifdef CONFIG_SMP

Expand Down
2 changes: 1 addition & 1 deletion kernel/kcov.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ static void kcov_remote_area_put(struct kcov_remote_area *area,
* Unlike in_serving_softirq(), this function returns false when called during
* a hardirq or an NMI that happened in the softirq context.
*/
static inline bool in_softirq_really(void)
static __always_inline bool in_softirq_really(void)
{
return in_serving_softirq() && !in_hardirq() && !in_nmi();
}
Expand Down
1 change: 1 addition & 0 deletions lib/maple_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -4354,6 +4354,7 @@ int mas_alloc_cyclic(struct ma_state *mas, unsigned long *startp,
ret = 1;
}
if (ret < 0 && range_lo > min) {
mas_reset(mas);
ret = mas_empty_area(mas, min, range_hi, 1);
if (ret == 0)
ret = 1;
Expand Down
10 changes: 9 additions & 1 deletion mm/damon/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,11 @@ static int damon_commit_schemes(struct damon_ctx *dst, struct damon_ctx *src)
NUMA_NO_NODE);
if (!new_scheme)
return -ENOMEM;
err = damos_commit(new_scheme, src_scheme);
if (err) {
damon_destroy_scheme(new_scheme);
return err;
}
damon_add_scheme(dst, new_scheme);
}
return 0;
Expand Down Expand Up @@ -961,8 +966,11 @@ static int damon_commit_targets(
return -ENOMEM;
err = damon_commit_target(new_target, false,
src_target, damon_target_has_pid(src));
if (err)
if (err) {
damon_destroy_target(new_target);
return err;
}
damon_add_target(dst, new_target);
}
return 0;
}
Expand Down
9 changes: 0 additions & 9 deletions mm/filemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,6 @@
* ->private_lock (zap_pte_range->block_dirty_folio)
*/

static void mapping_set_update(struct xa_state *xas,
struct address_space *mapping)
{
if (dax_mapping(mapping) || shmem_mapping(mapping))
return;
xas_set_update(xas, workingset_update_node);
xas_set_lru(xas, &shadow_nodes);
}

static void page_cache_delete(struct address_space *mapping,
struct folio *folio, void *shadow)
{
Expand Down
16 changes: 7 additions & 9 deletions mm/hugetlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -7211,7 +7211,7 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,
spte = hugetlb_walk(svma, saddr,
vma_mmu_pagesize(svma));
if (spte) {
get_page(virt_to_page(spte));
ptdesc_pmd_pts_inc(virt_to_ptdesc(spte));
break;
}
}
Expand All @@ -7226,7 +7226,7 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,
(pmd_t *)((unsigned long)spte & PAGE_MASK));
mm_inc_nr_pmds(mm);
} else {
put_page(virt_to_page(spte));
ptdesc_pmd_pts_dec(virt_to_ptdesc(spte));
}
spin_unlock(&mm->page_table_lock);
out:
Expand All @@ -7238,10 +7238,6 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,
/*
* unmap huge page backed by shared pte.
*
* Hugetlb pte page is ref counted at the time of mapping. If pte is shared
* indicated by page_count > 1, unmap is achieved by clearing pud and
* decrementing the ref count. If count == 1, the pte page is not shared.
*
* Called with page table lock held.
*
* returns: 1 successfully unmapped a shared pte page
Expand All @@ -7250,18 +7246,20 @@ pte_t *huge_pmd_share(struct mm_struct *mm, struct vm_area_struct *vma,
int huge_pmd_unshare(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep)
{
unsigned long sz = huge_page_size(hstate_vma(vma));
pgd_t *pgd = pgd_offset(mm, addr);
p4d_t *p4d = p4d_offset(pgd, addr);
pud_t *pud = pud_offset(p4d, addr);

i_mmap_assert_write_locked(vma->vm_file->f_mapping);
hugetlb_vma_assert_locked(vma);
BUG_ON(page_count(virt_to_page(ptep)) == 0);
if (page_count(virt_to_page(ptep)) == 1)
if (sz != PMD_SIZE)
return 0;
if (!ptdesc_pmd_pts_count(virt_to_ptdesc(ptep)))
return 0;

pud_clear(pud);
put_page(virt_to_page(ptep));
ptdesc_pmd_pts_dec(virt_to_ptdesc(ptep));
mm_dec_nr_pmds(mm);
return 1;
}
Expand Down
6 changes: 6 additions & 0 deletions mm/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1504,6 +1504,12 @@ static inline void shrinker_debugfs_remove(struct dentry *debugfs_entry,
/* Only track the nodes of mappings with shadow entries */
void workingset_update_node(struct xa_node *node);
extern struct list_lru shadow_nodes;
#define mapping_set_update(xas, mapping) do { \
if (!dax_mapping(mapping) && !shmem_mapping(mapping)) { \
xas_set_update(xas, workingset_update_node); \
xas_set_lru(xas, &shadow_nodes); \
} \
} while (0)

/* mremap.c */
unsigned long move_page_tables(struct vm_area_struct *vma,
Expand Down
3 changes: 3 additions & 0 deletions mm/khugepaged.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/rcupdate_wait.h>
#include <linux/swapops.h>
#include <linux/shmem_fs.h>
#include <linux/dax.h>
#include <linux/ksm.h>

#include <asm/tlb.h>
Expand Down Expand Up @@ -1837,6 +1838,8 @@ static int collapse_file(struct mm_struct *mm, unsigned long addr,
if (result != SCAN_SUCCEED)
goto out;

mapping_set_update(&xas, mapping);

__folio_set_locked(new_folio);
if (is_shmem)
__folio_set_swapbacked(new_folio);
Expand Down
2 changes: 1 addition & 1 deletion mm/kmemleak.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ static void print_unreferenced(struct seq_file *seq,

for (i = 0; i < nr_entries; i++) {
void *ptr = (void *)entries[i];
warn_or_seq_printf(seq, " [<%pK>] %pS\n", ptr, ptr);
warn_or_seq_printf(seq, " %pS\n", ptr);
}
}

Expand Down
Loading

0 comments on commit 5635d8b

Please sign in to comment.