History

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 ...

Linus Torvalds committed 1 year ago

Commit 3ce99252 parents 3450309 7b08b7423 files · +314 −95Browse files

Unified · Split

23 files
  1. .mailmap +3 −0
  2. MAINTAINERS +62 −4
  3. arch/x86/kernel/vmlinux.lds.S +9 −1
  4. fs/nilfs2/the_nilfs.c +0 −3
  5. fs/ocfs2/alloc.c +1 −0
  6. fs/ocfs2/journal.c +58 −22
  7. fs/ocfs2/journal.h +1 −0
  8. fs/ocfs2/ocfs2.h +16 −1
  9. fs/ocfs2/quota_local.c +2 −7
  10. fs/ocfs2/suballoc.c +32 −6
  11. fs/ocfs2/suballoc.h +1 −0
  12. fs/ocfs2/super.c +3 −0
  13. fs/userfaultfd.c +22 −6
  14. include/linux/vmalloc.h +1 −0
  15. mm/huge_memory.c +8 −3
  16. mm/hugetlb.c +6 −0
  17. mm/internal.h +11 −16
  18. mm/swapfile.c +16 −7
  19. mm/vmalloc.c +24 −7
  20. tools/testing/selftests/mm/compaction_test.c +14 −5
  21. tools/testing/selftests/mm/guard-regions.c +10 −6
  22. tools/testing/selftests/mm/pkey-powerpc.h +13 −1
  23. tools/testing/selftests/mm/pkey_util.c +1 −0
