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 tag 'mm-hotfixes-stable-2025-05-25-00-58' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull hotfixes from Andrew Morton:
"22 hotfixes.

13 are cc:stable and the remainder address post-6.14 issues or aren't
considered necessary for -stable kernels. 19 are for MM"

* tag 'mm-hotfixes-stable-2025-05-25-00-58' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (22 commits)
mailmap: add Jarkko's employer email address
mm: fix copy_vma() error handling for hugetlb mappings
memcg: always call cond_resched() after fn()
mm/hugetlb: fix kernel NULL pointer dereference when replacing free hugetlb folios
mm: vmalloc: only zero-init on vrealloc shrink
mm: vmalloc: actually use the in-place vrealloc region
alloc_tag: allocate percpu counters for module tags dynamically
module: release codetag section when module load fails
mm/cma: make detection of highmem_start more robust
MAINTAINERS: add mm memory policy section
MAINTAINERS: add mm ksm section
kasan: avoid sleepable page allocation from atomic context
highmem: add folio_test_partial_kmap()
MAINTAINERS: add hung-task detector section
taskstats: fix struct taskstats breaks backward compatibility since version 15
mm/truncate: fix out-of-bounds when doing a right-aligned split
MAINTAINERS: add mm reclaim section
MAINTAINERS: update page allocator section
mm: fix VM_UFFD_MINOR == VM_SHADOW_STACK on USERFAULTFD=y && ARM64_GCS=y
mm: mmap: map MAP_STACK to VM_NOHUGEPAGE only if THP is enabled
...

