Pull misc fixes from Andrew Morton: "16 hotfixes. 6 are cc:stable and the remainder address post-6.15 issues or aren't considered necessary for -stable kernels. 5 are for MM" * tag 'mm-hotfixes-stable-2025-06-27-16-56' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: MAINTAINERS: add Lorenzo as THP co-maintainer mailmap: update Duje Mihanović's email address selftests/mm: fix validate_addr() helper crashdump: add CONFIG_KEYS dependency mailmap: correct name for a historical account of Zijun Hu mailmap: add entries for Zijun Hu fuse: fix runtime warning on truncate_folio_batch_exceptionals() scripts/gdb: fix dentry_name() lookup mm/damon/sysfs-schemes: free old damon_sysfs_scheme_filter->memcg_path on write mm/alloc_tag: fix the kmemleak false positive issue in the allocation of the percpu variable tag->counters lib/group_cpus: fix NULL pointer dereference from group_cpus_evenly() mm/hugetlb: remove unnecessary holding of hugetlb_lock MAINTAINERS: add missing files to mm page alloc section MAINTAINERS: add tree entry to mm init block mm: add OOM killer maintainer structure fs/proc/task_mmu: fix PAGE_IS_PFNZERO detection for the huge zero folio
Unified · Split
| @@ -224,6 +224,7 @@ Dmitry Safonov <0x7f454c46@gmail.com> <dsafonov@virtuozzo.com> · 223 unmodified lines | ||
| 224 | 224 | Domen Puncer <domen@coderock.org> |
| 225 | 225 | Douglas Gilbert <dougg@torque.net> |
| 226 | 226 | Drew Fustini <fustini@kernel.org> <drew@pdp7.com> |
| 227 | +<duje@dujemihanovic.xyz> <duje.mihanovic@skole.hr> | |
| 227 | 228 | Ed L. Cashin <ecashin@coraid.com> |
| 228 | 229 | Elliot Berman <quic_eberman@quicinc.com> <eberman@codeaurora.org> |
| 229 | 230 | Enric Balletbo i Serra <eballetbo@kernel.org> <enric.balletbo@collabora.com> |
| @@ -831,3 +832,6 @@ Yosry Ahmed <yosry.ahmed@linux.dev> <yosryahmed@google.com> · 601 unmodified lines | ||
| 831 | 832 | Yusuke Goda <goda.yusuke@renesas.com> |
| 832 | 833 | Zack Rusin <zack.rusin@broadcom.com> <zackr@vmware.com> |
| 833 | 834 | Zhu Yanjun <zyjzyj2000@gmail.com> <yanjunz@nvidia.com> |
| 835 | +Zijun Hu <zijun.hu@oss.qualcomm.com> <quic_zijuhu@quicinc.com> | |
| 836 | +Zijun Hu <zijun.hu@oss.qualcomm.com> <zijuhu@codeaurora.org> | |
| 837 | +Zijun Hu <zijun_hu@htc.com> | |
| @@ -15676,6 +15676,8 @@ MEMBLOCK AND MEMORY MANAGEMENT INITIALIZATION · 15675 unmodified lines | ||
| 15676 | 15676 | M: Mike Rapoport <rppt@kernel.org> |
| 15677 | 15677 | L: linux-mm@kvack.org |
| 15678 | 15678 | S: Maintained |
| 15679 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock.git for-next | |
| 15680 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock.git fixes | |
| 15679 | 15681 | F: Documentation/core-api/boot-time-mm.rst |
| 15680 | 15682 | F: Documentation/core-api/kho/bindings/memblock/* |
| 15681 | 15683 | F: include/linux/memblock.h |
| @@ -15848,6 +15850,17 @@ F: mm/numa.c · 166 unmodified lines | ||
| 15848 | 15850 | F: mm/numa_emulation.c |
| 15849 | 15851 | F: mm/numa_memblks.c |
| 15850 | 15852 | |
| 15853 | +MEMORY MANAGEMENT - OOM KILLER | |
| 15854 | +M: Michal Hocko <mhocko@suse.com> | |
| 15855 | +R: David Rientjes <rientjes@google.com> | |
| 15856 | +R: Shakeel Butt <shakeel.butt@linux.dev> | |
| 15857 | +L: linux-mm@kvack.org | |
| 15858 | +S: Maintained | |
| 15859 | +F: include/linux/oom.h | |
| 15860 | +F: include/trace/events/oom.h | |
| 15861 | +F: include/uapi/linux/oom.h | |
| 15862 | +F: mm/oom_kill.c | |
| 15863 | + | |
| 15851 | 15864 | MEMORY MANAGEMENT - PAGE ALLOCATOR |
| 15852 | 15865 | M: Andrew Morton <akpm@linux-foundation.org> |
| 15853 | 15866 | M: Vlastimil Babka <vbabka@suse.cz> |
| @@ -15862,8 +15875,17 @@ F: include/linux/compaction.h · 8 unmodified lines | ||
| 15862 | 15875 | F: include/linux/gfp.h |
| 15863 | 15876 | F: include/linux/page-isolation.h |
| 15864 | 15877 | F: mm/compaction.c |
| 15878 | +F: mm/debug_page_alloc.c | |
| 15879 | +F: mm/fail_page_alloc.c | |
| 15865 | 15880 | F: mm/page_alloc.c |
| 15881 | +F: mm/page_ext.c | |
| 15882 | +F: mm/page_frag_cache.c | |
| 15866 | 15883 | F: mm/page_isolation.c |
| 15884 | +F: mm/page_owner.c | |
| 15885 | +F: mm/page_poison.c | |
| 15886 | +F: mm/page_reporting.c | |
| 15887 | +F: mm/show_mem.c | |
| 15888 | +F: mm/shuffle.c | |
| 15867 | 15889 | |
| 15868 | 15890 | MEMORY MANAGEMENT - RECLAIM |
| 15869 | 15891 | M: Andrew Morton <akpm@linux-foundation.org> |
| @@ -15923,9 +15945,9 @@ F: mm/swapfile.c · 53 unmodified lines | ||
| 15923 | 15945 | MEMORY MANAGEMENT - THP (TRANSPARENT HUGE PAGE) |
| 15924 | 15946 | M: Andrew Morton <akpm@linux-foundation.org> |
| 15925 | 15947 | M: David Hildenbrand <david@redhat.com> |
| 15948 | +M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | |
| 15926 | 15949 | R: Zi Yan <ziy@nvidia.com> |
| 15927 | 15950 | R: Baolin Wang <baolin.wang@linux.alibaba.com> |
| 15928 | −R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | |
| 15929 | 15951 | R: Liam R. Howlett <Liam.Howlett@oracle.com> |
| 15930 | 15952 | R: Nico Pache <npache@redhat.com> |
| 15931 | 15953 | R: Ryan Roberts <ryan.roberts@arm.com> |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | #include "fuse_i.h" |
| 10 | 10 | #include "dev_uring_i.h" |
| 11 | 11 | |
| 12 | +#include <linux/dax.h> | |
| 12 | 13 | #include <linux/pagemap.h> |
| 13 | 14 | #include <linux/slab.h> |
| 14 | 15 | #include <linux/file.h> |
| @@ -162,6 +163,9 @@ static void fuse_evict_inode(struct inode *inode) · 147 unmodified lines | ||
| 162 | 163 | /* Will write inode on close/munmap and in all other dirtiers */ |
| 163 | 164 | WARN_ON(inode->i_state & I_DIRTY_INODE); |
| 164 | 165 | |
| 166 | + if (FUSE_IS_DAX(inode)) | |
| 167 | + dax_break_layout_final(inode); | |
| 168 | + | |
| 165 | 169 | truncate_inode_pages_final(&inode->i_data); |
| 166 | 170 | clear_inode(inode); |
| 167 | 171 | if (inode->i_sb->s_flags & SB_ACTIVE) { |
| @@ -2182,7 +2182,7 @@ static unsigned long pagemap_thp_category(struct pagemap_scan_private *p, · 2181 unmodified lines | ||
| 2182 | 2182 | categories |= PAGE_IS_FILE; |
| 2183 | 2183 | } |
| 2184 | 2184 | |
| 2185 | − if (is_zero_pfn(pmd_pfn(pmd))) | |
| 2185 | + if (is_huge_zero_pmd(pmd)) | |
| 2186 | 2186 | categories |= PAGE_IS_PFNZERO; |
| 2187 | 2187 | if (pmd_soft_dirty(pmd)) |
| 2188 | 2188 | categories |= PAGE_IS_SOFT_DIRTY; |
| @@ -28,6 +28,7 @@ extern void kmemleak_update_trace(const void *ptr) __ref; · 27 unmodified lines | ||
| 28 | 28 | extern void kmemleak_not_leak(const void *ptr) __ref; |
| 29 | 29 | extern void kmemleak_transient_leak(const void *ptr) __ref; |
| 30 | 30 | extern void kmemleak_ignore(const void *ptr) __ref; |
| 31 | +extern void kmemleak_ignore_percpu(const void __percpu *ptr) __ref; | |
| 31 | 32 | extern void kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) __ref; |
| 32 | 33 | extern void kmemleak_no_scan(const void *ptr) __ref; |
| 33 | 34 | extern void kmemleak_alloc_phys(phys_addr_t phys, size_t size, |
| @@ -97,6 +98,9 @@ static inline void kmemleak_not_leak(const void *ptr) · 63 unmodified lines | ||
| 97 | 98 | static inline void kmemleak_transient_leak(const void *ptr) |
| 98 | 99 | { |
| 99 | 100 | } |
| 101 | +static inline void kmemleak_ignore_percpu(const void __percpu *ptr) | |
| 102 | +{ | |
| 103 | +} | |
| 100 | 104 | static inline void kmemleak_ignore(const void *ptr) |
| 101 | 105 | { |
| 102 | 106 | } |
| @@ -134,6 +134,7 @@ config CRASH_DM_CRYPT · 133 unmodified lines | ||
| 134 | 134 | depends on KEXEC_FILE |
| 135 | 135 | depends on CRASH_DUMP |
| 136 | 136 | depends on DM_CRYPT |
| 137 | + depends on KEYS | |
| 137 | 138 | help |
| 138 | 139 | With this option enabled, user space can intereact with |
| 139 | 140 | /sys/kernel/config/crash_dm_crypt_keys to make the dm crypt keys |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <linux/seq_buf.h> |
| 11 | 11 | #include <linux/seq_file.h> |
| 12 | 12 | #include <linux/vmalloc.h> |
| 13 | +#include <linux/kmemleak.h> | |
| 13 | 14 | |
| 14 | 15 | #define ALLOCINFO_FILE_NAME "allocinfo" |
| 15 | 16 | #define MODULE_ALLOC_TAG_VMAP_SIZE (100000UL * sizeof(struct alloc_tag)) |
| @@ -632,8 +633,13 @@ static int load_module(struct module *mod, struct codetag *start, struct codetag · 616 unmodified lines | ||
| 632 | 633 | mod->name); |
| 633 | 634 | return -ENOMEM; |
| 634 | 635 | } |
| 635 | − } | |
| 636 | 636 | |
| 637 | + /* | |
| 638 | + * Avoid a kmemleak false positive. The pointer to the counters is stored | |
| 639 | + * in the alloc_tag section of the module and cannot be directly accessed. | |
| 640 | + */ | |
| 641 | + kmemleak_ignore_percpu(tag->counters); | |
| 642 | + } | |
| 637 | 643 | return 0; |
| 638 | 644 | } |
| 639 | 645 | |
| @@ -352,6 +352,9 @@ struct cpumask *group_cpus_evenly(unsigned int numgrps) · 351 unmodified lines | ||
| 352 | 352 | int ret = -ENOMEM; |
| 353 | 353 | struct cpumask *masks = NULL; |
| 354 | 354 | |
| 355 | + if (numgrps == 0) | |
| 356 | + return NULL; | |
| 357 | + | |
| 355 | 358 | if (!zalloc_cpumask_var(&nmsk, GFP_KERNEL)) |
| 356 | 359 | return NULL; |
| 357 | 360 | |
| @@ -426,8 +429,12 @@ struct cpumask *group_cpus_evenly(unsigned int numgrps) · 68 unmodified lines | ||
| 426 | 429 | #else /* CONFIG_SMP */ |
| 427 | 430 | struct cpumask *group_cpus_evenly(unsigned int numgrps) |
| 428 | 431 | { |
| 429 | − struct cpumask *masks = kcalloc(numgrps, sizeof(*masks), GFP_KERNEL); | |
| 432 | + struct cpumask *masks; | |
| 430 | 433 | |
| 434 | + if (numgrps == 0) | |
| 435 | + return NULL; | |
| 436 | + | |
| 437 | + masks = kcalloc(numgrps, sizeof(*masks), GFP_KERNEL); | |
| 431 | 438 | if (!masks) |
| 432 | 439 | return NULL; |
| 433 | 440 | |
| @@ -472,6 +472,7 @@ static ssize_t memcg_path_store(struct kobject *kobj, · 471 unmodified lines | ||
| 472 | 472 | return -ENOMEM; |
| 473 | 473 | |
| 474 | 474 | strscpy(path, buf, count + 1); |
| 475 | + kfree(filter->memcg_path); | |
| 475 | 476 | filter->memcg_path = path; |
| 476 | 477 | return count; |
| 477 | 478 | } |
| @@ -2787,20 +2787,24 @@ void restore_reserve_on_error(struct hstate *h, struct vm_area_struct *vma, · 2786 unmodified lines | ||
| 2787 | 2787 | /* |
| 2788 | 2788 | * alloc_and_dissolve_hugetlb_folio - Allocate a new folio and dissolve |
| 2789 | 2789 | * the old one |
| 2790 | − * @h: struct hstate old page belongs to | |
| 2791 | 2790 | * @old_folio: Old folio to dissolve |
| 2792 | 2791 | * @list: List to isolate the page in case we need to |
| 2793 | 2792 | * Returns 0 on success, otherwise negated error. |
| 2794 | 2793 | */ |
| 2795 | −static int alloc_and_dissolve_hugetlb_folio(struct hstate *h, | |
| 2796 | − struct folio *old_folio, struct list_head *list) | |
| 2794 | +static int alloc_and_dissolve_hugetlb_folio(struct folio *old_folio, | |
| 2795 | + struct list_head *list) | |
| 2797 | 2796 | { |
| 2798 | − gfp_t gfp_mask = htlb_alloc_mask(h) | __GFP_THISNODE; | |
| 2797 | + gfp_t gfp_mask; | |
| 2798 | + struct hstate *h; | |
| 2799 | 2799 | int nid = folio_nid(old_folio); |
| 2800 | 2800 | struct folio *new_folio = NULL; |
| 2801 | 2801 | int ret = 0; |
| 2802 | 2802 | |
| 2803 | 2803 | retry: |
| 2804 | + /* | |
| 2805 | + * The old_folio might have been dissolved from under our feet, so make sure | |
| 2806 | + * to carefully check the state under the lock. | |
| 2807 | + */ | |
| 2804 | 2808 | spin_lock_irq(&hugetlb_lock); |
| 2805 | 2809 | if (!folio_test_hugetlb(old_folio)) { |
| 2806 | 2810 | /* |
| @@ -2829,8 +2833,10 @@ retry: · 22 unmodified lines | ||
| 2829 | 2833 | cond_resched(); |
| 2830 | 2834 | goto retry; |
| 2831 | 2835 | } else { |
| 2836 | + h = folio_hstate(old_folio); | |
| 2832 | 2837 | if (!new_folio) { |
| 2833 | 2838 | spin_unlock_irq(&hugetlb_lock); |
| 2839 | + gfp_mask = htlb_alloc_mask(h) | __GFP_THISNODE; | |
| 2834 | 2840 | new_folio = alloc_buddy_hugetlb_folio(h, gfp_mask, nid, |
| 2835 | 2841 | NULL, NULL); |
| 2836 | 2842 | if (!new_folio) |
| @@ -2874,35 +2880,24 @@ free_new: · 37 unmodified lines | ||
| 2874 | 2880 | |
| 2875 | 2881 | int isolate_or_dissolve_huge_folio(struct folio *folio, struct list_head *list) |
| 2876 | 2882 | { |
| 2877 | − struct hstate *h; | |
| 2878 | 2883 | int ret = -EBUSY; |
| 2879 | 2884 | |
| 2880 | − /* | |
| 2881 | − * The page might have been dissolved from under our feet, so make sure | |
| 2882 | − * to carefully check the state under the lock. | |
| 2883 | − * Return success when racing as if we dissolved the page ourselves. | |
| 2884 | − */ | |
| 2885 | − spin_lock_irq(&hugetlb_lock); | |
| 2886 | − if (folio_test_hugetlb(folio)) { | |
| 2887 | − h = folio_hstate(folio); | |
| 2888 | − } else { | |
| 2889 | − spin_unlock_irq(&hugetlb_lock); | |
| 2885 | + /* Not to disrupt normal path by vainly holding hugetlb_lock */ | |
| 2886 | + if (!folio_test_hugetlb(folio)) | |
| 2890 | 2887 | return 0; |
| 2891 | − } | |
| 2892 | − spin_unlock_irq(&hugetlb_lock); | |
| 2893 | 2888 | |
| 2894 | 2889 | /* |
| 2895 | 2890 | * Fence off gigantic pages as there is a cyclic dependency between |
| 2896 | 2891 | * alloc_contig_range and them. Return -ENOMEM as this has the effect |
| 2897 | 2892 | * of bailing out right away without further retrying. |
| 2898 | 2893 | */ |
| 2899 | − if (hstate_is_gigantic(h)) | |
| 2894 | + if (folio_order(folio) > MAX_PAGE_ORDER) | |
| 2900 | 2895 | return -ENOMEM; |
| 2901 | 2896 | |
| 2902 | 2897 | if (folio_ref_count(folio) && folio_isolate_hugetlb(folio, list)) |
| 2903 | 2898 | ret = 0; |
| 2904 | 2899 | else if (!folio_ref_count(folio)) |
| 2905 | − ret = alloc_and_dissolve_hugetlb_folio(h, folio, list); | |
| 2900 | + ret = alloc_and_dissolve_hugetlb_folio(folio, list); | |
| 2906 | 2901 | |
| 2907 | 2902 | return ret; |
| 2908 | 2903 | } |
| @@ -2916,7 +2911,6 @@ int isolate_or_dissolve_huge_folio(struct folio *folio, struct list_head *list) · 7 unmodified lines | ||
| 2916 | 2911 | */ |
| 2917 | 2912 | int replace_free_hugepage_folios(unsigned long start_pfn, unsigned long end_pfn) |
| 2918 | 2913 | { |
| 2919 | − struct hstate *h; | |
| 2920 | 2914 | struct folio *folio; |
| 2921 | 2915 | int ret = 0; |
| 2922 | 2916 | |
| @@ -2925,23 +2919,9 @@ int replace_free_hugepage_folios(unsigned long start_pfn, unsigned long end_pfn) · 2 unmodified lines | ||
| 2925 | 2919 | while (start_pfn < end_pfn) { |
| 2926 | 2920 | folio = pfn_folio(start_pfn); |
| 2927 | 2921 | |
| 2928 | − /* | |
| 2929 | − * The folio might have been dissolved from under our feet, so make sure | |
| 2930 | − * to carefully check the state under the lock. | |
| 2931 | − */ | |
| 2932 | − spin_lock_irq(&hugetlb_lock); | |
| 2933 | − if (folio_test_hugetlb(folio)) { | |
| 2934 | − h = folio_hstate(folio); | |
| 2935 | − } else { | |
| 2936 | − spin_unlock_irq(&hugetlb_lock); | |
| 2937 | − start_pfn++; | |
| 2938 | − continue; | |
| 2939 | − } | |
| 2940 | − spin_unlock_irq(&hugetlb_lock); | |
| 2941 | − | |
| 2942 | − if (!folio_ref_count(folio)) { | |
| 2943 | − ret = alloc_and_dissolve_hugetlb_folio(h, folio, | |
| 2944 | − &isolate_list); | |
| 2922 | + /* Not to disrupt normal path by vainly holding hugetlb_lock */ | |
| 2923 | + if (folio_test_hugetlb(folio) && !folio_ref_count(folio)) { | |
| 2924 | + ret = alloc_and_dissolve_hugetlb_folio(folio, &isolate_list); | |
| 2945 | 2925 | if (ret) |
| 2946 | 2926 | break; |
| 2947 | 2927 | |
| @@ -1246,6 +1246,20 @@ void __ref kmemleak_transient_leak(const void *ptr) · 1245 unmodified lines | ||
| 1246 | 1246 | } |
| 1247 | 1247 | EXPORT_SYMBOL(kmemleak_transient_leak); |
| 1248 | 1248 | |
| 1249 | +/** | |
| 1250 | + * kmemleak_ignore_percpu - similar to kmemleak_ignore but taking a percpu | |
| 1251 | + * address argument | |
| 1252 | + * @ptr: percpu address of the object | |
| 1253 | + */ | |
| 1254 | +void __ref kmemleak_ignore_percpu(const void __percpu *ptr) | |
| 1255 | +{ | |
| 1256 | + pr_debug("%s(0x%px)\n", __func__, ptr); | |
| 1257 | + | |
| 1258 | + if (kmemleak_enabled && ptr && !IS_ERR_PCPU(ptr)) | |
| 1259 | + make_black_object((unsigned long)ptr, OBJECT_PERCPU); | |
| 1260 | +} | |
| 1261 | +EXPORT_SYMBOL_GPL(kmemleak_ignore_percpu); | |
| 1262 | + | |
| 1249 | 1263 | /** |
| 1250 | 1264 | * kmemleak_ignore - ignore an allocated object |
| 1251 | 1265 | * @ptr: pointer to beginning of the object |
| @@ -22,7 +22,7 @@ def dentry_name(d): · 21 unmodified lines | ||
| 22 | 22 | if parent == d or parent == 0: |
| 23 | 23 | return "" |
| 24 | 24 | p = dentry_name(d['d_parent']) + "/" |
| 25 | − return p + d['d_iname'].string() | |
| 25 | + return p + d['d_shortname']['string'].string() | |
| 26 | 26 | |
| 27 | 27 | class DentryName(gdb.Function): |
| 28 | 28 | """Return string of the full path of a dentry. |
| @@ -77,8 +77,11 @@ static void validate_addr(char *ptr, int high_addr) · 76 unmodified lines | ||
| 77 | 77 | { |
| 78 | 78 | unsigned long addr = (unsigned long) ptr; |
| 79 | 79 | |
| 80 | − if (high_addr && addr < HIGH_ADDR_MARK) | |
| 81 | − ksft_exit_fail_msg("Bad address %lx\n", addr); | |
| 80 | + if (high_addr) { | |
| 81 | + if (addr < HIGH_ADDR_MARK) | |
| 82 | + ksft_exit_fail_msg("Bad address %lx\n", addr); | |
| 83 | + return; | |
| 84 | + } | |
| 82 | 85 | |
| 83 | 86 | if (addr > HIGH_ADDR_MARK) |
| 84 | 87 | ksft_exit_fail_msg("Bad address %lx\n", addr); |