.mailmap+3−0
@@ -447,6 +447,8 @@ Luca Ceresoli <luca.ceresoli@bootlin.com> <luca@lucaceresoli.net> · 446 unmodified lines
447Luca Weiss <luca@lucaweiss.eu> <luca@z3ntu.xyz>447Luca Weiss <luca@lucaweiss.eu> <luca@z3ntu.xyz>
448Lukasz Luba <lukasz.luba@arm.com> <l.luba@partner.samsung.com>448Lukasz Luba <lukasz.luba@arm.com> <l.luba@partner.samsung.com>
449Luo Jie <quic_luoj@quicinc.com> <luoj@codeaurora.org>449Luo Jie <quic_luoj@quicinc.com> <luoj@codeaurora.org>
450Lance Yang <lance.yang@linux.dev> <ioworker0@gmail.com>
451Lance Yang <lance.yang@linux.dev> <mingzhe.yang@ly.com>
450Maciej W. Rozycki <macro@mips.com> <macro@imgtec.com>452Maciej W. Rozycki <macro@mips.com> <macro@imgtec.com>
451Maciej W. Rozycki <macro@orcam.me.uk> <macro@linux-mips.org>453Maciej W. Rozycki <macro@orcam.me.uk> <macro@linux-mips.org>
452Maharaja Kennadyrajan <quic_mkenna@quicinc.com> <mkenna@codeaurora.org>454Maharaja Kennadyrajan <quic_mkenna@quicinc.com> <mkenna@codeaurora.org>
@@ -749,6 +751,7 @@ Tvrtko Ursulin <tursulin@ursulin.net> <tvrtko@ursulin.net> · 296 unmodified lines
749Tycho Andersen <tycho@tycho.pizza> <tycho@tycho.ws>751Tycho Andersen <tycho@tycho.pizza> <tycho@tycho.ws>
750Tzung-Bi Shih <tzungbi@kernel.org> <tzungbi@google.com>752Tzung-Bi Shih <tzungbi@kernel.org> <tzungbi@google.com>
751Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>753Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
754Uwe Kleine-König <u.kleine-koenig@baylibre.com> <ukleinek@baylibre.com>
752Uwe Kleine-König <u.kleine-koenig@pengutronix.de>755Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
753Uwe Kleine-König <ukleinek@strlen.de>756Uwe Kleine-König <ukleinek@strlen.de>
754Uwe Kleine-König <ukl@pengutronix.de>757Uwe Kleine-König <ukl@pengutronix.de>
MAINTAINERS+62−4
@@ -15495,24 +15495,45 @@ F: Documentation/mm/ · 15494 unmodified lines
15495F: include/linux/gfp.h15495F: include/linux/gfp.h
15496F: include/linux/gfp_types.h15496F: include/linux/gfp_types.h
15497F: include/linux/memfd.h15497F: include/linux/memfd.h
15498F: include/linux/memory.h
15499F: include/linux/memory_hotplug.h15498F: include/linux/memory_hotplug.h
15500F: include/linux/memory-tiers.h15499F: include/linux/memory-tiers.h
15501F: include/linux/mempolicy.h15500F: include/linux/mempolicy.h
15502F: include/linux/mempool.h15501F: include/linux/mempool.h
15503F: include/linux/memremap.h15502F: include/linux/memremap.h
15504F: include/linux/mm.h
15505F: include/linux/mm_*.h
15506F: include/linux/mmzone.h15503F: include/linux/mmzone.h
15507F: include/linux/mmu_notifier.h15504F: include/linux/mmu_notifier.h
15508F: include/linux/pagewalk.h15505F: include/linux/pagewalk.h
15509F: include/linux/rmap.h
15510F: include/trace/events/ksm.h15506F: include/trace/events/ksm.h
15511F: mm/15507F: mm/
15512F: tools/mm/15508F: tools/mm/
15513F: tools/testing/selftests/mm/15509F: tools/testing/selftests/mm/
15514N: include/linux/page[-_]*15510N: include/linux/page[-_]*
15515 15511
15512MEMORY MANAGEMENT - CORE
15513M: Andrew Morton <akpm@linux-foundation.org>
15514M: David Hildenbrand <david@redhat.com>
15515R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
15516R: Liam R. Howlett <Liam.Howlett@oracle.com>
15517R: Vlastimil Babka <vbabka@suse.cz>
15518R: Mike Rapoport <rppt@kernel.org>
15519R: Suren Baghdasaryan <surenb@google.com>
15520R: Michal Hocko <mhocko@suse.com>
15521L: linux-mm@kvack.org
15522S: Maintained
15523W: http://www.linux-mm.org
15524T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
15525F: include/linux/memory.h
15526F: include/linux/mm.h
15527F: include/linux/mm_*.h
15528F: include/linux/mmdebug.h
15529F: include/linux/pagewalk.h
15530F: mm/Kconfig
15531F: mm/debug.c
15532F: mm/init-mm.c
15533F: mm/memory.c
15534F: mm/pagewalk.c
15535F: mm/util.c
15536
15516MEMORY MANAGEMENT - EXECMEM15537MEMORY MANAGEMENT - EXECMEM
15517M: Andrew Morton <akpm@linux-foundation.org>15538M: Andrew Morton <akpm@linux-foundation.org>
15518M: Mike Rapoport <rppt@kernel.org>15539M: Mike Rapoport <rppt@kernel.org>
@@ -15546,6 +15567,19 @@ F: mm/page_alloc.c · 27 unmodified lines
15546F: include/linux/gfp.h15567F: include/linux/gfp.h
15547F: include/linux/compaction.h15568F: include/linux/compaction.h
15548 15569
15570MEMORY MANAGEMENT - RMAP (REVERSE MAPPING)
15571M: Andrew Morton <akpm@linux-foundation.org>
15572M: David Hildenbrand <david@redhat.com>
15573M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
15574R: Rik van Riel <riel@surriel.com>
15575R: Liam R. Howlett <Liam.Howlett@oracle.com>
15576R: Vlastimil Babka <vbabka@suse.cz>
15577R: Harry Yoo <harry.yoo@oracle.com>
15578L: linux-mm@kvack.org
15579S: Maintained
15580F: include/linux/rmap.h
15581F: mm/rmap.c
15582
15549MEMORY MANAGEMENT - SECRETMEM15583MEMORY MANAGEMENT - SECRETMEM
15550M: Andrew Morton <akpm@linux-foundation.org>15584M: Andrew Morton <akpm@linux-foundation.org>
15551M: Mike Rapoport <rppt@kernel.org>15585M: Mike Rapoport <rppt@kernel.org>
@@ -15554,6 +15588,30 @@ S: Maintained · 2 unmodified lines
15554F: include/linux/secretmem.h15588F: include/linux/secretmem.h
15555F: mm/secretmem.c15589F: mm/secretmem.c
15556 15590
15591MEMORY MANAGEMENT - THP (TRANSPARENT HUGE PAGE)
15592M: Andrew Morton <akpm@linux-foundation.org>
15593M: David Hildenbrand <david@redhat.com>
15594R: Zi Yan <ziy@nvidia.com>
15595R: Baolin Wang <baolin.wang@linux.alibaba.com>
15596R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
15597R: Liam R. Howlett <Liam.Howlett@oracle.com>
15598R: Nico Pache <npache@redhat.com>
15599R: Ryan Roberts <ryan.roberts@arm.com>
15600R: Dev Jain <dev.jain@arm.com>
15601L: linux-mm@kvack.org
15602S: Maintained
15603W: http://www.linux-mm.org
15604T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
15605F: Documentation/admin-guide/mm/transhuge.rst
15606F: include/linux/huge_mm.h
15607F: include/linux/khugepaged.h
15608F: include/trace/events/huge_memory.h
15609F: mm/huge_memory.c
15610F: mm/khugepaged.c
15611F: tools/testing/selftests/mm/khugepaged.c
15612F: tools/testing/selftests/mm/split_huge_page_test.c
15613F: tools/testing/selftests/mm/transhuge-stress.c
15614
15557MEMORY MANAGEMENT - USERFAULTFD15615MEMORY MANAGEMENT - USERFAULTFD
15558M: Andrew Morton <akpm@linux-foundation.org>15616M: Andrew Morton <akpm@linux-foundation.org>
15559R: Peter Xu <peterx@redhat.com>15617R: Peter Xu <peterx@redhat.com>
arch/x86/kernel/vmlinux.lds.S+9−1
@@ -466,10 +466,18 @@ SECTIONS · 465 unmodified lines
466}466}
467 467
468/*468/*
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:
470 */477 */
471. = ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE),478. = ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE),
472 "kernel image bigger than KERNEL_IMAGE_SIZE");479 "kernel image bigger than KERNEL_IMAGE_SIZE");
480#endif
473 481
474/* needed for Clang - see arch/x86/entry/entry.S */482/* needed for Clang - see arch/x86/entry/entry.S */
475PROVIDE(__ref_stack_chk_guard = __stack_chk_guard);483PROVIDE(__ref_stack_chk_guard = __stack_chk_guard);
fs/nilfs2/the_nilfs.c+0−3
@@ -705,8 +705,6 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb) · 704 unmodified lines
705 int blocksize;705 int blocksize;
706 int err;706 int err;
707 707
708 down_write(&nilfs->ns_sem);
709
710 blocksize = sb_min_blocksize(sb, NILFS_MIN_BLOCK_SIZE);708 blocksize = sb_min_blocksize(sb, NILFS_MIN_BLOCK_SIZE);
711 if (!blocksize) {709 if (!blocksize) {
712 nilfs_err(sb, "unable to set blocksize");710 nilfs_err(sb, "unable to set blocksize");
@@ -779,7 +777,6 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb) · 66 unmodified lines
779 set_nilfs_init(nilfs);777 set_nilfs_init(nilfs);
780 err = 0;778 err = 0;
781 out:779 out:
782 up_write(&nilfs->ns_sem);
783 return err;780 return err;
784 781
785 failed_sbh:782 failed_sbh:
fs/ocfs2/alloc.c+1−0
@@ -6918,6 +6918,7 @@ static int ocfs2_grab_folios(struct inode *inode, loff_t start, loff_t end, · 6917 unmodified lines
6918 if (IS_ERR(folios[numfolios])) {6918 if (IS_ERR(folios[numfolios])) {
6919 ret = PTR_ERR(folios[numfolios]);6919 ret = PTR_ERR(folios[numfolios]);
6920 mlog_errno(ret);6920 mlog_errno(ret);
6921 folios[numfolios] = NULL;
6921 goto out;6922 goto out;
6922 }6923 }
6923 6924
fs/ocfs2/journal.c+58−22
@@ -174,7 +174,7 @@ int ocfs2_recovery_init(struct ocfs2_super *osb) · 173 unmodified lines
174 struct ocfs2_recovery_map *rm;174 struct ocfs2_recovery_map *rm;
175 175
176 mutex_init(&osb->recovery_lock);176 mutex_init(&osb->recovery_lock);
177 osb->disable_recovery = 0;177 osb->recovery_state = OCFS2_REC_ENABLED;
178 osb->recovery_thread_task = NULL;178 osb->recovery_thread_task = NULL;
179 init_waitqueue_head(&osb->recovery_event);179 init_waitqueue_head(&osb->recovery_event);
180 180
@@ -190,31 +190,53 @@ int ocfs2_recovery_init(struct ocfs2_super *osb) · 9 unmodified lines
190 return 0;190 return 0;
191}191}
192 192
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 */
196static int ocfs2_recovery_thread_running(struct ocfs2_super *osb)193static int ocfs2_recovery_thread_running(struct ocfs2_super *osb)
197{194{
198 mb();
199 return osb->recovery_thread_task != NULL;195 return osb->recovery_thread_task != NULL;
200}196}
201 197
202void ocfs2_recovery_exit(struct ocfs2_super *osb)198static void ocfs2_recovery_disable(struct ocfs2_super *osb,
199 enum ocfs2_recovery_state state)
203{200{
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. */
208 mutex_lock(&osb->recovery_lock);201 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));
217out_lock:
210 mutex_unlock(&osb->recovery_lock);218 mutex_unlock(&osb->recovery_lock);
211 wait_event(osb->recovery_event, !ocfs2_recovery_thread_running(osb));
212 219
213 /* At this point, we know that no more recovery threads can be220 /*
214 * launched, so wait for any recovery completion work to221 * At this point we know that no more recovery work can be queued so
215 * complete. */222 * wait for any recovery completion work to complete.
223 */
216 if (osb->ocfs2_wq)224 if (osb->ocfs2_wq)
217 flush_workqueue(osb->ocfs2_wq);225 flush_workqueue(osb->ocfs2_wq);
226}
227
228void ocfs2_recovery_disable_quota(struct ocfs2_super *osb)
229{
230 ocfs2_recovery_disable(osb, OCFS2_REC_QUOTA_WANT_DISABLE);
231}
232
233void 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);
218 240
219 /*241 /*
220 * Now that recovery is shut down, and the osb is about to be242 * Now that recovery is shut down, and the osb is about to be
@@ -1472,6 +1494,18 @@ static int __ocfs2_recovery_thread(void *arg) · 1251 unmodified lines
1472 }1494 }
1473 }1495 }
1474restart:1496restart:
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
1475 status = ocfs2_super_lock(osb, 1);1509 status = ocfs2_super_lock(osb, 1);
1476 if (status < 0) {1510 if (status < 0) {
1477 mlog_errno(status);1511 mlog_errno(status);
@@ -1569,27 +1603,29 @@ bail: · 91 unmodified lines
1569 1603
1570 ocfs2_free_replay_slots(osb);1604 ocfs2_free_replay_slots(osb);
1571 osb->recovery_thread_task = NULL;1605 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;
1573 wake_up(&osb->recovery_event);1608 wake_up(&osb->recovery_event);
1574 1609
1575 mutex_unlock(&osb->recovery_lock);1610 mutex_unlock(&osb->recovery_lock);
1576 1611
1577 if (quota_enabled)1612 kfree(rm_quota);
1578 kfree(rm_quota);
1579 1613
1580 return status;1614 return status;
1581}1615}
1582 1616
1583void ocfs2_recovery_thread(struct ocfs2_super *osb, int node_num)1617void ocfs2_recovery_thread(struct ocfs2_super *osb, int node_num)
1584{1618{
1619 int was_set = -1;
1620
1585 mutex_lock(&osb->recovery_lock);1621 mutex_lock(&osb->recovery_lock);
1622 if (osb->recovery_state < OCFS2_REC_WANT_DISABLE)
1623 was_set = ocfs2_recovery_map_set(osb, node_num);
1586 1624
1587 trace_ocfs2_recovery_thread(node_num, osb->node_num,1625 trace_ocfs2_recovery_thread(node_num, osb->node_num,
1588 osb->disable_recovery, osb->recovery_thread_task,1626 osb->recovery_state, osb->recovery_thread_task, was_set);
1589 osb->disable_recovery ?
1590 -1 : ocfs2_recovery_map_set(osb, node_num));
1591 1627
1592 if (osb->disable_recovery)1628 if (osb->recovery_state >= OCFS2_REC_WANT_DISABLE)
1593 goto out;1629 goto out;
1594 1630
1595 if (osb->recovery_thread_task)1631 if (osb->recovery_thread_task)
fs/ocfs2/journal.h+1−0
@@ -148,6 +148,7 @@ void ocfs2_wait_for_recovery(struct ocfs2_super *osb); · 147 unmodified lines
148 148
149int ocfs2_recovery_init(struct ocfs2_super *osb);149int ocfs2_recovery_init(struct ocfs2_super *osb);
150void ocfs2_recovery_exit(struct ocfs2_super *osb);150void ocfs2_recovery_exit(struct ocfs2_super *osb);
151void ocfs2_recovery_disable_quota(struct ocfs2_super *osb);
151 152
152int ocfs2_compute_replay_slots(struct ocfs2_super *osb);153int ocfs2_compute_replay_slots(struct ocfs2_super *osb);
153void ocfs2_free_replay_slots(struct ocfs2_super *osb);154void ocfs2_free_replay_slots(struct ocfs2_super *osb);
fs/ocfs2/ocfs2.h+16−1
@@ -308,6 +308,21 @@ enum ocfs2_journal_trigger_type { · 307 unmodified lines
308void ocfs2_initialize_journal_triggers(struct super_block *sb,308void ocfs2_initialize_journal_triggers(struct super_block *sb,
309 struct ocfs2_triggers triggers[]);309 struct ocfs2_triggers triggers[]);
310 310
311enum 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
311struct ocfs2_journal;326struct ocfs2_journal;
312struct ocfs2_slot_info;327struct ocfs2_slot_info;
313struct ocfs2_recovery_map;328struct ocfs2_recovery_map;
@@ -370,7 +385,7 @@ struct ocfs2_super · 56 unmodified lines
370 struct ocfs2_recovery_map *recovery_map;385 struct ocfs2_recovery_map *recovery_map;
371 struct ocfs2_replay_map *replay_map;386 struct ocfs2_replay_map *replay_map;
372 struct task_struct *recovery_thread_task;387 struct task_struct *recovery_thread_task;
373 int disable_recovery;388 enum ocfs2_recovery_state recovery_state;
374 wait_queue_head_t checkpoint_event;389 wait_queue_head_t checkpoint_event;
375 struct ocfs2_journal *journal;390 struct ocfs2_journal *journal;
376 unsigned long osb_commit_interval;391 unsigned long osb_commit_interval;
fs/ocfs2/quota_local.c+2−7
@@ -453,8 +453,7 @@ out: · 452 unmodified lines
453 453
454/* Sync changes in local quota file into global quota file and454/* Sync changes in local quota file into global quota file and
455 * reinitialize local quota file.455 * reinitialize local quota file.
456 * The function expects local quota file to be already locked and456 * The function expects local quota file to be already locked. */
457 * s_umount locked in shared mode. */
458static int ocfs2_recover_local_quota_file(struct inode *lqinode,457static int ocfs2_recover_local_quota_file(struct inode *lqinode,
459 int type,458 int type,
460 struct ocfs2_quota_recovery *rec)459 struct ocfs2_quota_recovery *rec)
@@ -588,7 +587,6 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb, · 127 unmodified lines
588{587{
589 unsigned int ino[OCFS2_MAXQUOTAS] = { LOCAL_USER_QUOTA_SYSTEM_INODE,588 unsigned int ino[OCFS2_MAXQUOTAS] = { LOCAL_USER_QUOTA_SYSTEM_INODE,
590 LOCAL_GROUP_QUOTA_SYSTEM_INODE };589 LOCAL_GROUP_QUOTA_SYSTEM_INODE };
591 struct super_block *sb = osb->sb;
592 struct ocfs2_local_disk_dqinfo *ldinfo;590 struct ocfs2_local_disk_dqinfo *ldinfo;
593 struct buffer_head *bh;591 struct buffer_head *bh;
594 handle_t *handle;592 handle_t *handle;
@@ -600,7 +598,6 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb, · 5 unmodified lines
600 printk(KERN_NOTICE "ocfs2: Finishing quota recovery on device (%s) for "598 printk(KERN_NOTICE "ocfs2: Finishing quota recovery on device (%s) for "
601 "slot %u\n", osb->dev_str, slot_num);599 "slot %u\n", osb->dev_str, slot_num);
602 600
603 down_read(&sb->s_umount);
604 for (type = 0; type < OCFS2_MAXQUOTAS; type++) {601 for (type = 0; type < OCFS2_MAXQUOTAS; type++) {
605 if (list_empty(&(rec->r_list[type])))602 if (list_empty(&(rec->r_list[type])))
606 continue;603 continue;
@@ -677,7 +674,6 @@ out_put: · 70 unmodified lines
677 break;674 break;
678 }675 }
679out:676out:
680 up_read(&sb->s_umount);
681 kfree(rec);677 kfree(rec);
682 return status;678 return status;
683}679}
@@ -843,8 +839,7 @@ static int ocfs2_local_free_info(struct super_block *sb, int type) · 159 unmodified lines
843 ocfs2_release_local_quota_bitmaps(&oinfo->dqi_chunk);839 ocfs2_release_local_quota_bitmaps(&oinfo->dqi_chunk);
844 840
845 /*841 /*
846 * s_umount held in exclusive mode protects us against racing with842 * ocfs2_dismount_volume() has already aborted quota recovery...
847 * recovery thread...
848 */843 */
849 if (oinfo->dqi_rec) {844 if (oinfo->dqi_rec) {
850 ocfs2_free_quota_recovery(oinfo->dqi_rec);845 ocfs2_free_quota_recovery(oinfo->dqi_rec);
fs/ocfs2/suballoc.c+32−6
@@ -698,10 +698,12 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, · 697 unmodified lines
698 698
699 bg_bh = ocfs2_block_group_alloc_contig(osb, handle, alloc_inode,699 bg_bh = ocfs2_block_group_alloc_contig(osb, handle, alloc_inode,
700 ac, cl);700 ac, cl);
701 if (PTR_ERR(bg_bh) == -ENOSPC)701 if (PTR_ERR(bg_bh) == -ENOSPC) {
702 ac->ac_which = OCFS2_AC_USE_MAIN_DISCONTIG;
702 bg_bh = ocfs2_block_group_alloc_discontig(handle,703 bg_bh = ocfs2_block_group_alloc_discontig(handle,
703 alloc_inode,704 alloc_inode,
704 ac, cl);705 ac, cl);
706 }
705 if (IS_ERR(bg_bh)) {707 if (IS_ERR(bg_bh)) {
706 status = PTR_ERR(bg_bh);708 status = PTR_ERR(bg_bh);
707 bg_bh = NULL;709 bg_bh = NULL;
@@ -1794,6 +1796,7 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, · 1086 unmodified lines
1794{1796{
1795 int status;1797 int status;
1796 u16 chain;1798 u16 chain;
1799 u32 contig_bits;
1797 u64 next_group;1800 u64 next_group;
1798 struct inode *alloc_inode = ac->ac_inode;1801 struct inode *alloc_inode = ac->ac_inode;
1799 struct buffer_head *group_bh = NULL;1802 struct buffer_head *group_bh = NULL;
@@ -1819,10 +1822,21 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, · 19 unmodified lines
1819 status = -ENOSPC;1822 status = -ENOSPC;
1820 /* for now, the chain search is a bit simplistic. We just use1823 /* for now, the chain search is a bit simplistic. We just use
1821 * the 1st group with any empty bits. */1824 * the 1st group with any empty bits. */
1822 while ((status = ac->ac_group_search(alloc_inode, group_bh,1825 while (1) {
1823 bits_wanted, min_bits,1826 if (ac->ac_which == OCFS2_AC_USE_MAIN_DISCONTIG) {
1824 ac->ac_max_block,1827 contig_bits = le16_to_cpu(bg->bg_contig_free_bits);
1825 res)) == -ENOSPC) {1828 if (!contig_bits)
1829 contig_bits = ocfs2_find_max_contig_free_bits(bg->bg_bitmap,
1830 le16_to_cpu(bg->bg_bits), 0);
1831 if (bits_wanted > contig_bits && contig_bits >= min_bits)
1832 bits_wanted = contig_bits;
1833 }
1834
1835 status = ac->ac_group_search(alloc_inode, group_bh,
1836 bits_wanted, min_bits,
1837 ac->ac_max_block, res);
1838 if (status != -ENOSPC)
1839 break;
1826 if (!bg->bg_next_group)1840 if (!bg->bg_next_group)
1827 break;1841 break;
1828 1842
@@ -1982,6 +1996,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, · 153 unmodified lines
1982 victim = ocfs2_find_victim_chain(cl);1996 victim = ocfs2_find_victim_chain(cl);
1983 ac->ac_chain = victim;1997 ac->ac_chain = victim;
1984 1998
1999search:
1985 status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits,2000 status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits,
1986 res, &bits_left);2001 res, &bits_left);
1987 if (!status) {2002 if (!status) {
@@ -2022,6 +2037,16 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, · 34 unmodified lines
2022 }2037 }
2023 }2038 }
2024 2039
2040 /* Chains can't supply the bits_wanted contiguous space.
2041 * We should switch to using every single bit when allocating
2042 * from the global bitmap. */
2043 if (i == le16_to_cpu(cl->cl_next_free_rec) &&
2044 status == -ENOSPC && ac->ac_which == OCFS2_AC_USE_MAIN) {
2045 ac->ac_which = OCFS2_AC_USE_MAIN_DISCONTIG;
2046 ac->ac_chain = victim;
2047 goto search;
2048 }
2049
2025set_hint:2050set_hint:
2026 if (status != -ENOSPC) {2051 if (status != -ENOSPC) {
2027 /* If the next search of this group is not likely to2052 /* If the next search of this group is not likely to
@@ -2365,7 +2390,8 @@ int __ocfs2_claim_clusters(handle_t *handle, · 337 unmodified lines
2365 BUG_ON(ac->ac_bits_given >= ac->ac_bits_wanted);2390 BUG_ON(ac->ac_bits_given >= ac->ac_bits_wanted);
2366 2391
2367 BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL2392 BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL
2368 && ac->ac_which != OCFS2_AC_USE_MAIN);2393 && ac->ac_which != OCFS2_AC_USE_MAIN
2394 && ac->ac_which != OCFS2_AC_USE_MAIN_DISCONTIG);
2369 2395
2370 if (ac->ac_which == OCFS2_AC_USE_LOCAL) {2396 if (ac->ac_which == OCFS2_AC_USE_LOCAL) {
2371 WARN_ON(min_clusters > 1);2397 WARN_ON(min_clusters > 1);
fs/ocfs2/suballoc.h+1−0
@@ -29,6 +29,7 @@ struct ocfs2_alloc_context { · 28 unmodified lines
29#define OCFS2_AC_USE_MAIN 229#define OCFS2_AC_USE_MAIN 2
30#define OCFS2_AC_USE_INODE 330#define OCFS2_AC_USE_INODE 3
31#define OCFS2_AC_USE_META 431#define OCFS2_AC_USE_META 4
32#define OCFS2_AC_USE_MAIN_DISCONTIG 5
32 u32 ac_which;33 u32 ac_which;
33 34
34 /* these are used by the chain search */35 /* these are used by the chain search */
fs/ocfs2/super.c+3−0
@@ -1812,6 +1812,9 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) · 1811 unmodified lines
1812 /* Orphan scan should be stopped as early as possible */1812 /* Orphan scan should be stopped as early as possible */
1813 ocfs2_orphan_scan_stop(osb);1813 ocfs2_orphan_scan_stop(osb);
1814 1814
1815 /* Stop quota recovery so that we can disable quotas */
1816 ocfs2_recovery_disable_quota(osb);
1817
1815 ocfs2_disable_quotas(osb);1818 ocfs2_disable_quotas(osb);
1816 1819
1817 /* All dquots should be freed by now */1820 /* All dquots should be freed by now */
fs/userfaultfd.c+22−6
@@ -1585,8 +1585,11 @@ static int userfaultfd_copy(struct userfaultfd_ctx *ctx, · 1584 unmodified lines
1585 user_uffdio_copy = (struct uffdio_copy __user *) arg;1585 user_uffdio_copy = (struct uffdio_copy __user *) arg;
1586 1586
1587 ret = -EAGAIN;1587 ret = -EAGAIN;
1588 if (atomic_read(&ctx->mmap_changing))1588 if (unlikely(atomic_read(&ctx->mmap_changing))) {
1589 if (unlikely(put_user(ret, &user_uffdio_copy->copy)))
1590 return -EFAULT;
1589 goto out;1591 goto out;
1592 }
1590 1593
1591 ret = -EFAULT;1594 ret = -EFAULT;
1592 if (copy_from_user(&uffdio_copy, user_uffdio_copy,1595 if (copy_from_user(&uffdio_copy, user_uffdio_copy,
@@ -1641,8 +1644,11 @@ static int userfaultfd_zeropage(struct userfaultfd_ctx *ctx, · 48 unmodified lines
1641 user_uffdio_zeropage = (struct uffdio_zeropage __user *) arg;1644 user_uffdio_zeropage = (struct uffdio_zeropage __user *) arg;
1642 1645
1643 ret = -EAGAIN;1646 ret = -EAGAIN;
1644 if (atomic_read(&ctx->mmap_changing))1647 if (unlikely(atomic_read(&ctx->mmap_changing))) {
1648 if (unlikely(put_user(ret, &user_uffdio_zeropage->zeropage)))
1649 return -EFAULT;
1645 goto out;1650 goto out;
1651 }
1646 1652
1647 ret = -EFAULT;1653 ret = -EFAULT;
1648 if (copy_from_user(&uffdio_zeropage, user_uffdio_zeropage,1654 if (copy_from_user(&uffdio_zeropage, user_uffdio_zeropage,
@@ -1744,8 +1750,11 @@ static int userfaultfd_continue(struct userfaultfd_ctx *ctx, unsigned long arg) · 95 unmodified lines
1744 user_uffdio_continue = (struct uffdio_continue __user *)arg;1750 user_uffdio_continue = (struct uffdio_continue __user *)arg;
1745 1751
1746 ret = -EAGAIN;1752 ret = -EAGAIN;
1747 if (atomic_read(&ctx->mmap_changing))1753 if (unlikely(atomic_read(&ctx->mmap_changing))) {
1754 if (unlikely(put_user(ret, &user_uffdio_continue->mapped)))
1755 return -EFAULT;
1748 goto out;1756 goto out;
1757 }
1749 1758
1750 ret = -EFAULT;1759 ret = -EFAULT;
1751 if (copy_from_user(&uffdio_continue, user_uffdio_continue,1760 if (copy_from_user(&uffdio_continue, user_uffdio_continue,
@@ -1801,8 +1810,11 @@ static inline int userfaultfd_poison(struct userfaultfd_ctx *ctx, unsigned long · 49 unmodified lines
1801 user_uffdio_poison = (struct uffdio_poison __user *)arg;1810 user_uffdio_poison = (struct uffdio_poison __user *)arg;
1802 1811
1803 ret = -EAGAIN;1812 ret = -EAGAIN;
1804 if (atomic_read(&ctx->mmap_changing))1813 if (unlikely(atomic_read(&ctx->mmap_changing))) {
1814 if (unlikely(put_user(ret, &user_uffdio_poison->updated)))
1815 return -EFAULT;
1805 goto out;1816 goto out;
1817 }
1806 1818
1807 ret = -EFAULT;1819 ret = -EFAULT;
1808 if (copy_from_user(&uffdio_poison, user_uffdio_poison,1820 if (copy_from_user(&uffdio_poison, user_uffdio_poison,
@@ -1870,8 +1882,12 @@ static int userfaultfd_move(struct userfaultfd_ctx *ctx, · 61 unmodified lines
1870 1882
1871 user_uffdio_move = (struct uffdio_move __user *) arg;1883 user_uffdio_move = (struct uffdio_move __user *) arg;
1872 1884
1873 if (atomic_read(&ctx->mmap_changing))1885 ret = -EAGAIN;
1874 return -EAGAIN;1886 if (unlikely(atomic_read(&ctx->mmap_changing))) {
1887 if (unlikely(put_user(ret, &user_uffdio_move->move)))
1888 return -EFAULT;
1889 goto out;
1890 }
1875 1891
1876 if (copy_from_user(&uffdio_move, user_uffdio_move,1892 if (copy_from_user(&uffdio_move, user_uffdio_move,
1877 /* don't copy "move" last field */1893 /* don't copy "move" last field */
include/linux/vmalloc.h+1−0
@@ -61,6 +61,7 @@ struct vm_struct { · 60 unmodified lines
61 unsigned int nr_pages;61 unsigned int nr_pages;
62 phys_addr_t phys_addr;62 phys_addr_t phys_addr;
63 const void *caller;63 const void *caller;
64 unsigned long requested_size;
64};65};
65 66
66struct vmap_area {67struct vmap_area {
mm/huge_memory.c+8−3
@@ -3075,6 +3075,8 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, · 3074 unmodified lines
3075void split_huge_pmd_locked(struct vm_area_struct *vma, unsigned long address,3075void split_huge_pmd_locked(struct vm_area_struct *vma, unsigned long address,
3076 pmd_t *pmd, bool freeze, struct folio *folio)3076 pmd_t *pmd, bool freeze, struct folio *folio)
3077{3077{
3078 bool pmd_migration = is_pmd_migration_entry(*pmd);
3079
3078 VM_WARN_ON_ONCE(folio && !folio_test_pmd_mappable(folio));3080 VM_WARN_ON_ONCE(folio && !folio_test_pmd_mappable(folio));
3079 VM_WARN_ON_ONCE(!IS_ALIGNED(address, HPAGE_PMD_SIZE));3081 VM_WARN_ON_ONCE(!IS_ALIGNED(address, HPAGE_PMD_SIZE));
3080 VM_WARN_ON_ONCE(folio && !folio_test_locked(folio));3082 VM_WARN_ON_ONCE(folio && !folio_test_locked(folio));
@@ -3085,9 +3087,12 @@ void split_huge_pmd_locked(struct vm_area_struct *vma, unsigned long address, · 4 unmodified lines
3085 * require a folio to check the PMD against. Otherwise, there3087 * require a folio to check the PMD against. Otherwise, there
3086 * is a risk of replacing the wrong folio.3088 * is a risk of replacing the wrong folio.
3087 */3089 */
3088 if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd) ||3090 if (pmd_trans_huge(*pmd) || pmd_devmap(*pmd) || pmd_migration) {
3089 is_pmd_migration_entry(*pmd)) {3091 /*
3090 if (folio && folio != pmd_folio(*pmd))3092 * Do not apply pmd_folio() to a migration entry; and folio lock
3093 * guarantees that it must be of the wrong folio anyway.
3094 */
3095 if (folio && (pmd_migration || folio != pmd_folio(*pmd)))
3091 return;3096 return;
3092 __split_huge_pmd_locked(vma, pmd, address, freeze);3097 __split_huge_pmd_locked(vma, pmd, address, freeze);
3093 }3098 }
mm/hugetlb.c+6−0
@@ -4034,10 +4034,13 @@ static long demote_free_hugetlb_folios(struct hstate *src, struct hstate *dst, · 4033 unmodified lines
4034 4034
4035 list_for_each_entry_safe(folio, next, src_list, lru) {4035 list_for_each_entry_safe(folio, next, src_list, lru) {
4036 int i;4036 int i;
4037 bool cma;
4037 4038
4038 if (folio_test_hugetlb_vmemmap_optimized(folio))4039 if (folio_test_hugetlb_vmemmap_optimized(folio))
4039 continue;4040 continue;
4040 4041
4042 cma = folio_test_hugetlb_cma(folio);
4043
4041 list_del(&folio->lru);4044 list_del(&folio->lru);
4042 4045
4043 split_page_owner(&folio->page, huge_page_order(src), huge_page_order(dst));4046 split_page_owner(&folio->page, huge_page_order(src), huge_page_order(dst));
@@ -4053,6 +4056,9 @@ static long demote_free_hugetlb_folios(struct hstate *src, struct hstate *dst, · 9 unmodified lines
4053 4056
4054 new_folio->mapping = NULL;4057 new_folio->mapping = NULL;
4055 init_new_hugetlb_folio(dst, new_folio);4058 init_new_hugetlb_folio(dst, new_folio);
4059 /* Copy the CMA flag so that it is freed correctly */
4060 if (cma)
4061 folio_set_hugetlb_cma(new_folio);
4056 list_add(&new_folio->lru, &dst_list);4062 list_add(&new_folio->lru, &dst_list);
4057 }4063 }
4058 }4064 }
mm/internal.h+11−16
@@ -248,11 +248,9 @@ static inline int folio_pte_batch(struct folio *folio, unsigned long addr, · 247 unmodified lines
248 pte_t *start_ptep, pte_t pte, int max_nr, fpb_t flags,248 pte_t *start_ptep, pte_t pte, int max_nr, fpb_t flags,
249 bool *any_writable, bool *any_young, bool *any_dirty)249 bool *any_writable, bool *any_young, bool *any_dirty)
250{250{
251 unsigned long folio_end_pfn = folio_pfn(folio) + folio_nr_pages(folio);
252 const pte_t *end_ptep = start_ptep + max_nr;
253 pte_t expected_pte, *ptep;251 pte_t expected_pte, *ptep;
254 bool writable, young, dirty;252 bool writable, young, dirty;
255 int nr;253 int nr, cur_nr;
256 254
257 if (any_writable)255 if (any_writable)
258 *any_writable = false;256 *any_writable = false;
@@ -265,11 +263,15 @@ static inline int folio_pte_batch(struct folio *folio, unsigned long addr, · 6 unmodified lines
265 VM_WARN_ON_FOLIO(!folio_test_large(folio) || max_nr < 1, folio);263 VM_WARN_ON_FOLIO(!folio_test_large(folio) || max_nr < 1, folio);
266 VM_WARN_ON_FOLIO(page_folio(pfn_to_page(pte_pfn(pte))) != folio, folio);264 VM_WARN_ON_FOLIO(page_folio(pfn_to_page(pte_pfn(pte))) != folio, folio);
267 265
266 /* Limit max_nr to the actual remaining PFNs in the folio we could batch. */
267 max_nr = min_t(unsigned long, max_nr,
268 folio_pfn(folio) + folio_nr_pages(folio) - pte_pfn(pte));
269
268 nr = pte_batch_hint(start_ptep, pte);270 nr = pte_batch_hint(start_ptep, pte);
269 expected_pte = __pte_batch_clear_ignored(pte_advance_pfn(pte, nr), flags);271 expected_pte = __pte_batch_clear_ignored(pte_advance_pfn(pte, nr), flags);
270 ptep = start_ptep + nr;272 ptep = start_ptep + nr;
271 273
272 while (ptep < end_ptep) {274 while (nr < max_nr) {
273 pte = ptep_get(ptep);275 pte = ptep_get(ptep);
274 if (any_writable)276 if (any_writable)
275 writable = !!pte_write(pte);277 writable = !!pte_write(pte);
@@ -282,14 +284,6 @@ static inline int folio_pte_batch(struct folio *folio, unsigned long addr, · 6 unmodified lines
282 if (!pte_same(pte, expected_pte))284 if (!pte_same(pte, expected_pte))
283 break;285 break;
284 286
285 /*
286 * Stop immediately once we reached the end of the folio. In
287 * corner cases the next PFN might fall into a different
288 * folio.
289 */
290 if (pte_pfn(pte) >= folio_end_pfn)
291 break;
292
293 if (any_writable)287 if (any_writable)
294 *any_writable |= writable;288 *any_writable |= writable;
295 if (any_young)289 if (any_young)
@@ -297,12 +291,13 @@ static inline int folio_pte_batch(struct folio *folio, unsigned long addr, · 1 unmodified line
297 if (any_dirty)291 if (any_dirty)
298 *any_dirty |= dirty;292 *any_dirty |= dirty;
299 293
300 nr = pte_batch_hint(ptep, pte);294 cur_nr = pte_batch_hint(ptep, pte);
301 expected_pte = pte_advance_pfn(expected_pte, nr);295 expected_pte = pte_advance_pfn(expected_pte, cur_nr);
302 ptep += nr;296 ptep += cur_nr;
297 nr += cur_nr;
303 }298 }
304 299
305 return min(ptep - start_ptep, max_nr);300 return min(nr, max_nr);
306}301}
307 302
308/**303/**
mm/swapfile.c+16−7
@@ -1272,13 +1272,22 @@ int folio_alloc_swap(struct folio *folio, gfp_t gfp) · 1271 unmodified lines
1272 VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);1272 VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
1273 VM_BUG_ON_FOLIO(!folio_test_uptodate(folio), folio);1273 VM_BUG_ON_FOLIO(!folio_test_uptodate(folio), folio);
1274 1274
1275 /*1275 if (order) {
1276 * Should not even be attempting large allocations when huge1276 /*
1277 * page swap is disabled. Warn and fail the allocation.1277 * Reject large allocation when THP_SWAP is disabled,
1278 */1278 * the caller should split the folio and try again.
1279 if (order && (!IS_ENABLED(CONFIG_THP_SWAP) || size > SWAPFILE_CLUSTER)) {1279 */
1280 VM_WARN_ON_ONCE(1);1280 if (!IS_ENABLED(CONFIG_THP_SWAP))
1281 return -EINVAL;1281 return -EAGAIN;
1282
1283 /*
1284 * Allocation size should never exceed cluster size
1285 * (HPAGE_PMD_SIZE).
1286 */
1287 if (size > SWAPFILE_CLUSTER) {
1288 VM_WARN_ON_ONCE(1);
1289 return -EINVAL;
1290 }
1282 }1291 }
1283 1292
1284 local_lock(&percpu_swap_cluster.lock);1293 local_lock(&percpu_swap_cluster.lock);
mm/vmalloc.c+24−7
@@ -1940,7 +1940,7 @@ static inline void setup_vmalloc_vm(struct vm_struct *vm, · 1939 unmodified lines
1940{1940{
1941 vm->flags = flags;1941 vm->flags = flags;
1942 vm->addr = (void *)va->va_start;1942 vm->addr = (void *)va->va_start;
1943 vm->size = va_size(va);1943 vm->size = vm->requested_size = va_size(va);
1944 vm->caller = caller;1944 vm->caller = caller;
1945 va->vm = vm;1945 va->vm = vm;
1946}1946}
@@ -3133,6 +3133,7 @@ struct vm_struct *__get_vm_area_node(unsigned long size, · 1186 unmodified lines
3133 3133
3134 area->flags = flags;3134 area->flags = flags;
3135 area->caller = caller;3135 area->caller = caller;
3136 area->requested_size = requested_size;
3136 3137
3137 va = alloc_vmap_area(size, align, start, end, node, gfp_mask, 0, area);3138 va = alloc_vmap_area(size, align, start, end, node, gfp_mask, 0, area);
3138 if (IS_ERR(va)) {3139 if (IS_ERR(va)) {
@@ -4063,6 +4064,8 @@ EXPORT_SYMBOL(vzalloc_node_noprof); · 924 unmodified lines
4063 */4064 */
4064void *vrealloc_noprof(const void *p, size_t size, gfp_t flags)4065void *vrealloc_noprof(const void *p, size_t size, gfp_t flags)
4065{4066{
4067 struct vm_struct *vm = NULL;
4068 size_t alloced_size = 0;
4066 size_t old_size = 0;4069 size_t old_size = 0;
4067 void *n;4070 void *n;
4068 4071
@@ -4072,15 +4075,17 @@ void *vrealloc_noprof(const void *p, size_t size, gfp_t flags) · 3 unmodified lines
4072 }4075 }
4073 4076
4074 if (p) {4077 if (p) {
4075 struct vm_struct *vm;
4076
4077 vm = find_vm_area(p);4078 vm = find_vm_area(p);
4078 if (unlikely(!vm)) {4079 if (unlikely(!vm)) {
4079 WARN(1, "Trying to vrealloc() nonexistent vm area (%p)\n", p);4080 WARN(1, "Trying to vrealloc() nonexistent vm area (%p)\n", p);
4080 return NULL;4081 return NULL;
4081 }4082 }
4082 4083
4083 old_size = get_vm_area_size(vm);4084 alloced_size = get_vm_area_size(vm);
4085 old_size = vm->requested_size;
4086 if (WARN(alloced_size < old_size,
4087 "vrealloc() has mismatched area vs requested sizes (%p)\n", p))
4088 return NULL;
4084 }4089 }
4085 4090
4086 /*4091 /*
@@ -4088,14 +4093,26 @@ void *vrealloc_noprof(const void *p, size_t size, gfp_t flags) · 1 unmodified line
4088 * would be a good heuristic for when to shrink the vm_area?4093 * would be a good heuristic for when to shrink the vm_area?
4089 */4094 */
4090 if (size <= old_size) {4095 if (size <= old_size) {
4091 /* Zero out spare memory. */4096 /* Zero out "freed" memory. */
4092 if (want_init_on_alloc(flags))4097 if (want_init_on_free())
4093 memset((void *)p + size, 0, old_size - size);4098 memset((void *)p + size, 0, old_size - size);
4099 vm->requested_size = size;
4094 kasan_poison_vmalloc(p + size, old_size - size);4100 kasan_poison_vmalloc(p + size, old_size - size);
4095 kasan_unpoison_vmalloc(p, size, KASAN_VMALLOC_PROT_NORMAL);
4096 return (void *)p;4101 return (void *)p;
4097 }4102 }
4098 4103
4104 /*
4105 * We already have the bytes available in the allocation; use them.
4106 */
4107 if (size <= alloced_size) {
4108 kasan_unpoison_vmalloc(p + old_size, size - old_size,
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);
4113 vm->requested_size = size;
4114 }
4115
4099 /* TODO: Grow the vm_area, i.e. allocate and map additional pages. */4116 /* TODO: Grow the vm_area, i.e. allocate and map additional pages. */
4100 n = __vmalloc_noprof(size, flags);4117 n = __vmalloc_noprof(size, flags);
4101 if (!n)4118 if (!n)
tools/testing/selftests/mm/compaction_test.c+14−5
@@ -90,6 +90,8 @@ int check_compaction(unsigned long mem_free, unsigned long hugepage_size, · 89 unmodified lines
90 int compaction_index = 0;90 int compaction_index = 0;
91 char nr_hugepages[20] = {0};91 char nr_hugepages[20] = {0};
92 char init_nr_hugepages[24] = {0};92 char init_nr_hugepages[24] = {0};
93 char target_nr_hugepages[24] = {0};
94 int slen;
93 95
94 snprintf(init_nr_hugepages, sizeof(init_nr_hugepages),96 snprintf(init_nr_hugepages, sizeof(init_nr_hugepages),
95 "%lu", initial_nr_hugepages);97 "%lu", initial_nr_hugepages);
@@ -106,11 +108,18 @@ int check_compaction(unsigned long mem_free, unsigned long hugepage_size, · 10 unmodified lines
106 goto out;108 goto out;
107 }109 }
108 110
109 /* Request a large number of huge pages. The Kernel will allocate111 /*
110 as much as it can */112 * Request huge pages for about half of the free memory. The Kernel
111 if (write(fd, "100000", (6*sizeof(char))) != (6*sizeof(char))) {113 * will allocate as much as it can, and we expect it will get at least 1/3
112 ksft_print_msg("Failed to write 100000 to /proc/sys/vm/nr_hugepages: %s\n",114 */
113 strerror(errno));115 nr_hugepages_ul = mem_free / hugepage_size / 2;
116 snprintf(target_nr_hugepages, sizeof(target_nr_hugepages),
117 "%lu", nr_hugepages_ul);
118
119 slen = strlen(target_nr_hugepages);
120 if (write(fd, target_nr_hugepages, slen) != slen) {
121 ksft_print_msg("Failed to write %lu to /proc/sys/vm/nr_hugepages: %s\n",
122 nr_hugepages_ul, strerror(errno));
114 goto close_fd;123 goto close_fd;
115 }124 }
116 125
tools/testing/selftests/mm/guard-regions.c+10−6
@@ -271,12 +271,16 @@ FIXTURE_SETUP(guard_regions) · 270 unmodified lines
271 self->page_size = (unsigned long)sysconf(_SC_PAGESIZE);271 self->page_size = (unsigned long)sysconf(_SC_PAGESIZE);
272 setup_sighandler();272 setup_sighandler();
273 273
274 if (variant->backing == ANON_BACKED)274 switch (variant->backing) {
275 case ANON_BACKED:
275 return;276 return;
276 277 case LOCAL_FILE_BACKED:
277 self->fd = open_file(278 self->fd = open_file("", self->path);
278 variant->backing == SHMEM_BACKED ? "/tmp/" : "",279 break;
279 self->path);280 case SHMEM_BACKED:
281 self->fd = memfd_create(self->path, 0);
282 break;
283 }
280 284
281 /* We truncate file to at least 100 pages, tests can modify as needed. */285 /* We truncate file to at least 100 pages, tests can modify as needed. */
282 ASSERT_EQ(ftruncate(self->fd, 100 * self->page_size), 0);286 ASSERT_EQ(ftruncate(self->fd, 100 * self->page_size), 0);
@@ -1696,7 +1700,7 @@ TEST_F(guard_regions, readonly_file) · 1413 unmodified lines
1696 char *ptr;1700 char *ptr;
1697 int i;1701 int i;
1698 1702
1699 if (variant->backing == ANON_BACKED)1703 if (variant->backing != LOCAL_FILE_BACKED)
1700 SKIP(return, "Read-only test specific to file-backed");1704 SKIP(return, "Read-only test specific to file-backed");
1701 1705
1702 /* Map shared so we can populate with pattern, populate it, unmap. */1706 /* Map shared so we can populate with pattern, populate it, unmap. */
tools/testing/selftests/mm/pkey-powerpc.h+13−1
@@ -3,6 +3,8 @@ · 2 unmodified lines
3#ifndef _PKEYS_POWERPC_H3#ifndef _PKEYS_POWERPC_H
4#define _PKEYS_POWERPC_H4#define _PKEYS_POWERPC_H
5 5
6#include <sys/stat.h>
7
6#ifndef SYS_pkey_alloc8#ifndef SYS_pkey_alloc
7# define SYS_pkey_alloc 3849# define SYS_pkey_alloc 384
8# define SYS_pkey_free 38510# define SYS_pkey_free 385
@@ -102,8 +104,18 @@ static inline void expect_fault_on_read_execonly_key(void *p1, int pkey) · 93 unmodified lines
102 return;104 return;
103}105}
104 106
107#define REPEAT_8(s) s s s s s s s s
108#define REPEAT_64(s) REPEAT_8(s) REPEAT_8(s) REPEAT_8(s) REPEAT_8(s) \
109 REPEAT_8(s) REPEAT_8(s) REPEAT_8(s) REPEAT_8(s)
110#define REPEAT_512(s) REPEAT_64(s) REPEAT_64(s) REPEAT_64(s) REPEAT_64(s) \
111 REPEAT_64(s) REPEAT_64(s) REPEAT_64(s) REPEAT_64(s)
112#define REPEAT_4096(s) REPEAT_512(s) REPEAT_512(s) REPEAT_512(s) REPEAT_512(s) \
113 REPEAT_512(s) REPEAT_512(s) REPEAT_512(s) REPEAT_512(s)
114#define REPEAT_16384(s) REPEAT_4096(s) REPEAT_4096(s) \
115 REPEAT_4096(s) REPEAT_4096(s)
116
105/* 4-byte instructions * 16384 = 64K page */117/* 4-byte instructions * 16384 = 64K page */
106#define __page_o_noops() asm(".rept 16384 ; nop; .endr")118#define __page_o_noops() asm(REPEAT_16384("nop\n"))
107 119
108static inline void *malloc_pkey_with_mprotect_subpage(long size, int prot, u16 pkey)120static inline void *malloc_pkey_with_mprotect_subpage(long size, int prot, u16 pkey)
109{121{
tools/testing/selftests/mm/pkey_util.c+1−0
@@ -1,4 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0-only1// SPDX-License-Identifier: GPL-2.0-only
2#define __SANE_USERSPACE_TYPES__
2#include <sys/syscall.h>3#include <sys/syscall.h>
3#include <unistd.h>4#include <unistd.h>
4 5