Skip to content

Commit 3ce9925

Browse files
committed
Merge tag 'mm-hotfixes-stable-2025-05-10-14-23' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull misc 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. About half are for MM. Five OCFS2 fixes and a few MAINTAINERS updates" * tag 'mm-hotfixes-stable-2025-05-10-14-23' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (22 commits) mm: fix folio_pte_batch() on XEN PV nilfs2: fix deadlock warnings caused by lock dependency in init_nilfs() mm/hugetlb: copy the CMA flag when demoting mm, swap: fix false warning for large allocation with !THP_SWAP selftests/mm: fix a build failure on powerpc selftests/mm: fix build break when compiling pkey_util.c mm: vmalloc: support more granular vrealloc() sizing tools/testing/selftests: fix guard region test tmpfs assumption ocfs2: stop quota recovery before disabling quotas ocfs2: implement handshaking with ocfs2 recovery thread ocfs2: switch osb->disable_recovery to enum mailmap: map Uwe's BayLibre addresses to a single one MAINTAINERS: add mm THP section mm/userfaultfd: fix uninitialized output field for -EAGAIN race selftests/mm: compaction_test: support platform with huge mount of memory MAINTAINERS: add core mm section ocfs2: fix panic in failed foilio allocation mm/huge_memory: fix dereferencing invalid pmd migration entry MAINTAINERS: add reverse mapping section x86: disable image size check for test builds ...
2 parents 3450309 + 7b08b74 commit 3ce9925

23 files changed

+314
-95
lines changed

.mailmap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,8 @@ Luca Ceresoli <luca.ceresoli@bootlin.com> <luca@lucaceresoli.net>
447447
Luca Weiss <luca@lucaweiss.eu> <luca@z3ntu.xyz>
448448
Lukasz Luba <lukasz.luba@arm.com> <l.luba@partner.samsung.com>
449449
Luo Jie <quic_luoj@quicinc.com> <luoj@codeaurora.org>
450+
Lance Yang <lance.yang@linux.dev> <ioworker0@gmail.com>
451+
Lance Yang <lance.yang@linux.dev> <mingzhe.yang@ly.com>
450452
Maciej W. Rozycki <macro@mips.com> <macro@imgtec.com>
451453
Maciej W. Rozycki <macro@orcam.me.uk> <macro@linux-mips.org>
452454
Maharaja Kennadyrajan <quic_mkenna@quicinc.com> <mkenna@codeaurora.org>
@@ -749,6 +751,7 @@ Tvrtko Ursulin <tursulin@ursulin.net> <tvrtko@ursulin.net>
749751
Tycho Andersen <tycho@tycho.pizza> <tycho@tycho.ws>
750752
Tzung-Bi Shih <tzungbi@kernel.org> <tzungbi@google.com>
751753
Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
754+
Uwe Kleine-König <u.kleine-koenig@baylibre.com> <ukleinek@baylibre.com>
752755
Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
753756
Uwe Kleine-König <ukleinek@strlen.de>
754757
Uwe Kleine-König <ukl@pengutronix.de>

MAINTAINERS

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15495,24 +15495,45 @@ F: Documentation/mm/
1549515495
F: include/linux/gfp.h
1549615496
F: include/linux/gfp_types.h
1549715497
F: include/linux/memfd.h
15498-
F: include/linux/memory.h
1549915498
F: include/linux/memory_hotplug.h
1550015499
F: include/linux/memory-tiers.h
1550115500
F: include/linux/mempolicy.h
1550215501
F: include/linux/mempool.h
1550315502
F: include/linux/memremap.h
15504-
F: include/linux/mm.h
15505-
F: include/linux/mm_*.h
1550615503
F: include/linux/mmzone.h
1550715504
F: include/linux/mmu_notifier.h
1550815505
F: include/linux/pagewalk.h
15509-
F: include/linux/rmap.h
1551015506
F: include/trace/events/ksm.h
1551115507
F: mm/
1551215508
F: tools/mm/
1551315509
F: tools/testing/selftests/mm/
1551415510
N: include/linux/page[-_]*
1551515511