+338 -91
+1
.mailmap
··· 313 313 Jan Kuliga <jtkuliga.kdev@gmail.com> <jankul@alatek.krakow.pl> 314 314 Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@linux.intel.com> 315 315 Jarkko Sakkinen <jarkko@kernel.org> <jarkko@profian.com> 316 + Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@opinsys.com> 316 317 Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com> 317 318 Jason Gunthorpe <jgg@ziepe.ca> <jgg@nvidia.com> 318 319 Jason Gunthorpe <jgg@ziepe.ca> <jgunthorpe@obsidianresearch.com>
+62 -4
MAINTAINERS
··· 11106 11106 S: Odd Fixes 11107 11107 F: drivers/tty/hvc/ 11108 11108 11109 + HUNG TASK DETECTOR 11110 + M: Andrew Morton <akpm@linux-foundation.org> 11111 + R: Lance Yang <lance.yang@linux.dev> 11112 + L: linux-kernel@vger.kernel.org 11113 + S: Maintained 11114 + F: include/linux/hung_task.h 11115 + F: kernel/hung_task.c 11116 + 11109 11117 I2C ACPI SUPPORT 11110 11118 M: Mika Westerberg <westeri@kernel.org> 11111 11119 L: linux-i2c@vger.kernel.org ··· 15569 15561 T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm 15570 15562 F: mm/gup.c 15571 15563 15564 + MEMORY MANAGEMENT - KSM (Kernel Samepage Merging) 15565 + M: Andrew Morton <akpm@linux-foundation.org> 15566 + M: David Hildenbrand <david@redhat.com> 15567 + R: Xu Xin <xu.xin16@zte.com.cn> 15568 + R: Chengming Zhou <chengming.zhou@linux.dev> 15569 + L: linux-mm@kvack.org 15570 + S: Maintained 15571 + W: http://www.linux-mm.org 15572 + T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm 15573 + F: Documentation/admin-guide/mm/ksm.rst 15574 + F: Documentation/mm/ksm.rst 15575 + F: include/linux/ksm.h 15576 + F: include/trace/events/ksm.h 15577 + F: mm/ksm.c 15578 + 15579 + MEMORY MANAGEMENT - MEMORY POLICY AND MIGRATION 15580 + M: Andrew Morton <akpm@linux-foundation.org> 15581 + M: David Hildenbrand <david@redhat.com> 15582 + R: Zi Yan <ziy@nvidia.com> 15583 + R: Matthew Brost <matthew.brost@intel.com> 15584 + R: Joshua Hahn <joshua.hahnjy@gmail.com> 15585 + R: Rakie Kim <rakie.kim@sk.com> 15586 + R: Byungchul Park <byungchul@sk.com> 15587 + R: Gregory Price <gourry@gourry.net> 15588 + R: Ying Huang <ying.huang@linux.alibaba.com> 15589 + L: linux-mm@kvack.org 15590 + S: Maintained 15591 + W: http://www.linux-mm.org 15592 + T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm 15593 + F: include/linux/mempolicy.h 15594 + F: include/linux/migrate.h 15595 + F: mm/mempolicy.c 15596 + F: mm/migrate.c 15597 + F: mm/migrate_device.c 15598 + 15572 15599 MEMORY MANAGEMENT - NUMA MEMBLOCKS AND NUMA EMULATION 15573 15600 M: Andrew Morton <akpm@linux-foundation.org> 15574 15601 M: Mike Rapoport <rppt@kernel.org> ··· 15616 15573 15617 15574 MEMORY MANAGEMENT - PAGE ALLOCATOR 15618 15575 M: Andrew Morton <akpm@linux-foundation.org> 15619 - R: Vlastimil Babka <vbabka@suse.cz> 15576 + M: Vlastimil Babka <vbabka@suse.cz> 15620 15577 R: Suren Baghdasaryan <surenb@google.com> 15621 15578 R: Michal Hocko <mhocko@suse.com> 15622 15579 R: Brendan Jackman <jackmanb@google.com> ··· 15624 15581 R: Zi Yan <ziy@nvidia.com> 15625 15582 L: linux-mm@kvack.org 15626 15583 S: Maintained 15584 + F: include/linux/compaction.h 15585 + F: include/linux/gfp.h 15586 + F: include/linux/page-isolation.h 15627 15587 F: mm/compaction.c 15628 15588 F: mm/page_alloc.c 15629 - F: include/linux/gfp.h 15630 - F: include/linux/compaction.h 15589 + F: mm/page_isolation.c 15590 + 15591 + MEMORY MANAGEMENT - RECLAIM 15592 + M: Andrew Morton <akpm@linux-foundation.org> 15593 + M: Johannes Weiner <hannes@cmpxchg.org> 15594 + R: David Hildenbrand <david@redhat.com> 15595 + R: Michal Hocko <mhocko@kernel.org> 15596 + R: Qi Zheng <zhengqi.arch@bytedance.com> 15597 + R: Shakeel Butt <shakeel.butt@linux.dev> 15598 + R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> 15599 + L: linux-mm@kvack.org 15600 + S: Maintained 15601 + F: mm/pt_reclaim.c 15602 + F: mm/vmscan.c 15631 15603 15632 15604 MEMORY MANAGEMENT - RMAP (REVERSE MAPPING) 15633 15605 M: Andrew Morton <akpm@linux-foundation.org> ··· 25970 25912 25971 25913 VMALLOC 25972 25914 M: Andrew Morton <akpm@linux-foundation.org> 25973 - R: Uladzislau Rezki <urezki@gmail.com> 25915 + M: Uladzislau Rezki <urezki@gmail.com> 25974 25916 L: linux-mm@kvack.org 25975 25917 S: Maintained 25976 25918 W: http://www.linux-mm.org
+12
include/linux/alloc_tag.h
··· 104 104 105 105 #else /* ARCH_NEEDS_WEAK_PER_CPU */ 106 106 107 + #ifdef MODULE 108 + 109 + #define DEFINE_ALLOC_TAG(_alloc_tag) \ 110 + static struct alloc_tag _alloc_tag __used __aligned(8) \ 111 + __section(ALLOC_TAG_SECTION_NAME) = { \ 112 + .ct = CODE_TAG_INIT, \ 113 + .counters = NULL }; 114 + 115 + #else /* MODULE */ 116 + 107 117 #define DEFINE_ALLOC_TAG(_alloc_tag) \ 108 118 static DEFINE_PER_CPU(struct alloc_tag_counters, _alloc_tag_cntr); \ 109 119 static struct alloc_tag _alloc_tag __used __aligned(8) \ 110 120 __section(ALLOC_TAG_SECTION_NAME) = { \ 111 121 .ct = CODE_TAG_INIT, \ 112 122 .counters = &_alloc_tag_cntr }; 123 + 124 + #endif /* MODULE */ 113 125 114 126 #endif /* ARCH_NEEDS_WEAK_PER_CPU */ 115 127
+4 -4
include/linux/codetag.h
··· 36 36 struct codetag_type_desc { 37 37 const char *section; 38 38 size_t tag_size; 39 - void (*module_load)(struct codetag_type *cttype, 40 - struct codetag_module *cmod); 41 - void (*module_unload)(struct codetag_type *cttype, 42 - struct codetag_module *cmod); 39 + void (*module_load)(struct module *mod, 40 + struct codetag *start, struct codetag *end); 41 + void (*module_unload)(struct module *mod, 42 + struct codetag *start, struct codetag *end); 43 43 #ifdef CONFIG_MODULES 44 44 void (*module_replaced)(struct module *mod, struct module *new_mod); 45 45 bool (*needs_section_mem)(struct module *mod, unsigned long size);
+5 -5
include/linux/highmem.h
··· 461 461 const char *from = kmap_local_folio(folio, offset); 462 462 size_t chunk = len; 463 463 464 - if (folio_test_highmem(folio) && 464 + if (folio_test_partial_kmap(folio) && 465 465 chunk > PAGE_SIZE - offset_in_page(offset)) 466 466 chunk = PAGE_SIZE - offset_in_page(offset); 467 467 memcpy(to, from, chunk); ··· 489 489 char *to = kmap_local_folio(folio, offset); 490 490 size_t chunk = len; 491 491 492 - if (folio_test_highmem(folio) && 492 + if (folio_test_partial_kmap(folio) && 493 493 chunk > PAGE_SIZE - offset_in_page(offset)) 494 494 chunk = PAGE_SIZE - offset_in_page(offset); 495 495 memcpy(to, from, chunk); ··· 522 522 { 523 523 size_t len = folio_size(folio) - offset; 524 524 525 - if (folio_test_highmem(folio)) { 525 + if (folio_test_partial_kmap(folio)) { 526 526 size_t max = PAGE_SIZE - offset_in_page(offset); 527 527 528 528 while (len > max) { ··· 560 560 561 561 VM_BUG_ON(offset + len > folio_size(folio)); 562 562 563 - if (folio_test_highmem(folio)) { 563 + if (folio_test_partial_kmap(folio)) { 564 564 size_t max = PAGE_SIZE - offset_in_page(offset); 565 565 566 566 while (len > max) { ··· 597 597 size_t offset = offset_in_folio(folio, pos); 598 598 char *from = kmap_local_folio(folio, offset); 599 599 600 - if (folio_test_highmem(folio)) { 600 + if (folio_test_partial_kmap(folio)) { 601 601 offset = offset_in_page(offset); 602 602 len = min_t(size_t, len, PAGE_SIZE - offset); 603 603 } else
+5
include/linux/hugetlb.h
··· 275 275 bool is_hugetlb_entry_migration(pte_t pte); 276 276 bool is_hugetlb_entry_hwpoisoned(pte_t pte); 277 277 void hugetlb_unshare_all_pmds(struct vm_area_struct *vma); 278 + void fixup_hugetlb_reservations(struct vm_area_struct *vma); 278 279 279 280 #else /* !CONFIG_HUGETLB_PAGE */ 280 281 ··· 468 467 } 469 468 470 469 static inline void hugetlb_unshare_all_pmds(struct vm_area_struct *vma) { } 470 + 471 + static inline void fixup_hugetlb_reservations(struct vm_area_struct *vma) 472 + { 473 + } 471 474 472 475 #endif /* !CONFIG_HUGETLB_PAGE */ 473 476
+1 -1
include/linux/mm.h
··· 385 385 #endif 386 386 387 387 #ifdef CONFIG_HAVE_ARCH_USERFAULTFD_MINOR 388 - # define VM_UFFD_MINOR_BIT 38 388 + # define VM_UFFD_MINOR_BIT 41 389 389 # define VM_UFFD_MINOR BIT(VM_UFFD_MINOR_BIT) /* UFFD minor faults */ 390 390 #else /* !CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */ 391 391 # define VM_UFFD_MINOR VM_NONE
+2
include/linux/mman.h
··· 155 155 return _calc_vm_trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN ) | 156 156 _calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED ) | 157 157 _calc_vm_trans(flags, MAP_SYNC, VM_SYNC ) | 158 + #ifdef CONFIG_TRANSPARENT_HUGEPAGE 158 159 _calc_vm_trans(flags, MAP_STACK, VM_NOHUGEPAGE) | 160 + #endif 159 161 arch_calc_vm_flag_bits(file, flags); 160 162 } 161 163
+7
include/linux/page-flags.h
··· 615 615 PAGEFLAG_FALSE(HighMem, highmem) 616 616 #endif 617 617 618 + /* Does kmap_local_folio() only allow access to one page of the folio? */ 619 + #ifdef CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP 620 + #define folio_test_partial_kmap(f) true 621 + #else 622 + #define folio_test_partial_kmap(f) folio_test_highmem(f) 623 + #endif 624 + 618 625 #ifdef CONFIG_SWAP 619 626 static __always_inline bool folio_test_swapcache(const struct folio *folio) 620 627 {
-4
include/linux/percpu.h
··· 15 15 16 16 /* enough to cover all DEFINE_PER_CPUs in modules */ 17 17 #ifdef CONFIG_MODULES 18 - #ifdef CONFIG_MEM_ALLOC_PROFILING 19 - #define PERCPU_MODULE_RESERVE (8 << 13) 20 - #else 21 18 #define PERCPU_MODULE_RESERVE (8 << 10) 22 - #endif 23 19 #else 24 20 #define PERCPU_MODULE_RESERVE 0 25 21 #endif
+29 -18
include/uapi/linux/taskstats.h
··· 34 34 */ 35 35 36 36 37 - #define TASKSTATS_VERSION 15 37 + #define TASKSTATS_VERSION 16 38 38 #define TS_COMM_LEN 32 /* should be >= TASK_COMM_LEN 39 39 * in linux/sched.h */ 40 40 ··· 72 72 */ 73 73 __u64 cpu_count __attribute__((aligned(8))); 74 74 __u64 cpu_delay_total; 75 - __u64 cpu_delay_max; 76 - __u64 cpu_delay_min; 77 75 78 76 /* Following four fields atomically updated using task->delays->lock */ 79 77 ··· 80 82 */ 81 83 __u64 blkio_count; 82 84 __u64 blkio_delay_total; 83 - __u64 blkio_delay_max; 84 - __u64 blkio_delay_min; 85 85 86 86 /* Delay waiting for page fault I/O (swap in only) */ 87 87 __u64 swapin_count; 88 88 __u64 swapin_delay_total; 89 - __u64 swapin_delay_max; 90 - __u64 swapin_delay_min; 91 89 92 90 /* cpu "wall-clock" running time 93 91 * On some architectures, value will adjust for cpu time stolen ··· 166 172 /* Delay waiting for memory reclaim */ 167 173 __u64 freepages_count; 168 174 __u64 freepages_delay_total; 169 - __u64 freepages_delay_max; 170 - __u64 freepages_delay_min; 175 + 171 176 172 177 /* Delay waiting for thrashing page */ 173 178 __u64 thrashing_count; 174 179 __u64 thrashing_delay_total; 175 - __u64 thrashing_delay_max; 176 - __u64 thrashing_delay_min; 177 180 178 181 /* v10: 64-bit btime to avoid overflow */ 179 182 __u64 ac_btime64; /* 64-bit begin time */ ··· 178 187 /* v11: Delay waiting for memory compact */ 179 188 __u64 compact_count; 180 189 __u64 compact_delay_total; 181 - __u64 compact_delay_max; 182 - __u64 compact_delay_min; 183 190 184 191 /* v12 begin */ 185 192 __u32 ac_tgid; /* thread group ID */ ··· 199 210 /* v13: Delay waiting for write-protect copy */ 200 211 __u64 wpcopy_count; 201 212 __u64 wpcopy_delay_total; 202 - __u64 wpcopy_delay_max; 203 - __u64 wpcopy_delay_min; 204 213 205 214 /* v14: Delay waiting for IRQ/SOFTIRQ */ 206 215 __u64 irq_count; 207 216 __u64 irq_delay_total; 208 - __u64 irq_delay_max; 209 - __u64 irq_delay_min; 210 - /* v15: add Delay max */ 217 + 218 + /* v15: add Delay max and Delay min */ 219 + 220 + /* v16: move Delay max and Delay min to the end of taskstat */ 221 + __u64 cpu_delay_max; 222 + __u64 cpu_delay_min; 223 + 224 + __u64 blkio_delay_max; 225 + __u64 blkio_delay_min; 226 + 227 + __u64 swapin_delay_max; 228 + __u64 swapin_delay_min; 229 + 230 + __u64 freepages_delay_max; 231 + __u64 freepages_delay_min; 232 + 233 + __u64 thrashing_delay_max; 234 + __u64 thrashing_delay_min; 235 + 236 + __u64 compact_delay_max; 237 + __u64 compact_delay_min; 238 + 239 + __u64 wpcopy_delay_max; 240 + __u64 wpcopy_delay_min; 241 + 242 + __u64 irq_delay_max; 243 + __u64 irq_delay_min; 211 244 }; 212 245 213 246
+1
kernel/module/main.c
··· 2829 2829 { 2830 2830 percpu_modfree(mod); 2831 2831 module_arch_freeing_init(mod); 2832 + codetag_free_module_sections(mod); 2832 2833 2833 2834 free_mod_mem(mod); 2834 2835 }
+69 -18
lib/alloc_tag.c
··· 350 350 return size >= sizeof(struct alloc_tag); 351 351 } 352 352 353 - static struct alloc_tag *find_used_tag(struct alloc_tag *from, struct alloc_tag *to) 353 + static bool clean_unused_counters(struct alloc_tag *start_tag, 354 + struct alloc_tag *end_tag) 354 355 { 355 - while (from <= to) { 356 + struct alloc_tag *tag; 357 + bool ret = true; 358 + 359 + for (tag = start_tag; tag <= end_tag; tag++) { 356 360 struct alloc_tag_counters counter; 357 361 358 - counter = alloc_tag_read(from); 359 - if (counter.bytes) 360 - return from; 361 - from++; 362 + if (!tag->counters) 363 + continue; 364 + 365 + counter = alloc_tag_read(tag); 366 + if (!counter.bytes) { 367 + free_percpu(tag->counters); 368 + tag->counters = NULL; 369 + } else { 370 + ret = false; 371 + } 362 372 } 363 373 364 - return NULL; 374 + return ret; 365 375 } 366 376 367 377 /* Called with mod_area_mt locked */ ··· 381 371 struct module *val; 382 372 383 373 mas_for_each(&mas, val, module_tags.size) { 374 + struct alloc_tag *start_tag; 375 + struct alloc_tag *end_tag; 376 + 384 377 if (val != &unloaded_mod) 385 378 continue; 386 379 387 380 /* Release area if all tags are unused */ 388 - if (!find_used_tag((struct alloc_tag *)(module_tags.start_addr + mas.index), 389 - (struct alloc_tag *)(module_tags.start_addr + mas.last))) 381 + start_tag = (struct alloc_tag *)(module_tags.start_addr + mas.index); 382 + end_tag = (struct alloc_tag *)(module_tags.start_addr + mas.last); 383 + if (clean_unused_counters(start_tag, end_tag)) 390 384 mas_erase(&mas); 391 385 } 392 386 } ··· 575 561 static void release_module_tags(struct module *mod, bool used) 576 562 { 577 563 MA_STATE(mas, &mod_area_mt, module_tags.size, module_tags.size); 578 - struct alloc_tag *tag; 564 + struct alloc_tag *start_tag; 565 + struct alloc_tag *end_tag; 579 566 struct module *val; 580 567 581 568 mas_lock(&mas); ··· 590 575 if (!used) 591 576 goto release_area; 592 577 593 - /* Find out if the area is used */ 594 - tag = find_used_tag((struct alloc_tag *)(module_tags.start_addr + mas.index), 595 - (struct alloc_tag *)(module_tags.start_addr + mas.last)); 596 - if (tag) { 597 - struct alloc_tag_counters counter = alloc_tag_read(tag); 578 + start_tag = (struct alloc_tag *)(module_tags.start_addr + mas.index); 579 + end_tag = (struct alloc_tag *)(module_tags.start_addr + mas.last); 580 + if (!clean_unused_counters(start_tag, end_tag)) { 581 + struct alloc_tag *tag; 598 582 599 - pr_info("%s:%u module %s func:%s has %llu allocated at module unload\n", 600 - tag->ct.filename, tag->ct.lineno, tag->ct.modname, 601 - tag->ct.function, counter.bytes); 583 + for (tag = start_tag; tag <= end_tag; tag++) { 584 + struct alloc_tag_counters counter; 585 + 586 + if (!tag->counters) 587 + continue; 588 + 589 + counter = alloc_tag_read(tag); 590 + pr_info("%s:%u module %s func:%s has %llu allocated at module unload\n", 591 + tag->ct.filename, tag->ct.lineno, tag->ct.modname, 592 + tag->ct.function, counter.bytes); 593 + } 602 594 } else { 603 595 used = false; 604 596 } ··· 616 594 mas_store(&mas, NULL); 617 595 out: 618 596 mas_unlock(&mas); 597 + } 598 + 599 + static void load_module(struct module *mod, struct codetag *start, struct codetag *stop) 600 + { 601 + /* Allocate module alloc_tag percpu counters */ 602 + struct alloc_tag *start_tag; 603 + struct alloc_tag *stop_tag; 604 + struct alloc_tag *tag; 605 + 606 + if (!mod) 607 + return; 608 + 609 + start_tag = ct_to_alloc_tag(start); 610 + stop_tag = ct_to_alloc_tag(stop); 611 + for (tag = start_tag; tag < stop_tag; tag++) { 612 + WARN_ON(tag->counters); 613 + tag->counters = alloc_percpu(struct alloc_tag_counters); 614 + if (!tag->counters) { 615 + while (--tag >= start_tag) { 616 + free_percpu(tag->counters); 617 + tag->counters = NULL; 618 + } 619 + shutdown_mem_profiling(true); 620 + pr_err("Failed to allocate memory for allocation tag percpu counters in the module %s. Memory allocation profiling is disabled!\n", 621 + mod->name); 622 + break; 623 + } 624 + } 619 625 } 620 626 621 627 static void replace_module(struct module *mod, struct module *new_mod) ··· 807 757 .needs_section_mem = needs_section_mem, 808 758 .alloc_section_mem = reserve_module_tags, 809 759 .free_section_mem = release_module_tags, 760 + .module_load = load_module, 810 761 .module_replaced = replace_module, 811 762 #endif 812 763 };
+3 -2
lib/codetag.c
··· 194 194 if (err >= 0) { 195 195 cttype->count += range_size(cttype, &range); 196 196 if (cttype->desc.module_load) 197 - cttype->desc.module_load(cttype, cmod); 197 + cttype->desc.module_load(mod, range.start, range.stop); 198 198 } 199 199 up_write(&cttype->mod_lock); 200 200 ··· 333 333 } 334 334 if (found) { 335 335 if (cttype->desc.module_unload) 336 - cttype->desc.module_unload(cttype, cmod); 336 + cttype->desc.module_unload(cmod->mod, 337 + cmod->range.start, cmod->range.stop); 337 338 338 339 cttype->count -= range_size(cttype, &cmod->range); 339 340 idr_remove(&cttype->mod_idr, mod_id);
+4 -1
mm/cma.c
··· 608 608 * complain. Find the boundary by adding one to the last valid 609 609 * address. 610 610 */ 611 - highmem_start = __pa(high_memory - 1) + 1; 611 + if (IS_ENABLED(CONFIG_HIGHMEM)) 612 + highmem_start = __pa(high_memory - 1) + 1; 613 + else 614 + highmem_start = memblock_end_of_DRAM(); 612 615 pr_debug("%s(size %pa, base %pa, limit %pa alignment %pa)\n", 613 616 __func__, &size, &base, &limit, &alignment); 614 617
+23 -1
mm/hugetlb.c
··· 1250 1250 /* 1251 1251 * Reset and decrement one ref on hugepage private reservation. 1252 1252 * Called with mm->mmap_lock writer semaphore held. 1253 - * This function should be only used by move_vma() and operate on 1253 + * This function should be only used by mremap and operate on 1254 1254 * same sized vma. It should never come here with last ref on the 1255 1255 * reservation. 1256 1256 */ ··· 2949 2949 2950 2950 while (start_pfn < end_pfn) { 2951 2951 folio = pfn_folio(start_pfn); 2952 + 2953 + /* 2954 + * The folio might have been dissolved from under our feet, so make sure 2955 + * to carefully check the state under the lock. 2956 + */ 2957 + spin_lock_irq(&hugetlb_lock); 2952 2958 if (folio_test_hugetlb(folio)) { 2953 2959 h = folio_hstate(folio); 2954 2960 } else { 2961 + spin_unlock_irq(&hugetlb_lock); 2955 2962 start_pfn++; 2956 2963 continue; 2957 2964 } 2965 + spin_unlock_irq(&hugetlb_lock); 2958 2966 2959 2967 if (!folio_ref_count(folio)) { 2960 2968 ret = alloc_and_dissolve_hugetlb_folio(h, folio, ··· 7938 7930 { 7939 7931 hugetlb_unshare_pmds(vma, ALIGN(vma->vm_start, PUD_SIZE), 7940 7932 ALIGN_DOWN(vma->vm_end, PUD_SIZE)); 7933 + } 7934 + 7935 + /* 7936 + * For hugetlb, mremap() is an odd edge case - while the VMA copying is 7937 + * performed, we permit both the old and new VMAs to reference the same 7938 + * reservation. 7939 + * 7940 + * We fix this up after the operation succeeds, or if a newly allocated VMA 7941 + * is closed as a result of a failure to allocate memory. 7942 + */ 7943 + void fixup_hugetlb_reservations(struct vm_area_struct *vma) 7944 + { 7945 + if (is_vm_hugetlb_page(vma)) 7946 + clear_vma_resv_huge_pages(vma); 7941 7947 }
+78 -14
mm/kasan/shadow.c
··· 292 292 { 293 293 } 294 294 295 + struct vmalloc_populate_data { 296 + unsigned long start; 297 + struct page **pages; 298 + }; 299 + 295 300 static int kasan_populate_vmalloc_pte(pte_t *ptep, unsigned long addr, 296 - void *unused) 301 + void *_data) 297 302 { 298 - unsigned long page; 303 + struct vmalloc_populate_data *data = _data; 304 + struct page *page; 299 305 pte_t pte; 306 + int index; 300 307 301 308 if (likely(!pte_none(ptep_get(ptep)))) 302 309 return 0; 303 310 304 - page = __get_free_page(GFP_KERNEL); 305 - if (!page) 306 - return -ENOMEM; 307 - 308 - __memset((void *)page, KASAN_VMALLOC_INVALID, PAGE_SIZE); 309 - pte = pfn_pte(PFN_DOWN(__pa(page)), PAGE_KERNEL); 311 + index = PFN_DOWN(addr - data->start); 312 + page = data->pages[index]; 313 + __memset(page_to_virt(page), KASAN_VMALLOC_INVALID, PAGE_SIZE); 314 + pte = pfn_pte(page_to_pfn(page), PAGE_KERNEL); 310 315 311 316 spin_lock(&init_mm.page_table_lock); 312 317 if (likely(pte_none(ptep_get(ptep)))) { 313 318 set_pte_at(&init_mm, addr, ptep, pte); 314 - page = 0; 319 + data->pages[index] = NULL; 315 320 } 316 321 spin_unlock(&init_mm.page_table_lock); 317 - if (page) 318 - free_page(page); 322 + 319 323 return 0; 324 + } 325 + 326 + static void ___free_pages_bulk(struct page **pages, int nr_pages) 327 + { 328 + int i; 329 + 330 + for (i = 0; i < nr_pages; i++) { 331 + if (pages[i]) { 332 + __free_pages(pages[i], 0); 333 + pages[i] = NULL; 334 + } 335 + } 336 + } 337 + 338 + static int ___alloc_pages_bulk(struct page **pages, int nr_pages) 339 + { 340 + unsigned long nr_populated, nr_total = nr_pages; 341 + struct page **page_array = pages; 342 + 343 + while (nr_pages) { 344 + nr_populated = alloc_pages_bulk(GFP_KERNEL, nr_pages, pages); 345 + if (!nr_populated) { 346 + ___free_pages_bulk(page_array, nr_total - nr_pages); 347 + return -ENOMEM; 348 + } 349 + pages += nr_populated; 350 + nr_pages -= nr_populated; 351 + } 352 + 353 + return 0; 354 + } 355 + 356 + static int __kasan_populate_vmalloc(unsigned long start, unsigned long end) 357 + { 358 + unsigned long nr_pages, nr_total = PFN_UP(end - start); 359 + struct vmalloc_populate_data data; 360 + int ret = 0; 361 + 362 + data.pages = (struct page **)__get_free_page(GFP_KERNEL | __GFP_ZERO); 363 + if (!data.pages) 364 + return -ENOMEM; 365 + 366 + while (nr_total) { 367 + nr_pages = min(nr_total, PAGE_SIZE / sizeof(data.pages[0])); 368 + ret = ___alloc_pages_bulk(data.pages, nr_pages); 369 + if (ret) 370 + break; 371 + 372 + data.start = start; 373 + ret = apply_to_page_range(&init_mm, start, nr_pages * PAGE_SIZE, 374 + kasan_populate_vmalloc_pte, &data); 375 + ___free_pages_bulk(data.pages, nr_pages); 376 + if (ret) 377 + break; 378 + 379 + start += nr_pages * PAGE_SIZE; 380 + nr_total -= nr_pages; 381 + } 382 + 383 + free_page((unsigned long)data.pages); 384 + 385 + return ret; 320 386 } 321 387 322 388 int kasan_populate_vmalloc(unsigned long addr, unsigned long size) ··· 414 348 shadow_start = PAGE_ALIGN_DOWN(shadow_start); 415 349 shadow_end = PAGE_ALIGN(shadow_end); 416 350 417 - ret = apply_to_page_range(&init_mm, shadow_start, 418 - shadow_end - shadow_start, 419 - kasan_populate_vmalloc_pte, NULL); 351 + ret = __kasan_populate_vmalloc(shadow_start, shadow_end); 420 352 if (ret) 421 353 return ret; 422 354
+2 -4
mm/memcontrol.c
··· 1168 1168 { 1169 1169 struct mem_cgroup *iter; 1170 1170 int ret = 0; 1171 - int i = 0; 1172 1171 1173 1172 BUG_ON(mem_cgroup_is_root(memcg)); 1174 1173 ··· 1177 1178 1178 1179 css_task_iter_start(&iter->css, CSS_TASK_ITER_PROCS, &it); 1179 1180 while (!ret && (task = css_task_iter_next(&it))) { 1180 - /* Avoid potential softlockup warning */ 1181 - if ((++i & 1023) == 0) 1182 - cond_resched(); 1183 1181 ret = fn(task, arg); 1182 + /* Avoid potential softlockup warning */ 1183 + cond_resched(); 1184 1184 } 1185 1185 css_task_iter_end(&it); 1186 1186 if (ret) {
+1 -2
mm/mremap.c
··· 1188 1188 mremap_userfaultfd_prep(new_vma, vrm->uf); 1189 1189 } 1190 1190 1191 - if (is_vm_hugetlb_page(vma)) 1192 - clear_vma_resv_huge_pages(vma); 1191 + fixup_hugetlb_reservations(vma); 1193 1192 1194 1193 /* Tell pfnmap has moved from this vma */ 1195 1194 if (unlikely(vma->vm_flags & VM_PFNMAP))
+8
mm/page_alloc.c
··· 4562 4562 } 4563 4563 4564 4564 retry: 4565 + /* 4566 + * Deal with possible cpuset update races or zonelist updates to avoid 4567 + * infinite retries. 4568 + */ 4569 + if (check_retry_cpuset(cpuset_mems_cookie, ac) || 4570 + check_retry_zonelist(zonelist_iter_cookie)) 4571 + goto restart; 4572 + 4565 4573 /* Ensure kswapd doesn't accidentally go to sleep as long as we loop */ 4566 4574 if (alloc_flags & ALLOC_KSWAPD) 4567 4575 wake_all_kswapds(order, gfp_mask, ac);
+12 -8
mm/truncate.c
··· 191 191 bool truncate_inode_partial_folio(struct folio *folio, loff_t start, loff_t end) 192 192 { 193 193 loff_t pos = folio_pos(folio); 194 + size_t size = folio_size(folio); 194 195 unsigned int offset, length; 195 196 struct page *split_at, *split_at2; 196 197 ··· 199 198 offset = start - pos; 200 199 else 201 200 offset = 0; 202 - length = folio_size(folio); 203 - if (pos + length <= (u64)end) 204 - length = length - offset; 201 + if (pos + size <= (u64)end) 202 + length = size - offset; 205 203 else 206 204 length = end + 1 - pos - offset; 207 205 208 206 folio_wait_writeback(folio); 209 - if (length == folio_size(folio)) { 207 + if (length == size) { 210 208 truncate_inode_folio(folio->mapping, folio); 211 209 return true; 212 210 } ··· 224 224 return true; 225 225 226 226 split_at = folio_page(folio, PAGE_ALIGN_DOWN(offset) / PAGE_SIZE); 227 - split_at2 = folio_page(folio, 228 - PAGE_ALIGN_DOWN(offset + length) / PAGE_SIZE); 229 - 230 227 if (!try_folio_split(folio, split_at, NULL)) { 231 228 /* 232 229 * try to split at offset + length to make sure folios within 233 230 * the range can be dropped, especially to avoid memory waste 234 231 * for shmem truncate 235 232 */ 236 - struct folio *folio2 = page_folio(split_at2); 233 + struct folio *folio2; 234 + 235 + if (offset + length == size) 236 + goto no_split; 237 + 238 + split_at2 = folio_page(folio, 239 + PAGE_ALIGN_DOWN(offset + length) / PAGE_SIZE); 240 + folio2 = page_folio(split_at2); 237 241 238 242 if (!folio_try_get(folio2)) 239 243 goto no_split;
+1
mm/vma.c
··· 1834 1834 return new_vma; 1835 1835 1836 1836 out_vma_link: 1837 + fixup_hugetlb_reservations(new_vma); 1837 1838 vma_close(new_vma); 1838 1839 1839 1840 if (new_vma->vm_file)
+8 -5
mm/vmalloc.c
··· 4093 4093 * would be a good heuristic for when to shrink the vm_area? 4094 4094 */ 4095 4095 if (size <= old_size) { 4096 - /* Zero out "freed" memory. */ 4097 - if (want_init_on_free()) 4096 + /* Zero out "freed" memory, potentially for future realloc. */ 4097 + if (want_init_on_free() || want_init_on_alloc(flags)) 4098 4098 memset((void *)p + size, 0, old_size - size); 4099 4099 vm->requested_size = size; 4100 4100 kasan_poison_vmalloc(p + size, old_size - size); ··· 4107 4107 if (size <= alloced_size) { 4108 4108 kasan_unpoison_vmalloc(p + old_size, size - old_size, 4109 4109 KASAN_VMALLOC_PROT_NORMAL); 4110 - /* Zero out "alloced" memory. */ 4111 - if (want_init_on_alloc(flags)) 4112 - memset((void *)p + old_size, 0, size - old_size); 4110 + /* 4111 + * No need to zero memory here, as unused memory will have 4112 + * already been zeroed at initial allocation time or during 4113 + * realloc shrink time. 4114 + */ 4113 4115 vm->requested_size = size; 4116 + return (void *)p; 4114 4117 } 4115 4118 4116 4119 /* TODO: Grow the vm_area, i.e. allocate and map additional pages. */