Skip to content

Commit 8b789f2

Browse files
committed
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
2 parents 592a93f + ce4be9e commit 8b789f2

File tree

15 files changed

+94
-52
lines changed

15 files changed

+94
-52
lines changed

MAINTAINERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16196,6 +16196,7 @@ R: Rik van Riel <[email protected]>
1619616196
R: Liam R. Howlett <[email protected]>
1619716197
R: Vlastimil Babka <[email protected]>
1619816198
R: Harry Yoo <[email protected]>
16199+
R: Jann Horn <[email protected]>
1619916200
1620016201
S: Maintained
1620116202
F: include/linux/rmap.h
@@ -16240,6 +16241,7 @@ R: Nico Pache <[email protected]>
1624016241
R: Ryan Roberts <[email protected]>
1624116242
R: Dev Jain <[email protected]>
1624216243
R: Barry Song <[email protected]>
16244+
R: Lance Yang <[email protected]>
1624316245
1624416246
S: Maintained
1624516247
W: http://www.linux-mm.org

drivers/block/zram/zram_drv.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,6 +1795,7 @@ static int write_same_filled_page(struct zram *zram, unsigned long fill,
17951795
u32 index)
17961796
{
17971797
zram_slot_lock(zram, index);
1798+
zram_free_page(zram, index);
17981799
zram_set_flag(zram, index, ZRAM_SAME);
17991800
zram_set_handle(zram, index, fill);
18001801
zram_slot_unlock(zram, index);
@@ -1832,6 +1833,7 @@ static int write_incompressible_page(struct zram *zram, struct page *page,
18321833
kunmap_local(src);
18331834

18341835
zram_slot_lock(zram, index);
1836+
zram_free_page(zram, index);
18351837
zram_set_flag(zram, index, ZRAM_HUGE);
18361838
zram_set_handle(zram, index, handle);
18371839
zram_set_obj_size(zram, index, PAGE_SIZE);
@@ -1855,11 +1857,6 @@ static int zram_write_page(struct zram *zram, struct page *page, u32 index)
18551857
unsigned long element;
18561858
bool same_filled;
18571859

1858-
/* First, free memory allocated to this slot (if any) */
1859-
zram_slot_lock(zram, index);
1860-
zram_free_page(zram, index);
1861-
zram_slot_unlock(zram, index);
1862-
18631860
mem = kmap_local_page(page);
18641861
same_filled = page_same_filled(mem, &element);
18651862
kunmap_local(mem);
@@ -1901,6 +1898,7 @@ static int zram_write_page(struct zram *zram, struct page *page, u32 index)
19011898
zcomp_stream_put(zstrm);
19021899

19031900
zram_slot_lock(zram, index);
1901+
zram_free_page(zram, index);
19041902
zram_set_handle(zram, index, handle);
19051903
zram_set_obj_size(zram, index, comp_len);
19061904
zram_slot_unlock(zram, index);

fs/nilfs2/sysfs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,7 +1075,7 @@ void nilfs_sysfs_delete_device_group(struct the_nilfs *nilfs)
10751075
************************************************************************/
10761076

10771077
static ssize_t nilfs_feature_revision_show(struct kobject *kobj,
1078-
struct attribute *attr, char *buf)
1078+
struct kobj_attribute *attr, char *buf)
10791079
{
10801080
return sysfs_emit(buf, "%d.%d\n",
10811081
NILFS_CURRENT_REV, NILFS_MINOR_REV);
@@ -1087,7 +1087,7 @@ static const char features_readme_str[] =
10871087
"(1) revision\n\tshow current revision of NILFS file system driver.\n";
10881088

10891089
static ssize_t nilfs_feature_README_show(struct kobject *kobj,
1090-
struct attribute *attr,
1090+
struct kobj_attribute *attr,
10911091
char *buf)
10921092
{
10931093
return sysfs_emit(buf, features_readme_str);

fs/nilfs2/sysfs.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,16 @@ struct nilfs_sysfs_dev_subgroups {
5050
struct completion sg_segments_kobj_unregister;
5151
};
5252

53-
#define NILFS_COMMON_ATTR_STRUCT(name) \
53+
#define NILFS_KOBJ_ATTR_STRUCT(name) \
5454
struct nilfs_##name##_attr { \
5555
struct attribute attr; \
56-
ssize_t (*show)(struct kobject *, struct attribute *, \
56+
ssize_t (*show)(struct kobject *, struct kobj_attribute *, \
5757
char *); \
58-
ssize_t (*store)(struct kobject *, struct attribute *, \
58+
ssize_t (*store)(struct kobject *, struct kobj_attribute *, \
5959
const char *, size_t); \
6060
}
6161

62-
NILFS_COMMON_ATTR_STRUCT(feature);
62+
NILFS_KOBJ_ATTR_STRUCT(feature);
6363

6464
#define NILFS_DEV_ATTR_STRUCT(name) \
6565
struct nilfs_##name##_attr { \

include/linux/damon.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ struct damon_operations {
636636
* @data: Data that will be passed to @fn.
637637
* @repeat: Repeat invocations.
638638
* @return_code: Return code from @fn invocation.
639+
* @dealloc_on_cancel: De-allocate when canceled.
639640
*
640641
* Control damon_call(), which requests specific kdamond to invoke a given
641642
* function. Refer to damon_call() for more details.
@@ -645,6 +646,7 @@ struct damon_call_control {
645646
void *data;
646647
bool repeat;
647648
int return_code;
649+
bool dealloc_on_cancel;
648650
/* private: internal use only */
649651
/* informs if the kdamond finished handling of the request */
650652
struct completion completion;

include/linux/swap.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,16 @@ void folio_add_lru_vma(struct folio *, struct vm_area_struct *);
385385
void mark_page_accessed(struct page *);
386386
void folio_mark_accessed(struct folio *);
387387

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+
388398
extern atomic_t lru_disable_count;
389399

390400
static inline bool lru_cache_disabled(void)

mm/damon/core.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2479,10 +2479,14 @@ static void kdamond_call(struct damon_ctx *ctx, bool cancel)
24792479
mutex_lock(&ctx->call_controls_lock);
24802480
list_del(&control->list);
24812481
mutex_unlock(&ctx->call_controls_lock);
2482-
if (!control->repeat)
2482+
if (!control->repeat) {
24832483
complete(&control->completion);
2484-
else
2484+
} else if (control->canceled && control->dealloc_on_cancel) {
2485+
kfree(control);
2486+
continue;
2487+
} else {
24852488
list_add(&control->list, &repeat_controls);
2489+
}
24862490
}
24872491
control = list_first_entry_or_null(&repeat_controls,
24882492
struct damon_call_control, list);

mm/damon/sysfs.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,14 +1534,10 @@ static int damon_sysfs_repeat_call_fn(void *data)
15341534
return 0;
15351535
}
15361536

1537-
static struct damon_call_control damon_sysfs_repeat_call_control = {
1538-
.fn = damon_sysfs_repeat_call_fn,
1539-
.repeat = true,
1540-
};
1541-
15421537
static int damon_sysfs_turn_damon_on(struct damon_sysfs_kdamond *kdamond)
15431538
{
15441539
struct damon_ctx *ctx;
1540+
struct damon_call_control *repeat_call_control;
15451541
int err;
15461542

15471543
if (damon_sysfs_kdamond_running(kdamond))
@@ -1554,18 +1550,29 @@ static int damon_sysfs_turn_damon_on(struct damon_sysfs_kdamond *kdamond)
15541550
damon_destroy_ctx(kdamond->damon_ctx);
15551551
kdamond->damon_ctx = NULL;
15561552

1553+
repeat_call_control = kmalloc(sizeof(*repeat_call_control),
1554+
GFP_KERNEL);
1555+
if (!repeat_call_control)
1556+
return -ENOMEM;
1557+
15571558
ctx = damon_sysfs_build_ctx(kdamond->contexts->contexts_arr[0]);
1558-
if (IS_ERR(ctx))
1559+
if (IS_ERR(ctx)) {
1560+
kfree(repeat_call_control);
15591561
return PTR_ERR(ctx);
1562+
}
15601563
err = damon_start(&ctx, 1, false);
15611564
if (err) {
1565+
kfree(repeat_call_control);
15621566
damon_destroy_ctx(ctx);
15631567
return err;
15641568
}
15651569
kdamond->damon_ctx = ctx;
15661570

1567-
damon_sysfs_repeat_call_control.data = kdamond;
1568-
damon_call(ctx, &damon_sysfs_repeat_call_control);
1571+
repeat_call_control->fn = damon_sysfs_repeat_call_fn;
1572+
repeat_call_control->data = kdamond;
1573+
repeat_call_control->repeat = true;
1574+
repeat_call_control->dealloc_on_cancel = true;
1575+
damon_call(ctx, repeat_call_control);
15691576
return err;
15701577
}
15711578

mm/gup.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2287,8 +2287,8 @@ static unsigned long collect_longterm_unpinnable_folios(
22872287
struct pages_or_folios *pofs)
22882288
{
22892289
unsigned long collected = 0;
2290-
bool drain_allow = true;
22912290
struct folio *folio;
2291+
int drained = 0;
22922292
long i = 0;
22932293

22942294
for (folio = pofs_get_folio(pofs, i); folio;
@@ -2307,9 +2307,17 @@ static unsigned long collect_longterm_unpinnable_folios(
23072307
continue;
23082308
}
23092309

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) {
23112319
lru_add_drain_all();
2312-
drain_allow = false;
2320+
drained = 2;
23132321
}
23142322

23152323
if (!folio_isolate_lru(folio))

mm/mlock.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ void mlock_folio(struct folio *folio)
255255

256256
folio_get(folio);
257257
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())
259259
mlock_folio_batch(fbatch);
260260
local_unlock(&mlock_fbatch.lock);
261261
}
@@ -278,7 +278,7 @@ void mlock_new_folio(struct folio *folio)
278278

279279
folio_get(folio);
280280
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())
282282
mlock_folio_batch(fbatch);
283283
local_unlock(&mlock_fbatch.lock);
284284
}
@@ -299,7 +299,7 @@ void munlock_folio(struct folio *folio)
299299
*/
300300
folio_get(folio);
301301
if (!folio_batch_add(fbatch, folio) ||
302-
folio_test_large(folio) || lru_cache_disabled())
302+
!folio_may_be_lru_cached(folio) || lru_cache_disabled())
303303
mlock_folio_batch(fbatch);
304304
local_unlock(&mlock_fbatch.lock);
305305
}

0 commit comments

Comments
 (0)