15512+
MEMORY MANAGEMENT - CORE
15513+
M: Andrew Morton <akpm@linux-foundation.org>
15514+
M: David Hildenbrand <david@redhat.com>
15515+
R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
15516+
R: Liam R. Howlett <Liam.Howlett@oracle.com>
15517+
R: Vlastimil Babka <vbabka@suse.cz>
15518+
R: Mike Rapoport <rppt@kernel.org>
15519+
R: Suren Baghdasaryan <surenb@google.com>
15520+
R: Michal Hocko <mhocko@suse.com>
15521+
L: linux-mm@kvack.org
15522+
S: Maintained
15523+
W: http://www.linux-mm.org
15524+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
15525+
F: include/linux/memory.h
15526+
F: include/linux/mm.h
15527+
F: include/linux/mm_*.h
15528+
F: include/linux/mmdebug.h
15529+
F: include/linux/pagewalk.h
15530+
F: mm/Kconfig
15531+
F: mm/debug.c
15532+
F: mm/init-mm.c
15533+
F: mm/memory.c
15534+
F: mm/pagewalk.c
15535+
F: mm/util.c
15536+
1551615537
MEMORY MANAGEMENT - EXECMEM
1551715538
M: Andrew Morton <akpm@linux-foundation.org>
1551815539
M: Mike Rapoport <rppt@kernel.org>
@@ -15546,6 +15567,19 @@ F: mm/page_alloc.c
1554615567
F: include/linux/gfp.h
1554715568
F: include/linux/compaction.h
1554815569

15570+
MEMORY MANAGEMENT - RMAP (REVERSE MAPPING)
15571+
M: Andrew Morton <akpm@linux-foundation.org>
15572+
M: David Hildenbrand <david@redhat.com>
15573+
M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
15574+
R: Rik van Riel <riel@surriel.com>
15575+
R: Liam R. Howlett <Liam.Howlett@oracle.com>
15576+
R: Vlastimil Babka <vbabka@suse.cz>
15577+
R: Harry Yoo <harry.yoo@oracle.com>
15578+
L: linux-mm@kvack.org
15579+
S: Maintained
15580+
F: include/linux/rmap.h
15581+
F: mm/rmap.c
15582+
1554915583
MEMORY MANAGEMENT - SECRETMEM
1555015584
M: Andrew Morton <akpm@linux-foundation.org>
1555115585
M: Mike Rapoport <rppt@kernel.org>
@@ -15554,6 +15588,30 @@ S: Maintained
1555415588
F: include/linux/secretmem.h
1555515589
F: mm/secretmem.c
1555615590

15591+
MEMORY MANAGEMENT - THP (TRANSPARENT HUGE PAGE)
15592+
M: Andrew Morton <akpm@linux-foundation.org>
15593+
M: David Hildenbrand <david@redhat.com>
15594+
R: Zi Yan <ziy@nvidia.com>
15595+
R: Baolin Wang <baolin.wang@linux.alibaba.com>
15596+
R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
15597+
R: Liam R. Howlett <Liam.Howlett@oracle.com>
15598+
R: Nico Pache <npache@redhat.com>
15599+
R: Ryan Roberts <ryan.roberts@arm.com>
15600+
R: Dev Jain <dev.jain@arm.com>
15601+
L: linux-mm@kvack.org
15602+
S: Maintained
15603+
W: http://www.linux-mm.org
15604+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
15605+
F: Documentation/admin-guide/mm/transhuge.rst
15606+
F: include/linux/huge_mm.h
15607+
F: include/linux/khugepaged.h
15608+
F: include/trace/events/huge_memory.h
15609+
F: mm/huge_memory.c
15610+
F: mm/khugepaged.c
15611+
F: tools/testing/selftests/mm/khugepaged.c
15612+
F: tools/testing/selftests/mm/split_huge_page_test.c
15613+
F: tools/testing/selftests/mm/transhuge-stress.c
15614+
1555715615
MEMORY MANAGEMENT - USERFAULTFD
1555815616
M: Andrew Morton <akpm@linux-foundation.org>
1555915617
R: Peter Xu <peterx@redhat.com>

