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-09-17-21-10' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull misc fixes from Andrew Morton:
"15 hotfixes. 11 are cc:stable and the remainder address post-6.16
issues or aren't considered necessary for -stable kernels. 13 of these
fixes are for MM.

The usual shower of singletons, plus

- fixes from Hugh to address various misbehaviors in get_user_pages()

- patches from SeongJae to address a quite severe issue in DAMON

- another series also from SeongJae which completes some fixes for a
DAMON startup issue"

* tag 'mm-hotfixes-stable-2025-09-17-21-10' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm:
zram: fix slot write race condition
nilfs2: fix CFI failure when accessing /sys/fs/nilfs2/features/*
samples/damon/mtier: avoid starting DAMON before initialization
samples/damon/prcl: avoid starting DAMON before initialization
samples/damon/wsse: avoid starting DAMON before initialization
MAINTAINERS: add Lance Yang as a THP reviewer
MAINTAINERS: add Jann Horn as rmap reviewer
mm/damon/sysfs: use dynamically allocated repeat mode damon_call_control
mm/damon/core: introduce damon_call_control->dealloc_on_cancel
mm: folio_may_be_lru_cached() unless folio_test_large()
mm: revert "mm: vmscan.c: fix OOM on swap stress test"
mm: revert "mm/gup: clear the LRU flag of a page before adding to LRU batch"
mm/gup: local lru_add_drain() to avoid lru_add_drain_all()
mm/gup: check ref_count instead of lru before migration

+94 -52
+2
MAINTAINERS
··· 16196 16196 R: Liam R. Howlett <Liam.Howlett@oracle.com> 16197 16197 R: Vlastimil Babka <vbabka@suse.cz> 16198 16198 R: Harry Yoo <harry.yoo@oracle.com> 16199 + R: Jann Horn <jannh@google.com> 16199 16200 L: linux-mm@kvack.org 16200 16201 S: Maintained 16201 16202 F: include/linux/rmap.h ··· 16241 16240 R: Ryan Roberts <ryan.roberts@arm.com> 16242 16241 R: Dev Jain <dev.jain@arm.com> 16243 16242 R: Barry Song <baohua@kernel.org> 16243 + R: Lance Yang <lance.yang@linux.dev> 16244 16244 L: linux-mm@kvack.org 16245 16245 S: Maintained 16246 16246 W: http://www.linux-mm.org
+3 -5
drivers/block/zram/zram_drv.c
··· 1795 1795 u32 index) 1796 1796 { 1797 1797 zram_slot_lock(zram, index); 1798 + zram_free_page(zram, index); 1798 1799 zram_set_flag(zram, index, ZRAM_SAME); 1799 1800 zram_set_handle(zram, index, fill); 1800 1801 zram_slot_unlock(zram, index); ··· 1833 1832 kunmap_local(src); 1834 1833 1835 1834 zram_slot_lock(zram, index); 1835 + zram_free_page(zram, index); 1836 1836 zram_set_flag(zram, index, ZRAM_HUGE); 1837 1837 zram_set_handle(zram, index, handle); 1838 1838 zram_set_obj_size(zram, index, PAGE_SIZE); ··· 1856 1854 struct zcomp_strm *zstrm; 1857 1855 unsigned long element; 1858 1856 bool same_filled; 1859 - 1860 - /* First, free memory allocated to this slot (if any) */ 1861 - zram_slot_lock(zram, index); 1862 - zram_free_page(zram, index); 1863 - zram_slot_unlock(zram, index); 1864 1857 1865 1858 mem = kmap_local_page(page); 1866 1859 same_filled = page_same_filled(mem, &element); ··· 1898 1901 zcomp_stream_put(zstrm); 1899 1902 1900 1903 zram_slot_lock(zram, index); 1904 + zram_free_page(zram, index); 1901 1905 zram_set_handle(zram, index, handle); 1902 1906 zram_set_obj_size(zram, index, comp_len); 1903 1907 zram_slot_unlock(zram, index);
+2 -2
fs/nilfs2/sysfs.c
··· 1075 1075 ************************************************************************/ 1076 1076 1077 1077 static ssize_t nilfs_feature_revision_show(struct kobject *kobj, 1078 - struct attribute *attr, char *buf) 1078 + struct kobj_attribute *attr, char *buf) 1079 1079 { 1080 1080 return sysfs_emit(buf, "%d.%d\n", 1081 1081 NILFS_CURRENT_REV, NILFS_MINOR_REV); ··· 1087 1087 "(1) revision\n\tshow current revision of NILFS file system driver.\n"; 1088 1088 1089 1089 static ssize_t nilfs_feature_README_show(struct kobject *kobj, 1090 - struct attribute *attr, 1090 + struct kobj_attribute *attr, 1091 1091 char *buf) 1092 1092 { 1093 1093 return sysfs_emit(buf, features_readme_str);
+4 -4
fs/nilfs2/sysfs.h
··· 50 50 struct completion sg_segments_kobj_unregister; 51 51 }; 52 52 53 - #define NILFS_COMMON_ATTR_STRUCT(name) \ 53 + #define NILFS_KOBJ_ATTR_STRUCT(name) \ 54 54 struct nilfs_##name##_attr { \ 55 55 struct attribute attr; \ 56 - ssize_t (*show)(struct kobject *, struct attribute *, \ 56 + ssize_t (*show)(struct kobject *, struct kobj_attribute *, \ 57 57 char *); \ 58 - ssize_t (*store)(struct kobject *, struct attribute *, \ 58 + ssize_t (*store)(struct kobject *, struct kobj_attribute *, \ 59 59 const char *, size_t); \ 60 60 } 61 61 62 - NILFS_COMMON_ATTR_STRUCT(feature); 62 + NILFS_KOBJ_ATTR_STRUCT(feature); 63 63 64 64 #define NILFS_DEV_ATTR_STRUCT(name) \ 65 65 struct nilfs_##name##_attr { \
+2
include/linux/damon.h
··· 636 636 * @data: Data that will be passed to @fn. 637 637 * @repeat: Repeat invocations. 638 638 * @return_code: Return code from @fn invocation. 639 + * @dealloc_on_cancel: De-allocate when canceled. 639 640 * 640 641 * Control damon_call(), which requests specific kdamond to invoke a given 641 642 * function. Refer to damon_call() for more details. ··· 646 645 void *data; 647 646 bool repeat; 648 647 int return_code; 648 + bool dealloc_on_cancel; 649 649 /* private: internal use only */ 650 650 /* informs if the kdamond finished handling of the request */ 651 651 struct completion completion;
+10
include/linux/swap.h
··· 385 385 void mark_page_accessed(struct page *); 386 386 void folio_mark_accessed(struct folio *); 387 387 388 + static inline bool folio_may_be_lru_cached(struct folio *folio) 389 + { 390 + /* 391 + * Holding PMD-sized folios in per-CPU LRU cache unbalances accounting. 392 + * Holding small numbers of low-order mTHP folios in per-CPU LRU cache 393 + * will be sensible, but nobody has implemented and tested that yet. 394 + */ 395 + return !folio_test_large(folio); 396 + } 397 + 388 398 extern atomic_t lru_disable_count; 389 399 390 400 static inline bool lru_cache_disabled(void)
+6 -2
mm/damon/core.c
··· 2479 2479 mutex_lock(&ctx->call_controls_lock); 2480 2480 list_del(&control->list); 2481 2481 mutex_unlock(&ctx->call_controls_lock); 2482 - if (!control->repeat) 2482 + if (!control->repeat) { 2483 2483 complete(&control->completion); 2484 - else 2484 + } else if (control->canceled && control->dealloc_on_cancel) { 2485 + kfree(control); 2486 + continue; 2487 + } else { 2485 2488 list_add(&control->list, &repeat_controls); 2489 + } 2486 2490 } 2487 2491 control = list_first_entry_or_null(&repeat_controls, 2488 2492 struct damon_call_control, list);
+15 -8
mm/damon/sysfs.c
··· 1534 1534 return 0; 1535 1535 } 1536 1536 1537 - static struct damon_call_control damon_sysfs_repeat_call_control = { 1538 - .fn = damon_sysfs_repeat_call_fn, 1539 - .repeat = true, 1540 - }; 1541 - 1542 1537 static int damon_sysfs_turn_damon_on(struct damon_sysfs_kdamond *kdamond) 1543 1538 { 1544 1539 struct damon_ctx *ctx; 1540 + struct damon_call_control *repeat_call_control; 1545 1541 int err; 1546 1542 1547 1543 if (damon_sysfs_kdamond_running(kdamond)) ··· 1550 1554 damon_destroy_ctx(kdamond->damon_ctx); 1551 1555 kdamond->damon_ctx = NULL; 1552 1556 1557 + repeat_call_control = kmalloc(sizeof(*repeat_call_control), 1558 + GFP_KERNEL); 1559 + if (!repeat_call_control) 1560 + return -ENOMEM; 1561 + 1553 1562 ctx = damon_sysfs_build_ctx(kdamond->contexts->contexts_arr[0]); 1554 - if (IS_ERR(ctx)) 1563 + if (IS_ERR(ctx)) { 1564 + kfree(repeat_call_control); 1555 1565 return PTR_ERR(ctx); 1566 + } 1556 1567 err = damon_start(&ctx, 1, false); 1557 1568 if (err) { 1569 + kfree(repeat_call_control); 1558 1570 damon_destroy_ctx(ctx); 1559 1571 return err; 1560 1572 } 1561 1573 kdamond->damon_ctx = ctx; 1562 1574 1563 - damon_sysfs_repeat_call_control.data = kdamond; 1564 - damon_call(ctx, &damon_sysfs_repeat_call_control); 1575 + repeat_call_control->fn = damon_sysfs_repeat_call_fn; 1576 + repeat_call_control->data = kdamond; 1577 + repeat_call_control->repeat = true; 1578 + repeat_call_control->dealloc_on_cancel = true; 1579 + damon_call(ctx, repeat_call_control); 1565 1580 return err; 1566 1581 } 1567 1582
+11 -3
mm/gup.c
··· 2287 2287 struct pages_or_folios *pofs) 2288 2288 { 2289 2289 unsigned long collected = 0; 2290 - bool drain_allow = true; 2291 2290 struct folio *folio; 2291 + int drained = 0; 2292 2292 long i = 0; 2293 2293 2294 2294 for (folio = pofs_get_folio(pofs, i); folio; ··· 2307 2307 continue; 2308 2308 } 2309 2309 2310 - if (!folio_test_lru(folio) && drain_allow) { 2310 + if (drained == 0 && folio_may_be_lru_cached(folio) && 2311 + folio_ref_count(folio) != 2312 + folio_expected_ref_count(folio) + 1) { 2313 + lru_add_drain(); 2314 + drained = 1; 2315 + } 2316 + if (drained == 1 && folio_may_be_lru_cached(folio) && 2317 + folio_ref_count(folio) != 2318 + folio_expected_ref_count(folio) + 1) { 2311 2319 lru_add_drain_all(); 2312 - drain_allow = false; 2320 + drained = 2; 2313 2321 } 2314 2322 2315 2323 if (!folio_isolate_lru(folio))
+3 -3
mm/mlock.c
··· 255 255 256 256 folio_get(folio); 257 257 if (!folio_batch_add(fbatch, mlock_lru(folio)) || 258 - folio_test_large(folio) || lru_cache_disabled()) 258 + !folio_may_be_lru_cached(folio) || lru_cache_disabled()) 259 259 mlock_folio_batch(fbatch); 260 260 local_unlock(&mlock_fbatch.lock); 261 261 } ··· 278 278 279 279 folio_get(folio); 280 280 if (!folio_batch_add(fbatch, mlock_new(folio)) || 281 - folio_test_large(folio) || lru_cache_disabled()) 281 + !folio_may_be_lru_cached(folio) || lru_cache_disabled()) 282 282 mlock_folio_batch(fbatch); 283 283 local_unlock(&mlock_fbatch.lock); 284 284 } ··· 299 299 */ 300 300 folio_get(folio); 301 301 if (!folio_batch_add(fbatch, folio) || 302 - folio_test_large(folio) || lru_cache_disabled()) 302 + !folio_may_be_lru_cached(folio) || lru_cache_disabled()) 303 303 mlock_folio_batch(fbatch); 304 304 local_unlock(&mlock_fbatch.lock); 305 305 }
+26 -24
mm/swap.c
··· 164 164 for (i = 0; i < folio_batch_count(fbatch); i++) { 165 165 struct folio *folio = fbatch->folios[i]; 166 166 167 + /* block memcg migration while the folio moves between lru */ 168 + if (move_fn != lru_add && !folio_test_clear_lru(folio)) 169 + continue; 170 + 167 171 folio_lruvec_relock_irqsave(folio, &lruvec, &flags); 168 172 move_fn(lruvec, folio); 169 173 ··· 180 176 } 181 177 182 178 static void __folio_batch_add_and_move(struct folio_batch __percpu *fbatch, 183 - struct folio *folio, move_fn_t move_fn, 184 - bool on_lru, bool disable_irq) 179 + struct folio *folio, move_fn_t move_fn, bool disable_irq) 185 180 { 186 181 unsigned long flags; 187 - 188 - if (on_lru && !folio_test_clear_lru(folio)) 189 - return; 190 182 191 183 folio_get(folio); 192 184 ··· 191 191 else 192 192 local_lock(&cpu_fbatches.lock); 193 193 194 - if (!folio_batch_add(this_cpu_ptr(fbatch), folio) || folio_test_large(folio) || 195 - lru_cache_disabled()) 194 + if (!folio_batch_add(this_cpu_ptr(fbatch), folio) || 195 + !folio_may_be_lru_cached(folio) || lru_cache_disabled()) 196 196 folio_batch_move_lru(this_cpu_ptr(fbatch), move_fn); 197 197 198 198 if (disable_irq) ··· 201 201 local_unlock(&cpu_fbatches.lock); 202 202 } 203 203 204 - #define folio_batch_add_and_move(folio, op, on_lru) \ 205 - __folio_batch_add_and_move( \ 206 - &cpu_fbatches.op, \ 207 - folio, \ 208 - op, \ 209 - on_lru, \ 210 - offsetof(struct cpu_fbatches, op) >= offsetof(struct cpu_fbatches, lock_irq) \ 204 + #define folio_batch_add_and_move(folio, op) \ 205 + __folio_batch_add_and_move( \ 206 + &cpu_fbatches.op, \ 207 + folio, \ 208 + op, \ 209 + offsetof(struct cpu_fbatches, op) >= \ 210 + offsetof(struct cpu_fbatches, lock_irq) \ 211 211 ) 212 212 213 213 static void lru_move_tail(struct lruvec *lruvec, struct folio *folio) ··· 231 231 void folio_rotate_reclaimable(struct folio *folio) 232 232 { 233 233 if (folio_test_locked(folio) || folio_test_dirty(folio) || 234 - folio_test_unevictable(folio)) 234 + folio_test_unevictable(folio) || !folio_test_lru(folio)) 235 235 return; 236 236 237 - folio_batch_add_and_move(folio, lru_move_tail, true); 237 + folio_batch_add_and_move(folio, lru_move_tail); 238 238 } 239 239 240 240 void lru_note_cost_unlock_irq(struct lruvec *lruvec, bool file, ··· 328 328 329 329 void folio_activate(struct folio *folio) 330 330 { 331 - if (folio_test_active(folio) || folio_test_unevictable(folio)) 331 + if (folio_test_active(folio) || folio_test_unevictable(folio) || 332 + !folio_test_lru(folio)) 332 333 return; 333 334 334 - folio_batch_add_and_move(folio, lru_activate, true); 335 + folio_batch_add_and_move(folio, lru_activate); 335 336 } 336 337 337 338 #else ··· 508 507 lru_gen_in_fault() && !(current->flags & PF_MEMALLOC)) 509 508 folio_set_active(folio); 510 509 511 - folio_batch_add_and_move(folio, lru_add, false); 510 + folio_batch_add_and_move(folio, lru_add); 512 511 } 513 512 EXPORT_SYMBOL(folio_add_lru); 514 513 ··· 686 685 void deactivate_file_folio(struct folio *folio) 687 686 { 688 687 /* Deactivating an unevictable folio will not accelerate reclaim */ 689 - if (folio_test_unevictable(folio)) 688 + if (folio_test_unevictable(folio) || !folio_test_lru(folio)) 690 689 return; 691 690 692 691 if (lru_gen_enabled() && lru_gen_clear_refs(folio)) 693 692 return; 694 693 695 - folio_batch_add_and_move(folio, lru_deactivate_file, true); 694 + folio_batch_add_and_move(folio, lru_deactivate_file); 696 695 } 697 696 698 697 /* ··· 705 704 */ 706 705 void folio_deactivate(struct folio *folio) 707 706 { 708 - if (folio_test_unevictable(folio)) 707 + if (folio_test_unevictable(folio) || !folio_test_lru(folio)) 709 708 return; 710 709 711 710 if (lru_gen_enabled() ? lru_gen_clear_refs(folio) : !folio_test_active(folio)) 712 711 return; 713 712 714 - folio_batch_add_and_move(folio, lru_deactivate, true); 713 + folio_batch_add_and_move(folio, lru_deactivate); 715 714 } 716 715 717 716 /** ··· 724 723 void folio_mark_lazyfree(struct folio *folio) 725 724 { 726 725 if (!folio_test_anon(folio) || !folio_test_swapbacked(folio) || 726 + !folio_test_lru(folio) || 727 727 folio_test_swapcache(folio) || folio_test_unevictable(folio)) 728 728 return; 729 729 730 - folio_batch_add_and_move(folio, lru_lazyfree, true); 730 + folio_batch_add_and_move(folio, lru_lazyfree); 731 731 } 732 732 733 733 void lru_add_drain(void)
+1 -1
mm/vmscan.c
··· 4507 4507 } 4508 4508 4509 4509 /* ineligible */ 4510 - if (!folio_test_lru(folio) || zone > sc->reclaim_idx) { 4510 + if (zone > sc->reclaim_idx) { 4511 4511 gen = folio_inc_gen(lruvec, folio, false); 4512 4512 list_move_tail(&folio->lru, &lrugen->folios[gen][type][zone]); 4513 4513 return true;
+3
samples/damon/mtier.c
··· 208 208 if (enabled == is_enabled) 209 209 return 0; 210 210 211 + if (!init_called) 212 + return 0; 213 + 211 214 if (enabled) { 212 215 err = damon_sample_mtier_start(); 213 216 if (err)
+3
samples/damon/prcl.c
··· 137 137 if (enabled == is_enabled) 138 138 return 0; 139 139 140 + if (!init_called) 141 + return 0; 142 + 140 143 if (enabled) { 141 144 err = damon_sample_prcl_start(); 142 145 if (err)
+3
samples/damon/wsse.c
··· 118 118 return 0; 119 119 120 120 if (enabled) { 121 + if (!init_called) 122 + return 0; 123 + 121 124 err = damon_sample_wsse_start(); 122 125 if (err) 123 126 enabled = false;