arch/x86/kernel/vmlinux.lds.S

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,10 +466,18 @@ SECTIONS
466466
}
467467

468468
/*
469-
* The ASSERT() sink to . is intentional, for binutils 2.14 compatibility:
469+
* COMPILE_TEST kernels can be large - CONFIG_KASAN, for example, can cause
470+
* this. Let's assume that nobody will be running a COMPILE_TEST kernel and
471+
* let's assert that fuller build coverage is more valuable than being able to
472+
* run a COMPILE_TEST kernel.
473+
*/
474+
#ifndef CONFIG_COMPILE_TEST
475+
/*
476+
* The ASSERT() sync to . is intentional, for binutils 2.14 compatibility:
470477
*/
471478
. = ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE),
472479
"kernel image bigger than KERNEL_IMAGE_SIZE");
480+
#endif
473481

474482
/* needed for Clang - see arch/x86/entry/entry.S */
475483
PROVIDE(__ref_stack_chk_guard = __stack_chk_guard);

fs/nilfs2/the_nilfs.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -705,8 +705,6 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
705705
int blocksize;
706706
int err;
707707

708-
down_write(&nilfs->ns_sem);
709-
710708
blocksize = sb_min_blocksize(sb, NILFS_MIN_BLOCK_SIZE);
711709
if (!blocksize) {
712710
nilfs_err(sb, "unable to set blocksize");
@@ -779,7 +777,6 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
779777
set_nilfs_init(nilfs);
780778
err = 0;
781779
out:
782-
up_write(&nilfs->ns_sem);
783780
return err;
784781

785782
failed_sbh:

fs/ocfs2/alloc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6918,6 +6918,7 @@ static int ocfs2_grab_folios(struct inode *inode, loff_t start, loff_t end,
69186918
if (IS_ERR(folios[numfolios])) {
69196919
ret = PTR_ERR(folios[numfolios]);
69206920
mlog_errno(ret);
6921+
folios[numfolios] = NULL;
69216922
goto out;
69226923
}
69236924

fs/ocfs2/journal.c

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ int ocfs2_recovery_init(struct ocfs2_super *osb)
174174
struct ocfs2_recovery_map *rm;
175175

176176
mutex_init(&osb->recovery_lock);
177-
osb->disable_recovery = 0;
177+
osb->recovery_state = OCFS2_REC_ENABLED;
178178
osb->recovery_thread_task = NULL;
179179
init_waitqueue_head(&osb->recovery_event);
180180

@@ -190,31 +190,53 @@ int ocfs2_recovery_init(struct ocfs2_super *osb)
190190
return 0;
191191
}
192192

193-
/* we can't grab the goofy sem lock from inside wait_event, so we use
194-
* memory barriers to make sure that we'll see the null task before
195-
* being woken up */
196193
static int ocfs2_recovery_thread_running(struct ocfs2_super *osb)
197194
{
198-
mb();
199195
return osb->recovery_thread_task != NULL;
200196
}
201197

202-
void ocfs2_recovery_exit(struct ocfs2_super *osb)
198+
static void ocfs2_recovery_disable(struct ocfs2_super *osb,
199+
enum ocfs2_recovery_state state)
203200
{
204-
struct ocfs2_recovery_map *rm;
205-
206-
/* disable any new recovery threads and wait for any currently
207-
* running ones to exit. Do this before setting the vol_state. */
208201
mutex_lock(&osb->recovery_lock);
209-
osb->disable_recovery = 1;
202+
/*
203+
* If recovery thread is not running, we can directly transition to
204+
* final state.
205+
*/
206+
if (!ocfs2_recovery_thread_running(osb)) {
207+
osb->recovery_state = state + 1;
208+
goto out_lock;
209+
}
210+
osb->recovery_state = state;
211+
/* Wait for recovery thread to acknowledge state transition */
212+
wait_event_cmd(osb->recovery_event,
213+
!ocfs2_recovery_thread_running(osb) ||
214+
osb->recovery_state >= state + 1,
215+
mutex_unlock(&osb->recovery_lock),
216+
mutex_lock(&osb->recovery_lock));
217+
out_lock:
210218
mutex_unlock(&osb->recovery_lock);
211-
wait_event(osb->recovery_event, !ocfs2_recovery_thread_running(osb));
212219

213-
/* At this point, we know that no more recovery threads can be
214-
* launched, so wait for any recovery completion work to
215-
* complete. */
220+
/*
221+
* At this point we know that no more recovery work can be queued so
222+
* wait for any recovery completion work to complete.
223+
*/
216224
if (osb->ocfs2_wq)
217225
flush_workqueue(osb->ocfs2_wq);
226+
}
227+
228+
void ocfs2_recovery_disable_quota(struct ocfs2_super *osb)
229+
{
230+
ocfs2_recovery_disable(osb, OCFS2_REC_QUOTA_WANT_DISABLE);
231+
}
232+
233+
void ocfs2_recovery_exit(struct ocfs2_super *osb)
234+
{
235+
struct ocfs2_recovery_map *rm;
236+
237+
/* disable any new recovery threads and wait for any currently
238+
* running ones to exit. Do this before setting the vol_state. */
239+
ocfs2_recovery_disable(osb, OCFS2_REC_WANT_DISABLE);
218240

219241
/*
220242
* Now that recovery is shut down, and the osb is about to be
@@ -1472,6 +1494,18 @@ static int __ocfs2_recovery_thread(void *arg)
14721494
}
14731495
}
14741496
restart:
1497+
if (quota_enabled) {
1498+
mutex_lock(&osb->recovery_lock);
1499+
/* Confirm that recovery thread will no longer recover quotas */
1500+
if (osb->recovery_state == OCFS2_REC_QUOTA_WANT_DISABLE) {
1501+
osb->recovery_state = OCFS2_REC_QUOTA_DISABLED;
1502+
wake_up(&osb->recovery_event);
1503+
}
1504+
if (osb->recovery_state >= OCFS2_REC_QUOTA_DISABLED)
1505+
quota_enabled = 0;
1506+
mutex_unlock(&osb->recovery_lock);
1507+
}
1508+
14751509
status = ocfs2_super_lock(osb, 1);
14761510
if (status < 0) {
14771511
mlog_errno(status);
@@ -1569,27 +1603,29 @@ static int __ocfs2_recovery_thread(void *arg)
15691603

15701604
ocfs2_free_replay_slots(osb);
15711605
osb->recovery_thread_task = NULL;
1572-
mb(); /* sync with ocfs2_recovery_thread_running */
1606+
if (osb->recovery_state == OCFS2_REC_WANT_DISABLE)
1607+
osb->recovery_state = OCFS2_REC_DISABLED;
15731608
wake_up(&osb->recovery_event);
15741609

15751610
mutex_unlock(&osb->recovery_lock);
15761611

1577-
if (quota_enabled)
1578-
kfree(rm_quota);
1612+
kfree(rm_quota);
15791613

15801614
return status;
15811615
}
15821616

15831617
void ocfs2_recovery_thread(struct ocfs2_super *osb, int node_num)
15841618
{
1619+
int was_set = -1;
1620+
15851621
mutex_lock(&osb->recovery_lock);
1622+
if (osb->recovery_state < OCFS2_REC_WANT_DISABLE)
1623+
was_set = ocfs2_recovery_map_set(osb, node_num);
15861624

15871625
trace_ocfs2_recovery_thread(node_num, osb->node_num,
1588-
osb->disable_recovery, osb->recovery_thread_task,
1589-
osb->disable_recovery ?
1590-
-1 : ocfs2_recovery_map_set(osb, node_num));
1626+
osb->recovery_state, osb->recovery_thread_task, was_set);
15911627

1592-
if (osb->disable_recovery)
1628+
if (osb->recovery_state >= OCFS2_REC_WANT_DISABLE)
15931629
goto out;
15941630

15951631
if (osb->recovery_thread_task)

fs/ocfs2/journal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ void ocfs2_wait_for_recovery(struct ocfs2_super *osb);
148148

149149
int ocfs2_recovery_init(struct ocfs2_super *osb);
150150
void ocfs2_recovery_exit(struct ocfs2_super *osb);
151+
void ocfs2_recovery_disable_quota(struct ocfs2_super *osb);
151152

152153
int ocfs2_compute_replay_slots(struct ocfs2_super *osb);
153154
void ocfs2_free_replay_slots(struct ocfs2_super *osb);

fs/ocfs2/ocfs2.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,21 @@ enum ocfs2_journal_trigger_type {
308308
void ocfs2_initialize_journal_triggers(struct super_block *sb,
309309
struct ocfs2_triggers triggers[]);
310310

311+
enum ocfs2_recovery_state {
312+
OCFS2_REC_ENABLED = 0,
313+
OCFS2_REC_QUOTA_WANT_DISABLE,
314+
/*
315+
* Must be OCFS2_REC_QUOTA_WANT_DISABLE + 1 for
316+
* ocfs2_recovery_disable_quota() to work.
317+
*/
318+
OCFS2_REC_QUOTA_DISABLED,
319+
OCFS2_REC_WANT_DISABLE,
320+
/*
321+
* Must be OCFS2_REC_WANT_DISABLE + 1 for ocfs2_recovery_exit() to work
322+
*/
323+
OCFS2_REC_DISABLED,
324+
};
325+
311326
struct ocfs2_journal;
312327
struct ocfs2_slot_info;
313328
struct ocfs2_recovery_map;
@@ -370,7 +385,7 @@ struct ocfs2_super
370385
struct ocfs2_recovery_map *recovery_map;
371386
struct ocfs2_replay_map *replay_map;
372387
struct task_struct *recovery_thread_task;
373-
int disable_recovery;
388+
enum ocfs2_recovery_state recovery_state;
374389
wait_queue_head_t checkpoint_event;
375390
struct ocfs2_journal *journal;
376391
unsigned long osb_commit_interval;

fs/ocfs2/quota_local.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,7 @@ struct ocfs2_quota_recovery *ocfs2_begin_quota_recovery(
453453

454454
/* Sync changes in local quota file into global quota file and
455455
* reinitialize local quota file.
456-
* The function expects local quota file to be already locked and
457-
* s_umount locked in shared mode. */
456+
* The function expects local quota file to be already locked. */
458457
static int ocfs2_recover_local_quota_file(struct inode *lqinode,
459458
int type,
460459
struct ocfs2_quota_recovery *rec)
@@ -588,7 +587,6 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
588587
{
589588
unsigned int ino[OCFS2_MAXQUOTAS] = { LOCAL_USER_QUOTA_SYSTEM_INODE,
590589
LOCAL_GROUP_QUOTA_SYSTEM_INODE };
591-
struct super_block *sb = osb->sb;
592590
struct ocfs2_local_disk_dqinfo *ldinfo;
593591
struct buffer_head *bh;
594592
handle_t *handle;
@@ -600,7 +598,6 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
600598
printk(KERN_NOTICE "ocfs2: Finishing quota recovery on device (%s) for "
601599
"slot %u\n", osb->dev_str, slot_num);
602600

603-
down_read(&sb->s_umount);
604601
for (type = 0; type < OCFS2_MAXQUOTAS; type++) {
605602
if (list_empty(&(rec->r_list[type])))
606603
continue;
@@ -677,7 +674,6 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
677674
break;
678675
}
679676
out:
680-
up_read(&sb->s_umount);
681677
kfree(rec);
682678
return status;
683679
}
@@ -843,8 +839,7 @@ static int ocfs2_local_free_info(struct super_block *sb, int type)
843839
ocfs2_release_local_quota_bitmaps(&oinfo->dqi_chunk);
844840

845841
/*
846-
* s_umount held in exclusive mode protects us against racing with
847-
* recovery thread...
842+
* ocfs2_dismount_volume() has already aborted quota recovery...
848843
*/
849844
if (oinfo->dqi_rec) {
850845
ocfs2_free_quota_recovery(oinfo->dqi_rec);

0 commit comments

Comments
 (0)