History

Merge tag 'mm-stable-2026-08-26-15-22' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull more MM updates from Andrew Morton: - "mm/rmap: index MAP_PRIVATE file-backed folios by anonymous pgoff" (Lorenzo Stoakes) Index MAP_PRIVATE file-backed folios by their anonymous page offset to resolve confusion around reverse mapping for zeroed and CoW'd file-backed memory. Use this new VMA anonymous page offset tracking to eliminate index conflicts and lay the foundation for scalable CoW performance improvements. - "promote mapped executable folios after first usage for MGLRU" (Baolin Wang) Make MGLRU's protection of mapped executable file folios more reliable. Follow the classical LRU's logic, promoting mapped executable file folios after their first usage to give executable code a better chance to stay in memory and improve workload performance. - "mm: vmscan: fix node reclaim ignoring swappiness parameter" (Ridong Chen) Fix per-node proactive reclaim interface's ignoring the swappiness parameter when CONFIG_MEMCG is disabled by consolidating sc_swappiness() into a single function that checks proactive_swappiness regardless of kernel configuration. - "mm/vmscan: reduce lru_lock contention via vmstat-derived scan-balance cost" (Usama Arif) Reduce lru_lock contention in the reclaim path by deriving scan-balance costs from vmstat counters rather than lock-acquired producer updates. Read and decay these cost signals on the reclaim side under a dedicated per-lruvec lock, reducing total LRU lock wait time by over 60% without impacting scan throughput. - "zram: fix zram issues reported by sashiko" (Sergey Senozhatsky) Fix two low-risk zram bugs which Sashiko spotted in drive-by review. - "Honor XA_FLAGS_ACCOUNT in xas_split_alloc() and charge to folio's memcg" (Zi Yan) Fix xas_split_alloc() by enabling target folio memcg charging during splits and adding the missing __GFP_ACCOUNT flag for proper XArray node memory accounting. - "selftests/mm: use pattern matching in .gitignore" (Pratyush Mallick) Replace hardcoded binary names in selftests/mm/.gitignore with a generic pattern-matching rule to automatically ignore generated test files and avoid manual updates when adding new tests. - "mm/page_ext: remove pgdat_page_ext_init()" (Sang-Heon Jeon) Make the incompatibility between FLATMEM and NUMA explicit in mm/Kconfig and remove the unused pgdat_page_ext_init() function. - "zram: fix zstd error paths and add parameter validation" (Haoqin Huang) Clean up zram compression backends by removing redundant error cleanup, adding parameter and dictionary validation, auto-prefixing algorithm error logs, and resetting parameters prior to reinitialization. - "zram: fix stale scan bounds after reinitialization" (Longlong Xia) Prevent out-of-bounds slot accesses during concurrent zram resets by moving table scan bound calculations under dev_lock in writeback_store() and read_block_state(). - "add anon mTHP collapse test cases" (Baolin Wang) Extend selftests helper functions to support arbitrary page orders and add new test cases and options for mTHP collapse in khugepaged. - "selftests/mm: Handle unsupported and transient test conditions" (Muhammad Usama Anjum) Update MM selftests to report a SKIP status instead of a failure when required kernel or filesystem features are unsupported, while adding retry logic for transient page migration errors. - "mm/zswap: Fixes and improves the zswap shrink" (Hao Jia) Fix the missing zswap global shrinker when CONFIG_MEMCG is disabled and extend shrink_memcg() to support batch writeback for improved writeback efficiency. - "alloc_tag: introduce IOCTL-based filtering for MAP" (Suren Baghdasaryan) Introduce an IOCTL-based binary interface for memory allocation profiling that enables kernel-side filtering before per-CPU counter aggregation. This eliminates the text-parsing overhead of /proc/allocinfo and provides up to a 20x speedup by transferring only filtered allocation data to userspace. - "better block swap batching and a different take on swap_ops v5" (Christoph Hellwig) Refactor block swap I/O to use swap_iocb for batching instead of single-bio requests and rebase the swap_ops interface, achieving faster swap throughput during kernel builds. - "mm: kmemleak: reduce transient false positives by confirming leaks" (Catalin Marinas) Reduce false-positive kmemleak reports by combining two kmemleak enhancements that add a second confirmation scan and a configurable minimum unreferenced scan count module parameter. - "mm: kmemleak: default min_unref_scans to 2 for verbose kernels" (Breno Leitao) Auto-scanning kernels can generate false-positive memory leak reports on single scans, so this patch defaults min_unref_scans to 2 when CONFIG_DEBUG_KMEMLEAK_VERBOSE is enabled to require a second confirming scan. - "swap_ops updates" (Christoph Hellwig) Batching I/O for synchronous swap devices causes performance regressions and filesystem-based swap suffers from double-indirection overhead. This series resolves both issues by reintroducing per-folio writes for synchronous swap and allowing filesystems to directly export their own swap_ops. - "mm/khugepaged: several cleanups" (Nico Pache) khugepaged accumulated redundant state-checking patterns and outdated comments following mTHP integration. Introduce dedicated helpers for PTE validation and event counting while refreshing the internal documentation. - "maple_tree: lock checking and clean ups" (Liam Howlett) Syzbot reports incorrectly blame memory management exit paths for locking bugs, maple tree erase operations risk allocation failures without gfp flags and internal documentation lacks clarity. Improve lock error detection, update docs, fix race and allocation edge cases and optimize erase allocations using a fallback to GFP_KERNEL | GFP_NOFAIL. * tag 'mm-stable-2026-08-26-15-22' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (172 commits) selftests/proc: make proc-maps-race work with READ_IMPLIES_EXEC memcg: move LRU size accounting on reparenting instead of copying it mm/vmscan: fix comment logic in balance_pgdat maple_tree: add helper mas_make_walkable() maple_tree: avoid extra gap calculation maple_tree: fix argument name in header maple_tree: change two GFP flags in tests maple_tree: document erase and allocations better maple_tree: avoid mas_erase() and mtree_erase() failures maple_tree: document that erase may use GFP_KERNEL for allocations maple_tree: catch race in mas_alloc_cyclic() maple_tree: add bulk parent set helper maple_tree: micro optimisation of mas_wr_store_type() maple_tree: optimise mas_wr_node_store() when not in rcu mode maple_tree: use prefetched value in mas_wr_store_type() maple_tree: clarify comments on mas_nomem() maple_tree: drop MAPLE_ALLOC_SLOTS maple_tree: drop dead code from mas_extend_spanning_null() maple_tree: documentation fix maple_tree: add write lock checking with lockdep sequence numbers ...

Linus Torvalds committed 2 months ago

Commit 18fbf512 parents 5e6ff28 0685630168 files · +4561 −1770Browse files

Unified · Split

168 files
  1. Documentation/admin-guide/blockdev/zram.rst +33 −1
  2. Documentation/admin-guide/kernel-parameters.txt +14 −2
  3. Documentation/admin-guide/mm/transhuge.rst +4 −2
  4. Documentation/core-api/maple_tree.rst +20 −4
  5. Documentation/dev-tools/kmemleak.rst +10 −0
  6. Documentation/filesystems/fscrypt.rst +4 −0
  7. Documentation/filesystems/locking.rst +2 −6
  8. Documentation/filesystems/vfs.rst +2 −6
  9. Documentation/mm/allocation-profiling.rst +16 −0
  10. Documentation/mm/ksm.rst +2 −2
  11. Documentation/mm/page_migration.rst +3 −3
  12. Documentation/translations/zh_CN/mm/ksm.rst +2 −2
  13. Documentation/userspace-api/ioctl/ioctl-number.rst +2 −0
  14. MAINTAINERS +6 −0
  15. arch/s390/mm/gmap_helpers.c +1 −1
  16. drivers/base/Kconfig +0 −7
  17. drivers/base/Makefile +0 −1
  18. drivers/block/zram/backend_842.c +10 −0
  19. drivers/block/zram/backend_deflate.c +23 −2
  20. drivers/block/zram/backend_lz4.c +9 −1
  21. drivers/block/zram/backend_lz4hc.c +15 −1
  22. drivers/block/zram/backend_lzo.c +10 −0
  23. drivers/block/zram/backend_lzorle.c +10 −0
  24. drivers/block/zram/backend_zstd.c +8 −3
  25. drivers/block/zram/zram_drv.c +109 −79
  26. drivers/block/zram/zram_drv.h +14 −0
  27. drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +2 −2
  28. drivers/gpu/drm/drm_gem_shmem_helper.c +1 −1
  29. drivers/gpu/drm/i915/gem/i915_gem_shmem.c +1 −1
  30. drivers/gpu/drm/panthor/panthor_gem.c +1 −1
  31. drivers/gpu/drm/ttm/ttm_backup.c +1 −1
  32. drivers/gpu/drm/ttm/ttm_bo_vm.c +1 −1
  33. drivers/gpu/drm/xe/xe_device.c +1 −1
  34. fs/nfs/direct.c +0 −20
  35. fs/nfs/file.c +38 −6
  36. fs/proc/task_mmu.c +1 −1
  37. fs/ramfs/file-nommu.c +3 −0
  38. fs/smb/client/file.c +39 −26
  39. include/linux/codetag.h +2 −0
  40. include/linux/execmem.h +1 −1
  41. include/linux/fs.h +0 −1
  42. include/linux/lockdep.h +3 −0
  43. include/linux/lockdep_types.h +2 −1
  44. include/linux/maple_tree.h +9 −7
  45. include/linux/memcontrol.h +17 −4
  46. include/linux/mm.h +125 −7
  47. include/linux/mm_types.h +26 −14
  48. include/linux/mmzone.h +13 −3
  49. include/linux/nfs_fs.h +0 −1
  50. include/linux/page_ext.h +0 −5
  51. include/linux/pagemap.h +37 −3
  52. include/linux/percpu-defs.h +1 −6
  53. include/linux/rmap.h +6 −5
  54. include/linux/sched.h +1 −0
  55. include/linux/shmem_fs.h +1 −4
  56. include/linux/swap.h +9 −21
  57. include/linux/swap_ops.h +44 −0
  58. include/linux/swapops.h +4 −3
  59. include/linux/vm_event_item.h +4 −0
  60. include/linux/vmalloc.h +1 −1
  61. include/linux/vmstat.h +16 −1
  62. include/rv/da_monitor.h +1 −1
  63. include/uapi/linux/alloc_tag.h +99 −0
  64. kernel/events/uprobes.c +1 −1
  65. kernel/locking/lockdep.c +51 −7
  66. lib/Kconfig.debug +0 −15
  67. lib/codetag.c +18 −0
  68. lib/maple_tree.c +280 −121
  69. lib/test_hmm.c +2 −3
  70. lib/xarray.c +3 −0
  71. mm/Kconfig +11 −11
  72. mm/Kconfig.debug +0 −1
  73. mm/Makefile +1 −0
  74. mm/alloc_tag.c +349 −2
  75. mm/arch_numa.c +12 −0
  76. mm/cma.c +1 −1
  77. mm/cma.h +1 −0
  78. mm/debug_page_alloc.c +4 −4
  79. mm/folio-compat.c +1 −0
  80. mm/folio.c +55 −69
  81. mm/gup.c +9 −14
  82. mm/gup_test.c +62 −32
  83. mm/hmm.c +4 −1
  84. mm/huge_memory.c +28 −18
  85. mm/hugetlb.c +7 −3
  86. mm/hugetlb_cma.c +134 −8
  87. mm/hugetlb_cma.h +2 −0
  88. mm/internal.h +54 −23
  89. mm/interval_tree.c +2 −2
  90. mm/kasan/quarantine.c +11 −1
  91. mm/khugepaged.c +65 −65
  92. mm/kmemleak.c +92 −13
  93. mm/ksm.c +7 −9
  94. mm/madvise.c +9 −8
  95. mm/memcontrol-v1.c +2 −2
  96. mm/memcontrol-v1.h +1 −0
  97. mm/memcontrol.c +66 −3
  98. mm/memory-failure.c +2 −2
  99. mm/memory.c +101 −39
  100. mm/mempolicy.c +7 −16
  101. mm/migrate.c +10 −11
  102. mm/migrate_device.c +14 −1
  103. mm/mm_init.c +0 −1
  104. mm/mmzone.c +1 −0
  105. mm/mremap.c +5 −3
  106. mm/nommu.c +4 −0
  107. mm/page-writeback.c +5 −0
  108. mm/page_alloc.c +20 −8
  109. mm/page_ext.c +0 −9
  110. mm/page_io.c +281 −300
  111. mm/page_reporting.c +18 −10
  112. mm/page_vma_mapped.c +5 −1
  113. mm/pgalloc-track.h +3 −0
  114. mm/rmap.c +25 −18
  115. mm/shmem.c +24 −5
  116. mm/show_mem.c +6 −6
  117. mm/shuffle.h +2 −0
  118. mm/sparse.c +4 −14
  119. mm/sparse.h +6 −0
  120. mm/swap.h +31 −34
  121. mm/swap_state.c +32 −22
  122. mm/swapfile.c +16 −8
  123. mm/userfaultfd.c +2 −2
  124. mm/vma.c +79 −34
  125. mm/vma.h +59 −30
  126. mm/vma_exec.c +1 −1
  127. mm/vma_init.c +1 −0
  128. mm/vmalloc.c +34 −37
  129. mm/vmalloc.h +2 −0
  130. mm/vmscan.c +151 −79
  131. mm/vmstat.c +18 −1
  132. mm/workingset.c +0 −5
  133. mm/zsmalloc.c +7 −4
  134. mm/zswap.c +29 −17
  135. tools/testing/radix-tree/maple.c +2 −2
  136. tools/testing/selftests/Makefile +1 −0
  137. tools/testing/selftests/alloc_tag/Makefile +8 −0
  138. tools/testing/selftests/alloc_tag/allocinfo_ioctl_test.c +548 −0
  139. tools/testing/selftests/cgroup/lib/include/cgroup_util.h +1 −0
  140. tools/testing/selftests/cgroup/test_zswap.c +11 −2
  141. tools/testing/selftests/mm/.gitignore +9 −67
  142. tools/testing/selftests/mm/Makefile +4 −3
  143. tools/testing/selftests/mm/check_config.sh +1 −1
  144. tools/testing/selftests/mm/compaction_test.c +21 −17
  145. tools/testing/selftests/mm/cow.c +8 −3
  146. tools/testing/selftests/mm/folio_split_race_test.c +1 −1
  147. tools/testing/selftests/mm/guard-regions.c +7 −3
  148. tools/testing/selftests/mm/gup_longterm.c +1 −1
  149. tools/testing/selftests/mm/khugepaged.c +155 −49
  150. tools/testing/selftests/mm/ksft_kmemleak_confirm.sh +130 −0
  151. tools/testing/selftests/mm/memory-failure.c +12 −2
  152. tools/testing/selftests/mm/merge.c +57 −0
  153. tools/testing/selftests/mm/migration.c +20 −17
  154. tools/testing/selftests/mm/mseal_test.c +1 −2
  155. tools/testing/selftests/mm/pagemap_ioctl.c +1 −7
  156. tools/testing/selftests/mm/prctl_thp_disable.c +1 −1
  157. tools/testing/selftests/mm/run_vmtests.sh +2 −0
  158. tools/testing/selftests/mm/soft-dirty.c +3 −2
  159. tools/testing/selftests/mm/split_huge_page_test.c +8 −131
  160. tools/testing/selftests/mm/uffd-common.c +3 −1
  161. tools/testing/selftests/mm/vm_util.c +197 −10
  162. tools/testing/selftests/mm/vm_util.h +5 −3
  163. tools/testing/selftests/proc/proc-maps-race.c +2 −1
  164. tools/testing/vma/include/dup.h +62 −2
  165. tools/testing/vma/shared.c +2 −1
  166. tools/testing/vma/tests/merge.c +39 −10
  167. tools/testing/vma/tests/vma.c +47 −3
  168. tools/testing/vma/vma_internal.h +1 −0
Documentation/admin-guide/blockdev/zram.rst+33−1
@@ -109,14 +109,41 @@ path to the `dict` along with other parameters:: · 108 unmodified lines
109 #pass path to pre-trained zstd dictionary109 #pass path to pre-trained zstd dictionary
110 echo "algo=zstd dict=/etc/dictionary" > /sys/block/zram0/algorithm_params110 echo "algo=zstd dict=/etc/dictionary" > /sys/block/zram0/algorithm_params
111 111
112 #pass path to pre-trained zstd dictionary and compression level
113 echo "algo=zstd level=8 dict=/etc/dictionary" > \
114 /sys/block/zram0/algorithm_params
115
112 #same, but using algorithm priority116 #same, but using algorithm priority
117 echo "algo=zstd priority=1" > /sys/block/zram0/recomp_algorithm
113 echo "priority=1 dict=/etc/dictionary" > \118 echo "priority=1 dict=/etc/dictionary" > \
114 /sys/block/zram0/algorithm_params119 /sys/block/zram0/algorithm_params
115 120
116 #pass path to pre-trained zstd dictionary and compression level121Each write to `algorithm_params` replaces the entire set of parameters of
122the corresponding algorithm, parameters that are not listed in the write
123are reset to their default values. Configure all of the parameters of an
124algorithm in one write::
125
126 #WRONG: the second write resets level back to its default value
127 echo "algo=zstd level=8" > /sys/block/zram0/algorithm_params
128 echo "algo=zstd dict=/etc/dictionary" > /sys/block/zram0/algorithm_params
129
130 #RIGHT
117 echo "algo=zstd level=8 dict=/etc/dictionary" > \131 echo "algo=zstd level=8 dict=/etc/dictionary" > \
118 /sys/block/zram0/algorithm_params132 /sys/block/zram0/algorithm_params
119 133
134Select the compression algorithm before configuring its parameters. The
135parameters of one algorithm are not necessarily valid for another one, so
136changing the algorithm of a particular priority resets that priority's
137parameters::
138
139 #WRONG: comp_algorithm write resets the previously configured level
140 echo "level=8" > /sys/block/zram0/algorithm_params
141 echo zstd > /sys/block/zram0/comp_algorithm
142
143 #RIGHT
144 echo zstd > /sys/block/zram0/comp_algorithm
145 echo "algo=zstd level=8" > /sys/block/zram0/algorithm_params
146
120Parameters are algorithm specific: not all algorithms support pre-trained147Parameters are algorithm specific: not all algorithms support pre-trained
121dictionaries, not all algorithms support `level`. Furthermore, for certain148dictionaries, not all algorithms support `level`. Furthermore, for certain
122algorithms `level` controls the compression level (the higher the value the149algorithms `level` controls the compression level (the higher the value the
@@ -124,6 +151,11 @@ better the compression ratio, it even can take negatives values for some · 1 unmodified line
124algorithms), for other algorithms `level` is acceleration level (the higher151algorithms), for other algorithms `level` is acceleration level (the higher
125the value the lower the compression ratio).152the value the lower the compression ratio).
126 153
154Parameters are handed over to the compression algorithm when the device is
155initialised, hence invalid parameters (or parameters that the selected
156algorithm does not support) are reported by the `disksize` write, and not
157by the `algorithm_params` write that has configured them.
158
127Set Disksize159Set Disksize
128============160============
129 161
Documentation/admin-guide/kernel-parameters.txt+14−2
@@ -2077,8 +2077,14 @@ Kernel parameters · 2076 unmodified lines
2077 hugetlb_cma= [HW,CMA,EARLY] The size of a CMA area used for allocation2077 hugetlb_cma= [HW,CMA,EARLY] The size of a CMA area used for allocation
2078 of gigantic hugepages. Or using node format, the size2078 of gigantic hugepages. Or using node format, the size
2079 of a CMA area per node can be specified.2079 of a CMA area per node can be specified.
2080 Format: nn[KMGTPE] or (node format)2080 The size can be an absolute value (e.g., 2G) or a
2081 <node>:nn[KMGTPE][,<node>:nn[KMGTPE]]2081 percentage of the total memory or node memory (e.g., 20%).
2082 Percentage-derived sizes are rounded down to a multiple of
2083 the architecture's gigantic hugepage size and may become
2084 zero.
2085 Format: nn[KMGTPE] or nn% or (node format)
2086 <node>:nn[KMGTPE][,<node>:nn[KMGTPE]] or
2087 <node>:nn%[,<node>:nn%]
2082 2088
2083 The size must be a multiple of the gigantic page size.2089 The size must be a multiple of the gigantic page size.
2084 When using node format, this applies to each per-node size.2090 When using node format, this applies to each per-node size.
@@ -4854,6 +4860,12 @@ Kernel parameters · 2769 unmodified lines
4854 Adjust the minimal page reporting order. The page4860 Adjust the minimal page reporting order. The page
4855 reporting is disabled when it exceeds MAX_PAGE_ORDER.4861 reporting is disabled when it exceeds MAX_PAGE_ORDER.
4856 4862
4863 page_reporting.page_reporting_delay_ms=
4864 [KNL] Free page reporting delay in milliseconds
4865 Format: <unsigned integer>
4866 Adjust the delay in milliseconds between free page
4867 reporting intervals. Default is 2000 (2 seconds).
4868
4857 panic= [KNL] Kernel behaviour on panic: delay <timeout>4869 panic= [KNL] Kernel behaviour on panic: delay <timeout>
4858 timeout > 0: seconds before rebooting4870 timeout > 0: seconds before rebooting
4859 timeout = 0: wait forever4871 timeout = 0: wait forever
Documentation/admin-guide/mm/transhuge.rst+4−2
@@ -224,7 +224,7 @@ khugepaged will be automatically started when any THP size is enabled · 223 unmodified lines
224(either of the per-size anon control or the top-level control are set224(either of the per-size anon control or the top-level control are set
225to "always" or "madvise"), and it'll be automatically shutdown when225to "always" or "madvise"), and it'll be automatically shutdown when
226all THP sizes are disabled (when both the per-size anon control and the226all THP sizes are disabled (when both the per-size anon control and the
227top-level control are "never")227top-level control are "never").
228 228
229process THP controls229process THP controls
230--------------------230--------------------
@@ -301,7 +301,9 @@ being replaced by a PMD mapping, or (2) physical pages replaced by one · 70 unmodified lines
301hugepage of various sizes (PMD-sized or mTHP). Each may happen independently,301hugepage of various sizes (PMD-sized or mTHP). Each may happen independently,
302or together, depending on the type of memory and the failures that occur.302or together, depending on the type of memory and the failures that occur.
303As such, this value should be interpreted roughly as a sign of progress,303As such, this value should be interpreted roughly as a sign of progress,
304and counters in /proc/vmstat consulted for more accurate accounting)::304and counters in /proc/vmstat consulted for more accurate accounting.
305Per-order mTHP collapse statistics are also available under
306/sys/kernel/mm/transparent_hugepage/hugepages-<size>kB/stats/)::
305 307
306 /sys/kernel/mm/transparent_hugepage/khugepaged/pages_collapsed308 /sys/kernel/mm/transparent_hugepage/khugepaged/pages_collapsed
307 309
Documentation/core-api/maple_tree.rst+20−4
@@ -17,7 +17,8 @@ supports iterating over a range of entries and going to the previous or next · 16 unmodified lines
17entry in a cache-efficient manner. The tree can also be put into an RCU-safe17entry in a cache-efficient manner. The tree can also be put into an RCU-safe
18mode of operation which allows reading and writing concurrently. Writers must18mode of operation which allows reading and writing concurrently. Writers must
19synchronize on a lock, which can be the default spinlock, or the user can set19synchronize on a lock, which can be the default spinlock, or the user can set
20the lock to an external lock of a different type.20the lock to an external lock of a different type. Note that external locks may
21interfere with allocations in a low memory situation.
21 22
22The Maple Tree maintains a small memory footprint and was designed to use23The Maple Tree maintains a small memory footprint and was designed to use
23modern processor cache efficiently. The majority of the users will be able to24modern processor cache efficiently. The majority of the users will be able to
@@ -42,6 +43,15 @@ successful store operation within a given · 18 unmodified lines
42code segment when allocating cannot be done. Allocations of nodes are43code segment when allocating cannot be done. Allocations of nodes are
43relatively small at around 256 bytes.44relatively small at around 256 bytes.
44 45
46Since the maple tree uses internal nodes that are allocated and has rules on
47data density, erasing an entry may cause allocations to occur. That is,
48erasing an entry may consume memory. Users must take care to ensure that they
49do not violate the larger system constraints on when and how memory is
50allocated. Most situations are fine to allocate, but the pre-allocation
51support is provided as a mechanism to avoid trickier situations. There is also
52the possibility of using special entries and clean up the tree later, in
53extreme circumstances.
54
45.. _maple-tree-normal-api:55.. _maple-tree-normal-api:
46 56
47Normal API57Normal API
@@ -63,7 +73,10 @@ success or an error code otherwise. mtree_store_range() works in the same way · 15 unmodified lines
63but takes a range. mtree_load() is used to retrieve the entry stored at a73but takes a range. mtree_load() is used to retrieve the entry stored at a
64given index. You can use mtree_erase() to erase an entire range by only74given index. You can use mtree_erase() to erase an entire range by only
65knowing one value within that range, or mtree_store() call with an entry of75knowing one value within that range, or mtree_store() call with an entry of
66NULL may be used to partially erase a range or many ranges at once.76NULL may be used to partially erase a range or many ranges at once. Note that
77mtree_erase() may use GFP_KERNEL | __GFP_NOFAIL for allocations and cannot
78fail. mtree_erase() can sleep, so it must not be called from an atomic
79context.
67 80
68If you want to only store a new entry to a range (or index) if that range is81If you want to only store a new entry to a range (or index) if that range is
69currently ``NULL``, you can use mtree_insert_range() or mtree_insert() which82currently ``NULL``, you can use mtree_insert_range() or mtree_insert() which
@@ -163,7 +176,10 @@ You can use mas_erase() to erase an entire range by setting index and · 93 unmodified lines
163last of the maple state to the desired range to erase. This will erase176last of the maple state to the desired range to erase. This will erase
164the first range that is found in that range, set the maple state index177the first range that is found in that range, set the maple state index
165and last as the range that was erased and return the entry that existed178and last as the range that was erased and return the entry that existed
166at that location.179at that location. Note that mas_erase() may allocate with the GFP_KERNEL
180__GFP_NOFAIL and cannot fail, but may sleep. If this is not okay, consider
181using mas_store_gfp() and pass it a ``NULL``,
182after setting up the correct range by walking to the entry.
167 183
168You can walk each entry within a range by using mas_for_each(). If you want184You can walk each entry within a range by using mas_for_each(). If you want
169to walk each element of the tree then ``0`` and ``ULONG_MAX`` may be used as185to walk each element of the tree then ``0`` and ``ULONG_MAX`` may be used as
@@ -211,7 +227,7 @@ Advanced Locking · 41 unmodified lines
211 227
212The maple tree uses a spinlock by default, but external locks can be used for228The maple tree uses a spinlock by default, but external locks can be used for
213tree updates as well. To use an external lock, the tree must be initialized229tree updates as well. To use an external lock, the tree must be initialized
214with the ``MT_FLAGS_LOCK_EXTERN flag``, this is usually done with the230with the ``MT_FLAGS_LOCK_EXTERN`` flag, this is usually done with the
215MTREE_INIT_EXT() #define, which takes an external lock as an argument.231MTREE_INIT_EXT() #define, which takes an external lock as an argument.
216 232
217Functions and structures233Functions and structures
Documentation/dev-tools/kmemleak.rst+10−0
@@ -198,6 +198,16 @@ systems, because of pointers temporarily stored in CPU registers or · 197 unmodified lines
198stacks. Kmemleak defines MSECS_MIN_AGE (defaulting to 1000) representing198stacks. Kmemleak defines MSECS_MIN_AGE (defaulting to 1000) representing
199the minimum age of an object to be reported as a memory leak.199the minimum age of an object to be reported as a memory leak.
200 200
201The ``min_unref_scans`` module parameter requires an object to be seen
202unreferenced in that many consecutive scans before it is reported. It
203defaults to 2 when CONFIG_DEBUG_KMEMLEAK_VERBOSE is enabled, where the
204periodic scan thread confirms a leak on its own, and to 1 otherwise. A
205value of 1 preserves the historical behaviour; higher values filter the
206transient false positives described above, at the cost of delaying genuine
207reports by up to that many scans. It can be set at boot with
208``kmemleak.min_unref_scans=<n>`` or at run-time via
209``/sys/module/kmemleak/parameters/min_unref_scans``.
210
201Limitations and Drawbacks211Limitations and Drawbacks
202-------------------------212-------------------------
203 213
Documentation/filesystems/fscrypt.rst+4−0
@@ -1237,6 +1237,10 @@ astute users may notice some differences in behavior: · 1236 unmodified lines
1237 1237
1238- DAX (Direct Access) is not supported on encrypted files.1238- DAX (Direct Access) is not supported on encrypted files.
1239 1239
1240- Encrypted files cannot be used directly as swap files. To swap to
1241 an encrypted file, set up a loopback device on top of it.
1242 Alternatively, encrypted swap can use a dm-crypt device.
1243
1240- The maximum length of an encrypted symlink is 2 bytes shorter than1244- The maximum length of an encrypted symlink is 2 bytes shorter than
1241 the maximum length of an unencrypted symlink. For example, on an1245 the maximum length of an unencrypted symlink. For example, on an
1242 EXT4 filesystem with a 4K block size, unencrypted symlinks can be up1246 EXT4 filesystem with a 4K block size, unencrypted symlinks can be up
Documentation/filesystems/locking.rst+2−6
@@ -266,7 +266,6 @@ prototypes:: · 265 unmodified lines
266 int (*error_remove_folio)(struct address_space *, struct folio *);266 int (*error_remove_folio)(struct address_space *, struct folio *);
267 int (*swap_activate)(struct swap_info_struct *sis, struct file *f, sector_t *span)267 int (*swap_activate)(struct swap_info_struct *sis, struct file *f, sector_t *span)
268 int (*swap_deactivate)(struct file *);268 int (*swap_deactivate)(struct file *);
269 int (*swap_rw)(struct kiocb *iocb, struct iov_iter *iter);
270 269
271locking rules:270locking rules:
272 All except dirty_folio and free_folio may block271 All except dirty_folio and free_folio may block
@@ -291,7 +290,6 @@ is_partially_uptodate: yes · 18 unmodified lines
291error_remove_folio: yes290error_remove_folio: yes
292swap_activate: no291swap_activate: no
293swap_deactivate: no292swap_deactivate: no
294swap_rw: yes, unlocks
295====================== ======================== ========= ===============293====================== ======================== ========= ===============
296 294
297->write_begin(), ->write_end() and ->read_folio() may be called from295->write_begin(), ->write_end() and ->read_folio() may be called from
@@ -355,14 +353,12 @@ should perform any validation and preparation necessary to ensure that · 57 unmodified lines
355writes can be performed with minimal memory allocation. It should call353writes can be performed with minimal memory allocation. It should call
356add_swap_extent(), or the helper iomap_swapfile_activate(), and return354add_swap_extent(), or the helper iomap_swapfile_activate(), and return
357the number of extents added. If IO should be submitted through355the number of extents added. If IO should be submitted through
358->swap_rw(), it should set SWP_FS_OPS, otherwise IO will be submitted356the file system it should call swap_fs_activate, otherwise IO will be
359directly to the block device ``sis->bdev``.357submitted directly to the block device ``sis->bdev``.
360 358
361->swap_deactivate() will be called in the sys_swapoff()359->swap_deactivate() will be called in the sys_swapoff()
362path after ->swap_activate() returned success.360path after ->swap_activate() returned success.
363 361
364->swap_rw will be called for swap IO if SWP_FS_OPS was set by ->swap_activate().
365
366file_lock_operations362file_lock_operations
367====================363====================
368 364
Documentation/filesystems/vfs.rst+2−6
@@ -776,7 +776,6 @@ cache in your filesystem. The following members are defined: · 775 unmodified lines
776 int (*error_remove_folio)(struct mapping *mapping, struct folio *);776 int (*error_remove_folio)(struct mapping *mapping, struct folio *);
777 int (*swap_activate)(struct swap_info_struct *sis, struct file *f, sector_t *span)777 int (*swap_activate)(struct swap_info_struct *sis, struct file *f, sector_t *span)
778 int (*swap_deactivate)(struct file *);778 int (*swap_deactivate)(struct file *);
779 int (*swap_rw)(struct kiocb *iocb, struct iov_iter *iter);
780 };779 };
781 780
782``read_folio``781``read_folio``
@@ -977,16 +976,13 @@ cache in your filesystem. The following members are defined: · 194 unmodified lines
977 can be performed with minimal memory allocation. It should call976 can be performed with minimal memory allocation. It should call
978 add_swap_extent(), or the helper iomap_swapfile_activate(), and977 add_swap_extent(), or the helper iomap_swapfile_activate(), and
979 return the number of extents added. If IO should be submitted978 return the number of extents added. If IO should be submitted
980 through ->swap_rw(), it should set SWP_FS_OPS, otherwise IO will979 through the file system it should call swap_fs_activate, otherwise IO
981 be submitted directly to the block device ``sis->bdev``.980 will be submitted directly to the block device ``sis->bdev``.
982 981
983``swap_deactivate``982``swap_deactivate``
984 Called during swapoff on files where swap_activate was983 Called during swapoff on files where swap_activate was
985 successful.984 successful.
986 985
987``swap_rw``
988 Called to read or write swap pages when SWP_FS_OPS is set.
989
990The File Object986The File Object
991===============987===============
992 988
Documentation/mm/allocation-profiling.rst+16−0
@@ -43,9 +43,25 @@ sysctl: · 42 unmodified lines
43 warnings produced by allocations made while profiling is disabled and freed43 warnings produced by allocations made while profiling is disabled and freed
44 when it's enabled.44 when it's enabled.
45 45
46 /proc/sys/vm/mem_profiling_compressed
47
48 1: Page alloc tag compression is enabled.
49
50 0: Page alloc tag compression is disabled.
51
52 This reflects a static boot-time configuration of how page allocation tags are
53 stored (in page flags when compression is enabled and in page_ext when disabled).
54 Toggling ``mem_profiling`` at runtime does not change the state of
55 ``mem_profiling_compressed``.
56
46Runtime info:57Runtime info:
47 /proc/allocinfo58 /proc/allocinfo
48 59
60 Profiling data can be retrieved either by reading `/proc/allocinfo` directly as
61 text or programmatically via `ioctl()` calls defined in `<uapi/linux/alloc_tag.h>`.
62 The ioctl interface supports structured binary data extraction as well as filtering
63 by module name, function, file, line number, accuracy, or allocation size limits.
64
49Example output::65Example output::
50 66
51 root@moria-kvm:~# sort -g /proc/allocinfo|tail|numfmt --to=iec67 root@moria-kvm:~# sort -g /proc/allocinfo|tail|numfmt --to=iec
Documentation/mm/ksm.rst+2−2
@@ -24,13 +24,13 @@ tree. · 23 unmodified lines
24 24
25If a KSM page is shared between less than ``max_page_sharing`` VMAs,25If a KSM page is shared between less than ``max_page_sharing`` VMAs,
26the node of the stable tree that represents such KSM page points to a26the node of the stable tree that represents such KSM page points to a
27list of struct ksm_rmap_item and the ``page->mapping`` of the27list of struct ksm_rmap_item and the ``folio->mapping`` of the
28KSM page points to the stable tree node.28KSM page points to the stable tree node.
29 29
30When the sharing passes this threshold, KSM adds a second dimension to30When the sharing passes this threshold, KSM adds a second dimension to
31the stable tree. The tree node becomes a "chain" that links one or31the stable tree. The tree node becomes a "chain" that links one or
32more "dups". Each "dup" keeps reverse mapping information for a KSM32more "dups". Each "dup" keeps reverse mapping information for a KSM
33page with ``page->mapping`` pointing to that "dup".33page with ``folio->mapping`` pointing to that "dup".
34 34
35Every "chain" and all "dups" linked into a "chain" enforce the35Every "chain" and all "dups" linked into a "chain" enforce the
36invariant that they represent the same write protected memory content,36invariant that they represent the same write protected memory content,
Documentation/mm/page_migration.rst+3−3
@@ -110,13 +110,13 @@ Steps: · 109 unmodified lines
1106. The refcount of the page is examined and we back out if references remain.1106. The refcount of the page is examined and we back out if references remain.
111 Otherwise, we know that we are the only one referencing this page.111 Otherwise, we know that we are the only one referencing this page.
112 112
1137. The radix tree is checked and if it does not contain the pointer to this1137. The page cache tree is checked and if it does not contain the pointer to this
114 page then we back out because someone else modified the radix tree.114 page then we back out because someone else modified the page cache tree.
115 115
1168. The new page is prepped with some settings from the old page so that1168. The new page is prepped with some settings from the old page so that
117 accesses to the new page will discover a page with the correct settings.117 accesses to the new page will discover a page with the correct settings.
118 118
1199. The radix tree is changed to point to the new page.1199. The page cache tree is changed to point to the new page.
120 120
12110. The reference count of the old page is dropped because the address space12110. The reference count of the old page is dropped because the address space
122 reference is gone. A reference to the new page is established because122 reference is gone. A reference to the new page is established because
Documentation/translations/zh_CN/mm/ksm.rst+2−2
@@ -31,10 +31,10 @@ KSM维护着稳定树中的KSM页的逆映射信息。 · 30 unmodified lines
31 31
32当KSM页面的共享数小于 ``max_page_sharing`` 的虚拟内存区域(VMAs)时,则代表了32当KSM页面的共享数小于 ``max_page_sharing`` 的虚拟内存区域(VMAs)时,则代表了
33KSM页的稳定树其中的节点指向了一个ksm_rmap_item结构体类型的列表。同时,这个KSM页33KSM页的稳定树其中的节点指向了一个ksm_rmap_item结构体类型的列表。同时,这个KSM页
34的 ``page->mapping`` 指向了该稳定树节点。34的 ``folio->mapping`` 指向了该稳定树节点。
35 35
36如果共享数超过了阈值,KSM将给稳定树添加第二个维度。稳定树就变成链接一个或多36如果共享数超过了阈值,KSM将给稳定树添加第二个维度。稳定树就变成链接一个或多
37个稳定树"副本"的"链"。每个副本都保留KSM页的逆映射信息,其中 ``page->mapping``37个稳定树"副本"的"链"。每个副本都保留KSM页的逆映射信息,其中 ``folio->mapping``
38指向该"副本"。38指向该"副本"。
39 39
40每个链以及链接到该链中的所有"副本"强制不变的是,它们代表了相同的写保护内存40每个链以及链接到该链中的所有"副本"强制不变的是,它们代表了相同的写保护内存
Documentation/userspace-api/ioctl/ioctl-number.rst+2−0
@@ -346,6 +346,8 @@ Code Seq# Include File Comments · 345 unmodified lines
346 <mailto:luzmaximilian@gmail.com>346 <mailto:luzmaximilian@gmail.com>
3470xA5 20-2F linux/surface_aggregator/dtx.h Microsoft Surface DTX driver3470xA5 20-2F linux/surface_aggregator/dtx.h Microsoft Surface DTX driver
348 <mailto:luzmaximilian@gmail.com>348 <mailto:luzmaximilian@gmail.com>
3490xA6 00-0F uapi/linux/alloc_tag.h Memory allocation profiling
350 <mailto:surenb@google.com>
3490xAA 00-3F linux/uapi/linux/userfaultfd.h3510xAA 00-3F linux/uapi/linux/userfaultfd.h
3500xAB 00-1F linux/nbd.h3520xAB 00-1F linux/nbd.h
3510xAC 00-1F linux/raw.h3530xAC 00-1F linux/raw.h
MAINTAINERS+6−0
@@ -17022,6 +17022,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rppt/memblock.git fixes · 17021 unmodified lines
17022F: Documentation/core-api/boot-time-mm.rst17022F: Documentation/core-api/boot-time-mm.rst
17023F: include/linux/kho/abi/memblock.h17023F: include/linux/kho/abi/memblock.h
17024F: include/linux/memblock.h17024F: include/linux/memblock.h
17025F: mm/arch_numa.c
17025F: mm/memblock.c17026F: mm/memblock.c
17026F: mm/memtest.c17027F: mm/memtest.c
17027F: mm/mm_init.c17028F: mm/mm_init.c
@@ -17081,7 +17082,9 @@ S: Maintained · 53 unmodified lines
17081F: Documentation/mm/allocation-profiling.rst17082F: Documentation/mm/allocation-profiling.rst
17082F: include/linux/alloc_tag.h17083F: include/linux/alloc_tag.h
17083F: include/linux/pgalloc_tag.h17084F: include/linux/pgalloc_tag.h
17085F: include/uapi/linux/alloc_tag.h
17084F: mm/alloc_tag.c17086F: mm/alloc_tag.c
17087F: tools/testing/selftests/alloc_tag/
17085 17088
17086MEMORY MANAGEMENT - BALLOON17089MEMORY MANAGEMENT - BALLOON
17087M: Andrew Morton <akpm@linux-foundation.org>17090M: Andrew Morton <akpm@linux-foundation.org>
@@ -17254,6 +17257,7 @@ F: Documentation/ABI/testing/sysfs-kernel-mm-memory-tiers · 166 unmodified lines
17254F: Documentation/ABI/testing/sysfs-kernel-mm-numa17257F: Documentation/ABI/testing/sysfs-kernel-mm-numa
17255F: Documentation/admin-guide/mm/17258F: Documentation/admin-guide/mm/
17256F: Documentation/mm/17259F: Documentation/mm/
17260F: drivers/char/mem.c
17257F: include/linux/cma.h17261F: include/linux/cma.h
17258F: include/linux/dmapool.h17262F: include/linux/dmapool.h
17259F: include/linux/ioremap.h17263F: include/linux/ioremap.h
@@ -17381,6 +17385,7 @@ S: Maintained · 121 unmodified lines
17381F: Documentation/ABI/testing/sysfs-kernel-mm-swap17385F: Documentation/ABI/testing/sysfs-kernel-mm-swap
17382F: Documentation/mm/swap-table.rst17386F: Documentation/mm/swap-table.rst
17383F: include/linux/swap.h17387F: include/linux/swap.h
17388F: include/linux/swap_ops.h
17384F: include/linux/swapfile.h17389F: include/linux/swapfile.h
17385F: include/linux/swapops.h17390F: include/linux/swapops.h
17386F: mm/page_io.c17391F: mm/page_io.c
@@ -17457,6 +17462,7 @@ L: linux-mm@kvack.org · 70 unmodified lines
17457S: Maintained17462S: Maintained
17458W: http://www.linux-mm.org17463W: http://www.linux-mm.org
17459T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm17464T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
17465F: drivers/char/mem.c
17460F: include/trace/events/mmap.h17466F: include/trace/events/mmap.h
17461F: fs/proc/task_mmu.c17467F: fs/proc/task_mmu.c
17462F: fs/proc/task_nommu.c17468F: fs/proc/task_nommu.c
arch/s390/mm/gmap_helpers.c+1−1
@@ -203,7 +203,7 @@ static int find_zeropage_pte_entry(pte_t *pte, unsigned long addr, · 202 unmodified lines
203 * currently only works in COW mappings, which is also where203 * currently only works in COW mappings, which is also where
204 * mm_forbids_zeropage() is checked.204 * mm_forbids_zeropage() is checked.
205 */205 */
206 if (!is_cow_mapping(walk->vma->vm_flags))206 if (!vma_is_cow_mapping(walk->vma))
207 return -EFAULT;207 return -EFAULT;
208 208
209 *found_addr = addr;209 *found_addr = addr;
drivers/base/Kconfig+0−7
@@ -230,13 +230,6 @@ config GENERIC_ARCH_TOPOLOGY · 229 unmodified lines
230 appropriate scaling, sysfs interface for reading capacity values at230 appropriate scaling, sysfs interface for reading capacity values at
231 runtime.231 runtime.
232 232
233config GENERIC_ARCH_NUMA
234 bool
235 select NUMA_MEMBLKS
236 help
237 Enable support for generic NUMA implementation. Currently, RISC-V
238 and ARM64 use it.
239
240config FW_DEVLINK_SYNC_STATE_TIMEOUT233config FW_DEVLINK_SYNC_STATE_TIMEOUT
241 bool "sync_state() behavior defaults to timeout instead of strict"234 bool "sync_state() behavior defaults to timeout instead of strict"
242 help235 help
drivers/base/Makefile+0−1
@@ -25,7 +25,6 @@ obj-$(CONFIG_PINCTRL) += pinctrl.o · 24 unmodified lines
25obj-$(CONFIG_DEV_COREDUMP) += devcoredump.o25obj-$(CONFIG_DEV_COREDUMP) += devcoredump.o
26obj-$(CONFIG_GENERIC_MSI_IRQ) += platform-msi.o26obj-$(CONFIG_GENERIC_MSI_IRQ) += platform-msi.o
27obj-$(CONFIG_GENERIC_ARCH_TOPOLOGY) += arch_topology.o27obj-$(CONFIG_GENERIC_ARCH_TOPOLOGY) += arch_topology.o
28obj-$(CONFIG_GENERIC_ARCH_NUMA) += arch_numa.o
29obj-$(CONFIG_ACPI) += physical_location.o28obj-$(CONFIG_ACPI) += physical_location.o
30 29
31obj-y += test/30obj-y += test/
drivers/block/zram/backend_842.c+10−0
@@ -1,5 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2 2
3#define pr_fmt(fmt) "842: " fmt
4
3#include <linux/kernel.h>5#include <linux/kernel.h>
4#include <linux/slab.h>6#include <linux/slab.h>
5#include <linux/sw842.h>7#include <linux/sw842.h>
@@ -13,6 +15,14 @@ static void release_params_842(struct zcomp_params *params) · 7 unmodified lines
13 15
14static int setup_params_842(struct zcomp_params *params)16static int setup_params_842(struct zcomp_params *params)
15{17{
18 if (params->dict_sz) {
19 pr_err("dictionary is not supported\n");
20 return -EOPNOTSUPP;
21 }
22 if (params->level != ZCOMP_PARAM_NOT_SET) {
23 pr_err("compression level is not supported\n");
24 return -EOPNOTSUPP;
25 }
16 return 0;26 return 0;
17}27}
18 28
drivers/block/zram/backend_deflate.c+23−2
@@ -1,5 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2 2
3#define pr_fmt(fmt) "deflate: " fmt
4
3#include <linux/kernel.h>5#include <linux/kernel.h>
4#include <linux/slab.h>6#include <linux/slab.h>
5#include <linux/vmalloc.h>7#include <linux/vmalloc.h>
@@ -22,10 +24,29 @@ static void deflate_release_params(struct zcomp_params *params) · 16 unmodified lines
22 24
23static int deflate_setup_params(struct zcomp_params *params)25static int deflate_setup_params(struct zcomp_params *params)
24{26{
25 if (params->level == ZCOMP_PARAM_NOT_SET)27 if (params->dict_sz) {
28 pr_err("dictionary is not supported\n");
29 return -EOPNOTSUPP;
30 }
31
32 if (params->level == ZCOMP_PARAM_NOT_SET) {
26 params->level = Z_DEFAULT_COMPRESSION;33 params->level = Z_DEFAULT_COMPRESSION;
27 if (params->deflate.winbits == ZCOMP_PARAM_NOT_SET)34 } else if (params->level < Z_DEFAULT_COMPRESSION ||
35 params->level > Z_BEST_COMPRESSION) {
36 pr_err("invalid compression level %d\n", params->level);
37 return -EINVAL;
38 }
39
40 if (params->deflate.winbits == ZCOMP_PARAM_NOT_SET) {
28 params->deflate.winbits = DEFLATE_DEF_WINBITS;41 params->deflate.winbits = DEFLATE_DEF_WINBITS;
42 } else {
43 s32 wb = params->deflate.winbits;
44
45 if ((wb < -15 || wb > -9) && (wb < 9 || wb > 15)) {
46 pr_err("invalid winbits %d\n", wb);
47 return -EINVAL;
48 }
49 }
29 50
30 return 0;51 return 0;
31}52}
drivers/block/zram/backend_lz4.c+9−1
@@ -1,3 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0-or-later
2
3#define pr_fmt(fmt) "lz4: " fmt
4
1#include <linux/kernel.h>5#include <linux/kernel.h>
2#include <linux/lz4.h>6#include <linux/lz4.h>
3#include <linux/slab.h>7#include <linux/slab.h>
@@ -28,8 +32,12 @@ static int lz4_setup_params(struct zcomp_params *params) · 24 unmodified lines
28 LZ4_stream_t *dict_stream;32 LZ4_stream_t *dict_stream;
29 int ret;33 int ret;
30 34
31 if (params->level == ZCOMP_PARAM_NOT_SET)35 if (params->level == ZCOMP_PARAM_NOT_SET) {
32 params->level = LZ4_ACCELERATION_DEFAULT;36 params->level = LZ4_ACCELERATION_DEFAULT;
37 } else if (params->level < LZ4_ACCELERATION_DEFAULT) {
38 pr_err("invalid compression level %d\n", params->level);
39 return -EINVAL;
40 }
33 41
34 if (!params->dict || !params->dict_sz)42 if (!params->dict || !params->dict_sz)
35 return 0;43 return 0;
drivers/block/zram/backend_lz4hc.c+15−1
@@ -1,3 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0-or-later
2
3#define pr_fmt(fmt) "lz4hc: " fmt
4
1#include <linux/kernel.h>5#include <linux/kernel.h>
2#include <linux/lz4.h>6#include <linux/lz4.h>
3#include <linux/slab.h>7#include <linux/slab.h>
@@ -18,8 +22,18 @@ static void lz4hc_release_params(struct zcomp_params *params) · 14 unmodified lines
18 22
19static int lz4hc_setup_params(struct zcomp_params *params)23static int lz4hc_setup_params(struct zcomp_params *params)
20{24{
21 if (params->level == ZCOMP_PARAM_NOT_SET)25 if (params->level == ZCOMP_PARAM_NOT_SET) {
22 params->level = LZ4HC_DEFAULT_CLEVEL;26 params->level = LZ4HC_DEFAULT_CLEVEL;
27 } else if (params->level < 1 || params->level > LZ4HC_MAX_CLEVEL) {
28 /*
29 * Use < 1 rather than < LZ4HC_MIN_CLEVEL here because
30 * LZ4HC_compress_generic() only clamps levels below 1
31 * (levels 1 and 2 are valid). LZ4HC_MIN_CLEVEL (3) is
32 * advisory and not enforced by the library.
33 */
34 pr_err("invalid compression level %d\n", params->level);
35 return -EINVAL;
36 }
23 37
24 return 0;38 return 0;
25}39}
drivers/block/zram/backend_lzo.c+10−0
@@ -1,5 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2 2
3#define pr_fmt(fmt) "lzo: " fmt
4
3#include <linux/kernel.h>5#include <linux/kernel.h>
4#include <linux/slab.h>6#include <linux/slab.h>
5#include <linux/lzo.h>7#include <linux/lzo.h>
@@ -12,6 +14,14 @@ static void lzo_release_params(struct zcomp_params *params) · 6 unmodified lines
12 14
13static int lzo_setup_params(struct zcomp_params *params)15static int lzo_setup_params(struct zcomp_params *params)
14{16{
17 if (params->dict_sz) {
18 pr_err("dictionary is not supported\n");
19 return -EOPNOTSUPP;
20 }
21 if (params->level != ZCOMP_PARAM_NOT_SET) {
22 pr_err("compression level is not supported\n");
23 return -EOPNOTSUPP;
24 }
15 return 0;25 return 0;
16}26}
17 27
drivers/block/zram/backend_lzorle.c+10−0
@@ -1,5 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2 2
3#define pr_fmt(fmt) "lzo-rle: " fmt
4
3#include <linux/kernel.h>5#include <linux/kernel.h>
4#include <linux/slab.h>6#include <linux/slab.h>
5#include <linux/lzo.h>7#include <linux/lzo.h>
@@ -12,6 +14,14 @@ static void lzorle_release_params(struct zcomp_params *params) · 6 unmodified lines
12 14
13static int lzorle_setup_params(struct zcomp_params *params)15static int lzorle_setup_params(struct zcomp_params *params)
14{16{
17 if (params->dict_sz) {
18 pr_err("dictionary is not supported\n");
19 return -EOPNOTSUPP;
20 }
21 if (params->level != ZCOMP_PARAM_NOT_SET) {
22 pr_err("compression level is not supported\n");
23 return -EOPNOTSUPP;
24 }
15 return 0;25 return 0;
16}26}
17 27
drivers/block/zram/backend_zstd.c+8−3
@@ -1,5 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0-or-later1// SPDX-License-Identifier: GPL-2.0-or-later
2 2
3#define pr_fmt(fmt) "zstd: " fmt
4
3#include <linux/kernel.h>5#include <linux/kernel.h>
4#include <linux/slab.h>6#include <linux/slab.h>
5#include <linux/vmalloc.h>7#include <linux/vmalloc.h>
@@ -58,8 +60,13 @@ static int zstd_setup_params(struct zcomp_params *params) · 52 unmodified lines
58 return -ENOMEM;60 return -ENOMEM;
59 61
60 params->drv_data = zp;62 params->drv_data = zp;
61 if (params->level == ZCOMP_PARAM_NOT_SET)63 if (params->level == ZCOMP_PARAM_NOT_SET) {
62 params->level = zstd_default_clevel();64 params->level = zstd_default_clevel();
65 } else if (params->level < zstd_min_clevel() ||
66 params->level > zstd_max_clevel()) {
67 pr_err("invalid compression level %d\n", params->level);
68 goto error;
69 }
63 70
64 zp->cprm = zstd_get_params(params->level, PAGE_SIZE);71 zp->cprm = zstd_get_params(params->level, PAGE_SIZE);
65 72
@@ -85,7 +92,6 @@ static int zstd_setup_params(struct zcomp_params *params) · 19 unmodified lines
85 return 0;92 return 0;
86 93
87error:94error:
88 zstd_release_params(params);
89 return -EINVAL;95 return -EINVAL;
90}96}
91 97
@@ -161,7 +167,6 @@ static int zstd_create(struct zcomp_params *params, struct zcomp_ctx *ctx) · 69 unmodified lines
161 return 0;167 return 0;
162 168
163error:169error:
164 zstd_release_params(params);
165 zstd_destroy(ctx);170 zstd_destroy(ctx);
166 return -EINVAL;171 return -EINVAL;
167}172}
drivers/block/zram/zram_drv.c+109−79
@@ -56,7 +56,7 @@ static size_t huge_class_size; · 55 unmodified lines
56 56
57static const struct block_device_operations zram_devops;57static const struct block_device_operations zram_devops;
58 58
59static void slot_free(struct zram *zram, u32 index);59static void slot_free(struct zram *zram, unsigned long index);
60 60
61/*61/*
62 * entry locking rules:62 * entry locking rules:
@@ -70,11 +70,11 @@ static void slot_free(struct zram *zram, u32 index); · 7 unmodified lines
70 * 4) Use TRY lock variant when in atomic context70 * 4) Use TRY lock variant when in atomic context
71 * - must check return value and handle locking failers71 * - must check return value and handle locking failers
72 */72 */
73static __must_check bool slot_trylock(struct zram *zram, u32 index)73static __must_check bool slot_trylock(struct zram *zram, unsigned long index)
74{74{
75 unsigned long *lock = &zram->table[index].__lock;75 unsigned long *lock = &zram->table[index].__lock;
76 76
77 if (!test_and_set_bit_lock(ZRAM_ENTRY_LOCK, lock)) {77 if (!test_and_set_bit_lock(ZRAM_ENTRY_LOCK_BIT, lock)) {
78 mutex_acquire(&zram->table_lock_map, 0, 1, _RET_IP_);78 mutex_acquire(&zram->table_lock_map, 0, 1, _RET_IP_);
79 lock_acquired(&zram->table_lock_map, _RET_IP_);79 lock_acquired(&zram->table_lock_map, _RET_IP_);
80 return true;80 return true;
@@ -83,21 +83,21 @@ static __must_check bool slot_trylock(struct zram *zram, u32 index) · 2 unmodified lines
83 return false;83 return false;
84}84}
85 85
86static void slot_lock(struct zram *zram, u32 index)86static void slot_lock(struct zram *zram, unsigned long index)
87{87{
88 unsigned long *lock = &zram->table[index].__lock;88 unsigned long *lock = &zram->table[index].__lock;
89 89
90 mutex_acquire(&zram->table_lock_map, 0, 0, _RET_IP_);90 mutex_acquire(&zram->table_lock_map, 0, 0, _RET_IP_);
91 wait_on_bit_lock(lock, ZRAM_ENTRY_LOCK, TASK_UNINTERRUPTIBLE);91 wait_on_bit_lock(lock, ZRAM_ENTRY_LOCK_BIT, TASK_UNINTERRUPTIBLE);
92 lock_acquired(&zram->table_lock_map, _RET_IP_);92 lock_acquired(&zram->table_lock_map, _RET_IP_);
93}93}
94 94
95static void slot_unlock(struct zram *zram, u32 index)95static void slot_unlock(struct zram *zram, unsigned long index)
96{96{
97 unsigned long *lock = &zram->table[index].__lock;97 unsigned long *lock = &zram->table[index].__lock;
98 98
99 mutex_release(&zram->table_lock_map, _RET_IP_);99 mutex_release(&zram->table_lock_map, _RET_IP_);
100 clear_and_wake_up_bit(ZRAM_ENTRY_LOCK, lock);100 clear_and_wake_up_bit(ZRAM_ENTRY_LOCK_BIT, lock);
101}101}
102 102
103static inline bool init_done(struct zram *zram)103static inline bool init_done(struct zram *zram)
@@ -110,55 +110,56 @@ static inline struct zram *dev_to_zram(struct device *dev) · 6 unmodified lines
110 return (struct zram *)dev_to_disk(dev)->private_data;110 return (struct zram *)dev_to_disk(dev)->private_data;
111}111}
112 112
113static unsigned long get_slot_handle(struct zram *zram, u32 index)113static unsigned long get_slot_handle(struct zram *zram, unsigned long index)
114{114{
115 return zram->table[index].handle;115 return zram->table[index].handle;
116}116}
117 117
118static void set_slot_handle(struct zram *zram, u32 index, unsigned long handle)118static void set_slot_handle(struct zram *zram, unsigned long index,
119 unsigned long handle)
119{120{
120 zram->table[index].handle = handle;121 zram->table[index].handle = handle;
121}122}
122 123
123static bool test_slot_flag(struct zram *zram, u32 index,124static bool test_slot_flag(struct zram *zram, unsigned long index,
124 enum zram_pageflags flag)125 enum zram_pageflags flag)
125{126{
126 return zram->table[index].attr.flags & BIT(flag);127 return zram->table[index].attr.flags & BIT(flag);
127}128}
128 129
129static void set_slot_flag(struct zram *zram, u32 index,130static void set_slot_flag(struct zram *zram, unsigned long index,
130 enum zram_pageflags flag)131 enum zram_pageflags flag)
131{132{
132 zram->table[index].attr.flags |= BIT(flag);133 zram->table[index].attr.flags |= BIT(flag);
133}134}
134 135
135static void clear_slot_flag(struct zram *zram, u32 index,136static void clear_slot_flag(struct zram *zram, unsigned long index,
136 enum zram_pageflags flag)137 enum zram_pageflags flag)
137{138{
138 zram->table[index].attr.flags &= ~BIT(flag);139 zram->table[index].attr.flags &= ~BIT(flag);
139}140}
140 141
141static size_t get_slot_size(struct zram *zram, u32 index)142static size_t get_slot_size(struct zram *zram, unsigned long index)
142{143{
143 return zram->table[index].attr.flags & (BIT(ZRAM_FLAG_SHIFT) - 1);144 return zram->table[index].attr.flags & (BIT(ZRAM_FLAG_SHIFT) - 1);
144}145}
145 146
146static void set_slot_size(struct zram *zram, u32 index, size_t size)147static void set_slot_size(struct zram *zram, unsigned long index, size_t size)
147{148{
148 unsigned long flags = zram->table[index].attr.flags >> ZRAM_FLAG_SHIFT;149 unsigned long flags = zram->table[index].attr.flags >> ZRAM_FLAG_SHIFT;
149 150
150 zram->table[index].attr.flags = (flags << ZRAM_FLAG_SHIFT) | size;151 zram->table[index].attr.flags = (flags << ZRAM_FLAG_SHIFT) | size;
151}152}
152 153
153static inline bool slot_allocated(struct zram *zram, u32 index)154static inline bool slot_allocated(struct zram *zram, unsigned long index)
154{155{
155 return get_slot_size(zram, index) ||156 return get_slot_size(zram, index) ||
156 test_slot_flag(zram, index, ZRAM_SAME) ||157 test_slot_flag(zram, index, ZRAM_SAME) ||
157 test_slot_flag(zram, index, ZRAM_WB);158 test_slot_flag(zram, index, ZRAM_WB);
158}159}
159 160
160static inline void set_slot_comp_priority(struct zram *zram, u32 index,161static inline void set_slot_comp_priority(struct zram *zram,
161 u32 prio)162 unsigned long index, u32 prio)
162{163{
163 prio &= ZRAM_COMP_PRIORITY_MASK;164 prio &= ZRAM_COMP_PRIORITY_MASK;
164 /*165 /*
@@ -170,14 +171,14 @@ static inline void set_slot_comp_priority(struct zram *zram, u32 index, · 5 unmodified lines
170 zram->table[index].attr.flags |= (prio << ZRAM_COMP_PRIORITY_BIT1);171 zram->table[index].attr.flags |= (prio << ZRAM_COMP_PRIORITY_BIT1);
171}172}
172 173
173static inline u32 get_slot_comp_priority(struct zram *zram, u32 index)174static inline u32 get_slot_comp_priority(struct zram *zram, unsigned long index)
174{175{
175 u32 prio = zram->table[index].attr.flags >> ZRAM_COMP_PRIORITY_BIT1;176 u32 prio = zram->table[index].attr.flags >> ZRAM_COMP_PRIORITY_BIT1;
176 177
177 return prio & ZRAM_COMP_PRIORITY_MASK;178 return prio & ZRAM_COMP_PRIORITY_MASK;
178}179}
179 180
180static void mark_slot_accessed(struct zram *zram, u32 index)181static void mark_slot_accessed(struct zram *zram, unsigned long index)
181{182{
182 clear_slot_flag(zram, index, ZRAM_IDLE);183 clear_slot_flag(zram, index, ZRAM_IDLE);
183 clear_slot_flag(zram, index, ZRAM_PP_SLOT);184 clear_slot_flag(zram, index, ZRAM_PP_SLOT);
@@ -284,7 +285,7 @@ static void release_pp_ctl(struct zram *zram, struct zram_pp_ctl *ctl) · 100 unmodified lines
284}285}
285 286
286static bool place_pp_slot(struct zram *zram, struct zram_pp_ctl *ctl,287static bool place_pp_slot(struct zram *zram, struct zram_pp_ctl *ctl,
287 u32 index)288 unsigned long index)
288{289{
289 struct zram_pp_slot *pps;290 struct zram_pp_slot *pps;
290 u32 bid;291 u32 bid;
@@ -418,7 +419,7 @@ static void mark_idle(struct zram *zram, ktime_t cutoff) · 127 unmodified lines
418{419{
419 int is_idle = 1;420 int is_idle = 1;
420 unsigned long nr_pages = zram->disksize >> PAGE_SHIFT;421 unsigned long nr_pages = zram->disksize >> PAGE_SHIFT;
421 int index;422 unsigned long index;
422 423
423 for (index = 0; index < nr_pages; index++) {424 for (index = 0; index < nr_pages; index++) {
424 /*425 /*
@@ -485,8 +486,9 @@ static ssize_t idle_store(struct device *dev, struct device_attribute *attr, · 60 unmodified lines
485#define INVALID_BDEV_BLOCK (~0UL)486#define INVALID_BDEV_BLOCK (~0UL)
486 487
487static int read_from_zspool_raw(struct zram *zram, struct page *page,488static int read_from_zspool_raw(struct zram *zram, struct page *page,
488 u32 index);489 unsigned long index);
489static int read_from_zspool(struct zram *zram, struct page *page, u32 index);490static int read_from_zspool(struct zram *zram, struct page *page,
491 unsigned long index);
490 492
491struct zram_wb_ctl {493struct zram_wb_ctl {
492 /* idle list is accessed only by the writeback task, no concurency */494 /* idle list is accessed only by the writeback task, no concurency */
@@ -522,7 +524,7 @@ struct zram_rb_req { · 29 unmodified lines
522 /* error status (sync read) */524 /* error status (sync read) */
523 int error;525 int error;
524 };526 };
525 u32 index;527 unsigned long index;
526};528};
527 529
528#define FOUR_K(x) ((x) * (1 << (PAGE_SHIFT - 12)))530#define FOUR_K(x) ((x) * (1 << (PAGE_SHIFT - 12)))
@@ -910,7 +912,7 @@ static void zram_account_writeback_submit(struct zram *zram) · 381 unmodified lines
910 912
911static int zram_writeback_complete(struct zram *zram, struct zram_wb_req *req)913static int zram_writeback_complete(struct zram *zram, struct zram_wb_req *req)
912{914{
913 u32 index = req->pps->index;915 unsigned long index = req->pps->index;
914 int err;916 int err;
915 917
916 err = blk_status_to_errno(req->bio.bi_status);918 err = blk_status_to_errno(req->bio.bi_status);
@@ -1032,7 +1034,7 @@ static int zram_writeback_slots(struct zram *zram, · 115 unmodified lines
1032 struct zram_wb_req *req = NULL;1034 struct zram_wb_req *req = NULL;
1033 struct zram_pp_slot *pps;1035 struct zram_pp_slot *pps;
1034 int ret = 0, err = 0;1036 int ret = 0, err = 0;
1035 u32 index = 0;1037 unsigned long index = 0;
1036 1038
1037 while ((pps = select_pp_slot(ctl))) {1039 while ((pps = select_pp_slot(ctl))) {
1038 if (zram->wb_limit_enable && !zram->bd_wb_limit) {1040 if (zram->wb_limit_enable && !zram->bd_wb_limit) {
@@ -1198,7 +1200,7 @@ static void scan_slots_for_writeback(struct zram *zram, u32 mode, · 159 unmodified lines
1198 unsigned long lo, unsigned long hi,1200 unsigned long lo, unsigned long hi,
1199 struct zram_pp_ctl *ctl)1201 struct zram_pp_ctl *ctl)
1200{1202{
1201 u32 index = lo;1203 unsigned long index = lo;
1202 1204
1203 while (index < hi) {1205 while (index < hi) {
1204 bool ok = true;1206 bool ok = true;
@@ -1235,8 +1237,8 @@ static ssize_t writeback_store(struct device *dev, · 30 unmodified lines
1235 const char *buf, size_t len)1237 const char *buf, size_t len)
1236{1238{
1237 struct zram *zram = dev_to_zram(dev);1239 struct zram *zram = dev_to_zram(dev);
1238 u64 nr_pages = zram->disksize >> PAGE_SHIFT;1240 unsigned long nr_pages;
1239 unsigned long lo = 0, hi = nr_pages;1241 unsigned long lo = 0, hi;
1240 struct zram_pp_ctl *pp_ctl = NULL;1242 struct zram_pp_ctl *pp_ctl = NULL;
1241 struct zram_wb_ctl *wb_ctl = NULL;1243 struct zram_wb_ctl *wb_ctl = NULL;
1242 char *args, *param, *val;1244 char *args, *param, *val;
@@ -1250,6 +1252,9 @@ static ssize_t writeback_store(struct device *dev, · 7 unmodified lines
1250 if (!zram->backing_dev)1252 if (!zram->backing_dev)
1251 return -ENODEV;1253 return -ENODEV;
1252 1254
1255 nr_pages = zram->disksize >> PAGE_SHIFT;
1256 hi = nr_pages;
1257
1253 pp_ctl = init_pp_ctl();1258 pp_ctl = init_pp_ctl();
1254 if (!pp_ctl)1259 if (!pp_ctl)
1255 return -ENOMEM;1260 return -ENOMEM;
@@ -1333,7 +1338,8 @@ out: · 77 unmodified lines
1333 return ret;1338 return ret;
1334}1339}
1335 1340
1336static int decompress_bdev_page(struct zram *zram, struct page *page, u32 index)1341static int decompress_bdev_page(struct zram *zram, struct page *page,
1342 unsigned long index)
1337{1343{
1338 struct zcomp_strm *zstrm;1344 struct zcomp_strm *zstrm;
1339 unsigned int size;1345 unsigned int size;
@@ -1375,7 +1381,7 @@ static void zram_deferred_decompress(struct work_struct *w) · 35 unmodified lines
1375 struct zram_rb_req *req = container_of(w, struct zram_rb_req, work);1381 struct zram_rb_req *req = container_of(w, struct zram_rb_req, work);
1376 struct page *page = bio_first_page_all(req->bio);1382 struct page *page = bio_first_page_all(req->bio);
1377 struct zram *zram = req->zram;1383 struct zram *zram = req->zram;
1378 u32 index = req->index;1384 unsigned long index = req->index;
1379 int ret;1385 int ret;
1380 1386
1381 ret = decompress_bdev_page(zram, page, index);1387 ret = decompress_bdev_page(zram, page, index);
@@ -1426,7 +1432,7 @@ static void zram_async_read_endio(struct bio *bio) · 44 unmodified lines
1426}1432}
1427 1433
1428static int read_from_bdev_async(struct zram *zram, struct page *page,1434static int read_from_bdev_async(struct zram *zram, struct page *page,
1429 u32 index, unsigned long blk_idx,1435 unsigned long index, unsigned long blk_idx,
1430 struct bio *parent)1436 struct bio *parent)
1431{1437{
1432 struct zram_rb_req *req;1438 struct zram_rb_req *req;
@@ -1476,8 +1482,8 @@ static void zram_sync_read(struct work_struct *w) · 43 unmodified lines
1476 * chained IO with parent IO in same context, it's a deadlock. To avoid that,1482 * chained IO with parent IO in same context, it's a deadlock. To avoid that,
1477 * use a worker thread context.1483 * use a worker thread context.
1478 */1484 */
1479static int read_from_bdev_sync(struct zram *zram, struct page *page, u32 index,1485static int read_from_bdev_sync(struct zram *zram, struct page *page,
1480 unsigned long blk_idx)1486 unsigned long index, unsigned long blk_idx)
1481{1487{
1482 struct zram_rb_req req;1488 struct zram_rb_req req;
1483 1489
@@ -1496,8 +1502,9 @@ static int read_from_bdev_sync(struct zram *zram, struct page *page, u32 index, · 12 unmodified lines
1496 return decompress_bdev_page(zram, page, index);1502 return decompress_bdev_page(zram, page, index);
1497}1503}
1498 1504
1499static int read_from_bdev(struct zram *zram, struct page *page, u32 index,1505static int read_from_bdev(struct zram *zram, struct page *page,
1500 unsigned long blk_idx, struct bio *parent)1506 unsigned long index, unsigned long blk_idx,
1507 struct bio *parent)
1501{1508{
1502 atomic64_inc(&zram->stats.bd_reads);1509 atomic64_inc(&zram->stats.bd_reads);
1503 if (!parent) {1510 if (!parent) {
@@ -1509,8 +1516,9 @@ static int read_from_bdev(struct zram *zram, struct page *page, u32 index, · 5 unmodified lines
1509}1516}
1510#else1517#else
1511static inline void reset_bdev(struct zram *zram) {};1518static inline void reset_bdev(struct zram *zram) {};
1512static int read_from_bdev(struct zram *zram, struct page *page, u32 index,1519static int read_from_bdev(struct zram *zram, struct page *page,
1513 unsigned long blk_idx, struct bio *parent)1520 unsigned long index, unsigned long blk_idx,
1521 struct bio *parent)
1514{1522{
1515 return -EIO;1523 return -EIO;
1516}1524}
@@ -1538,9 +1546,10 @@ static ssize_t read_block_state(struct file *file, char __user *buf, · 21 unmodified lines
1538 size_t count, loff_t *ppos)1546 size_t count, loff_t *ppos)
1539{1547{
1540 char *kbuf;1548 char *kbuf;
1541 ssize_t index, written = 0;1549 unsigned long index;
1550 ssize_t written = 0;
1542 struct zram *zram = file->private_data;1551 struct zram *zram = file->private_data;
1543 unsigned long nr_pages = zram->disksize >> PAGE_SHIFT;1552 unsigned long nr_pages;
1544 1553
1545 kbuf = kvmalloc(count, GFP_KERNEL);1554 kbuf = kvmalloc(count, GFP_KERNEL);
1546 if (!kbuf)1555 if (!kbuf)
@@ -1552,6 +1561,8 @@ static ssize_t read_block_state(struct file *file, char __user *buf, · 5 unmodified lines
1552 return -EINVAL;1561 return -EINVAL;
1553 }1562 }
1554 1563
1564 nr_pages = zram->disksize >> PAGE_SHIFT;
1565
1555 for (index = *ppos; index < nr_pages; index++) {1566 for (index = *ppos; index < nr_pages; index++) {
1556 int copied;1567 int copied;
1557 1568
@@ -1560,7 +1571,7 @@ static ssize_t read_block_state(struct file *file, char __user *buf, · 2 unmodified lines
1560 goto next;1571 goto next;
1561 1572
1562 copied = snprintf(kbuf + written, count,1573 copied = snprintf(kbuf + written, count,
1563 "%12zd %12u.%06d %c%c%c%c%c%c\n",1574 "%12lu %12u.%06d %c%c%c%c%c%c\n",
1564 index, zram->table[index].attr.ac_time, 0,1575 index, zram->table[index].attr.ac_time, 0,
1565 test_slot_flag(zram, index, ZRAM_SAME) ? 's' : '.',1576 test_slot_flag(zram, index, ZRAM_SAME) ? 's' : '.',
1566 test_slot_flag(zram, index, ZRAM_WB) ? 'w' : '.',1577 test_slot_flag(zram, index, ZRAM_WB) ? 'w' : '.',
@@ -1652,6 +1663,17 @@ static void comp_algorithm_set(struct zram *zram, u32 prio, const char *alg) · 85 unmodified lines
1652 zram->comp_algs[prio] = alg;1663 zram->comp_algs[prio] = alg;
1653}1664}
1654 1665
1666static void comp_params_reset(struct zram *zram, u32 prio)
1667{
1668 struct zcomp_params *params = &zram->params[prio];
1669
1670 vfree(params->dict);
1671 params->level = ZCOMP_PARAM_NOT_SET;
1672 params->deflate.winbits = ZCOMP_PARAM_NOT_SET;
1673 params->dict_sz = 0;
1674 params->dict = NULL;
1675}
1676
1655static int __comp_algorithm_store(struct zram *zram, u32 prio, const char *buf)1677static int __comp_algorithm_store(struct zram *zram, u32 prio, const char *buf)
1656{1678{
1657 const char *alg;1679 const char *alg;
@@ -1672,20 +1694,10 @@ static int __comp_algorithm_store(struct zram *zram, u32 prio, const char *buf) · 14 unmodified lines
1672 }1694 }
1673 1695
1674 comp_algorithm_set(zram, prio, alg);1696 comp_algorithm_set(zram, prio, alg);
1697 comp_params_reset(zram, prio);
1675 return 0;1698 return 0;
1676}1699}
1677 1700
1678static void comp_params_reset(struct zram *zram, u32 prio)
1679{
1680 struct zcomp_params *params = &zram->params[prio];
1681
1682 vfree(params->dict);
1683 params->level = ZCOMP_PARAM_NOT_SET;
1684 params->deflate.winbits = ZCOMP_PARAM_NOT_SET;
1685 params->dict_sz = 0;
1686 params->dict = NULL;
1687}
1688
1689static int comp_params_store(struct zram *zram, u32 prio, s32 level,1701static int comp_params_store(struct zram *zram, u32 prio, s32 level,
1690 const char *dict_path,1702 const char *dict_path,
1691 struct deflate_params *deflate_params)1703 struct deflate_params *deflate_params)
@@ -1700,8 +1712,16 @@ static int comp_params_store(struct zram *zram, u32 prio, s32 level, · 8 unmodified lines
1700 INT_MAX,1712 INT_MAX,
1701 NULL,1713 NULL,
1702 READING_POLICY);1714 READING_POLICY);
1703 if (sz < 0)1715 if (sz < 0) {
1716 pr_err("failed to load dictionary %s (err=%zd)\n",
1717 dict_path, sz);
1718 return sz;
1719 }
1720 if (sz == 0) {
1721 pr_err("failed to load dictionary %s (empty file)\n",
1722 dict_path);
1704 return -EINVAL;1723 return -EINVAL;
1724 }
1705 }1725 }
1706 1726
1707 zram->params[prio].dict_sz = sz;1727 zram->params[prio].dict_sz = sz;
@@ -1958,8 +1978,8 @@ static ssize_t debug_stat_show(struct device *dev, · 250 unmodified lines
1958 1978
1959static void zram_meta_free(struct zram *zram, u64 disksize)1979static void zram_meta_free(struct zram *zram, u64 disksize)
1960{1980{
1961 size_t num_pages = disksize >> PAGE_SHIFT;1981 unsigned long num_pages = disksize >> PAGE_SHIFT;
1962 size_t index;1982 unsigned long index;
1963 1983
1964 if (!zram->table)1984 if (!zram->table)
1965 return;1985 return;
@@ -1976,7 +1996,7 @@ static void zram_meta_free(struct zram *zram, u64 disksize) · 10 unmodified lines
1976 1996
1977static bool zram_meta_alloc(struct zram *zram, u64 disksize)1997static bool zram_meta_alloc(struct zram *zram, u64 disksize)
1978{1998{
1979 size_t num_pages;1999 unsigned long num_pages;
1980 2000
1981 num_pages = disksize >> PAGE_SHIFT;2001 num_pages = disksize >> PAGE_SHIFT;
1982 zram->table = vzalloc(array_size(num_pages, sizeof(*zram->table)));2002 zram->table = vzalloc(array_size(num_pages, sizeof(*zram->table)));
@@ -1999,7 +2019,7 @@ static bool zram_meta_alloc(struct zram *zram, u64 disksize) · 16 unmodified lines
1999 return true;2019 return true;
2000}2020}
2001 2021
2002static void slot_free(struct zram *zram, u32 index)2022static void slot_free(struct zram *zram, unsigned long index)
2003{2023{
2004 unsigned long handle;2024 unsigned long handle;
2005 2025
@@ -2053,7 +2073,7 @@ out: · 47 unmodified lines
2053}2073}
2054 2074
2055static int read_same_filled_page(struct zram *zram, struct page *page,2075static int read_same_filled_page(struct zram *zram, struct page *page,
2056 u32 index)2076 unsigned long index)
2057{2077{
2058 void *mem;2078 void *mem;
2059 2079
@@ -2064,7 +2084,7 @@ static int read_same_filled_page(struct zram *zram, struct page *page, · 4 unmodified lines
2064}2084}
2065 2085
2066static int read_incompressible_page(struct zram *zram, struct page *page,2086static int read_incompressible_page(struct zram *zram, struct page *page,
2067 u32 index)2087 unsigned long index)
2068{2088{
2069 unsigned long handle;2089 unsigned long handle;
2070 void *src, *dst;2090 void *src, *dst;
@@ -2079,7 +2099,8 @@ static int read_incompressible_page(struct zram *zram, struct page *page, · 8 unmodified lines
2079 return 0;2099 return 0;
2080}2100}
2081 2101
2082static int read_compressed_page(struct zram *zram, struct page *page, u32 index)2102static int read_compressed_page(struct zram *zram, struct page *page,
2103 unsigned long index)
2083{2104{
2084 struct zcomp_strm *zstrm;2105 struct zcomp_strm *zstrm;
2085 unsigned long handle;2106 unsigned long handle;
@@ -2104,7 +2125,8 @@ static int read_compressed_page(struct zram *zram, struct page *page, u32 index) · 18 unmodified lines
2104}2125}
2105 2126
2106#if defined CONFIG_ZRAM_WRITEBACK2127#if defined CONFIG_ZRAM_WRITEBACK
2107static int read_from_zspool_raw(struct zram *zram, struct page *page, u32 index)2128static int read_from_zspool_raw(struct zram *zram, struct page *page,
2129 unsigned long index)
2108{2130{
2109 struct zcomp_strm *zstrm;2131 struct zcomp_strm *zstrm;
2110 unsigned long handle;2132 unsigned long handle;
@@ -2136,7 +2158,8 @@ static int read_from_zspool_raw(struct zram *zram, struct page *page, u32 index) · 25 unmodified lines
2136 * Reads (decompresses if needed) a page from zspool (zsmalloc).2158 * Reads (decompresses if needed) a page from zspool (zsmalloc).
2137 * Corresponding ZRAM slot should be locked.2159 * Corresponding ZRAM slot should be locked.
2138 */2160 */
2139static int read_from_zspool(struct zram *zram, struct page *page, u32 index)2161static int read_from_zspool(struct zram *zram, struct page *page,
2162 unsigned long index)
2140{2163{
2141 if (test_slot_flag(zram, index, ZRAM_SAME) ||2164 if (test_slot_flag(zram, index, ZRAM_SAME) ||
2142 !get_slot_handle(zram, index))2165 !get_slot_handle(zram, index))
@@ -2148,8 +2171,8 @@ static int read_from_zspool(struct zram *zram, struct page *page, u32 index) · 5 unmodified lines
2148 return read_incompressible_page(zram, page, index);2171 return read_incompressible_page(zram, page, index);
2149}2172}
2150 2173
2151static int zram_read_page(struct zram *zram, struct page *page, u32 index,2174static int zram_read_page(struct zram *zram, struct page *page,
2152 struct bio *parent)2175 unsigned long index, struct bio *parent)
2153{2176{
2154 int ret;2177 int ret;
2155 2178
@@ -2171,7 +2194,7 @@ static int zram_read_page(struct zram *zram, struct page *page, u32 index, · 15 unmodified lines
2171 2194
2172 /* Should NEVER happen. Return bio error if it does. */2195 /* Should NEVER happen. Return bio error if it does. */
2173 if (WARN_ON(ret < 0))2196 if (WARN_ON(ret < 0))
2174 pr_err("Decompression failed! err=%d, page=%u\n", ret, index);2197 pr_err("Decompression failed! err=%d, page=%lu\n", ret, index);
2175 2198
2176 return ret;2199 return ret;
2177}2200}
@@ -2181,7 +2204,7 @@ static int zram_read_page(struct zram *zram, struct page *page, u32 index, · 3 unmodified lines
2181 * always expects a full page for the output.2204 * always expects a full page for the output.
2182 */2205 */
2183static int zram_bvec_read_partial(struct zram *zram, struct bio_vec *bvec,2206static int zram_bvec_read_partial(struct zram *zram, struct bio_vec *bvec,
2184 u32 index, int offset)2207 unsigned long index, int offset)
2185{2208{
2186 struct page *page = alloc_page(GFP_NOIO);2209 struct page *page = alloc_page(GFP_NOIO);
2187 int ret;2210 int ret;
@@ -2196,7 +2219,7 @@ static int zram_bvec_read_partial(struct zram *zram, struct bio_vec *bvec, · 8 unmodified lines
2196}2219}
2197 2220
2198static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,2221static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
2199 u32 index, int offset, struct bio *bio)2222 unsigned long index, int offset, struct bio *bio)
2200{2223{
2201 if (is_partial_io(bvec))2224 if (is_partial_io(bvec))
2202 return zram_bvec_read_partial(zram, bvec, index, offset);2225 return zram_bvec_read_partial(zram, bvec, index, offset);
@@ -2204,7 +2227,7 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, · 1 unmodified line
2204}2227}
2205 2228
2206static int write_same_filled_page(struct zram *zram, unsigned long fill,2229static int write_same_filled_page(struct zram *zram, unsigned long fill,
2207 u32 index)2230 unsigned long index)
2208{2231{
2209 slot_lock(zram, index);2232 slot_lock(zram, index);
2210 slot_free(zram, index);2233 slot_free(zram, index);
@@ -2219,7 +2242,7 @@ static int write_same_filled_page(struct zram *zram, unsigned long fill, · 8 unmodified lines
2219}2242}
2220 2243
2221static int write_incompressible_page(struct zram *zram, struct page *page,2244static int write_incompressible_page(struct zram *zram, struct page *page,
2222 u32 index)2245 unsigned long index)
2223{2246{
2224 unsigned long handle;2247 unsigned long handle;
2225 void *src;2248 void *src;
@@ -2259,7 +2282,8 @@ static int write_incompressible_page(struct zram *zram, struct page *page, · 33 unmodified lines
2259 return 0;2282 return 0;
2260}2283}
2261 2284
2262static int zram_write_page(struct zram *zram, struct page *page, u32 index)2285static int zram_write_page(struct zram *zram, struct page *page,
2286 unsigned long index)
2263{2287{
2264 int ret = 0;2288 int ret = 0;
2265 unsigned long handle;2289 unsigned long handle;
@@ -2326,7 +2350,7 @@ static int zram_write_page(struct zram *zram, struct page *page, u32 index) · 60 unmodified lines
2326 * This is a partial IO. Read the full page before writing the changes.2350 * This is a partial IO. Read the full page before writing the changes.
2327 */2351 */
2328static int zram_bvec_write_partial(struct zram *zram, struct bio_vec *bvec,2352static int zram_bvec_write_partial(struct zram *zram, struct bio_vec *bvec,
2329 u32 index, int offset)2353 unsigned long index, int offset)
2330{2354{
2331 struct page *page = alloc_page(GFP_NOIO);2355 struct page *page = alloc_page(GFP_NOIO);
2332 int ret;2356 int ret;
@@ -2344,7 +2368,7 @@ static int zram_bvec_write_partial(struct zram *zram, struct bio_vec *bvec, · 11 unmodified lines
2344}2368}
2345 2369
2346static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec,2370static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec,
2347 u32 index, int offset)2371 unsigned long index, int offset)
2348{2372{
2349 if (is_partial_io(bvec))2373 if (is_partial_io(bvec))
2350 return zram_bvec_write_partial(zram, bvec, index, offset);2374 return zram_bvec_write_partial(zram, bvec, index, offset);
@@ -2412,8 +2436,9 @@ next: · 61 unmodified lines
2412 *2436 *
2413 * Corresponding ZRAM slot should be locked.2437 * Corresponding ZRAM slot should be locked.
2414 */2438 */
2415static int recompress_slot(struct zram *zram, u32 index, struct page *page,2439static int recompress_slot(struct zram *zram, unsigned long index,
2416 u64 *num_recomp_pages, u32 threshold, u32 prio)2440 struct page *page, u64 *num_recomp_pages,
2441 u32 threshold, u32 prio)
2417{2442{
2418 struct zcomp_strm *zstrm = NULL;2443 struct zcomp_strm *zstrm = NULL;
2419 unsigned long handle_old;2444 unsigned long handle_old;
@@ -2665,7 +2690,7 @@ out: · 245 unmodified lines
2665static void zram_bio_discard(struct zram *zram, struct bio *bio)2690static void zram_bio_discard(struct zram *zram, struct bio *bio)
2666{2691{
2667 size_t n = bio->bi_iter.bi_size;2692 size_t n = bio->bi_iter.bi_size;
2668 u32 index = bio->bi_iter.bi_sector >> SECTORS_PER_PAGE_SHIFT;2693 unsigned long index = bio->bi_iter.bi_sector >> SECTORS_PER_PAGE_SHIFT;
2669 u32 offset = (bio->bi_iter.bi_sector & (SECTORS_PER_PAGE - 1)) <<2694 u32 offset = (bio->bi_iter.bi_sector & (SECTORS_PER_PAGE - 1)) <<
2670 SECTOR_SHIFT;2695 SECTOR_SHIFT;
2671 2696
@@ -2706,7 +2731,7 @@ static void zram_bio_read(struct zram *zram, struct bio *bio) · 34 unmodified lines
2706 struct bvec_iter iter = bio->bi_iter;2731 struct bvec_iter iter = bio->bi_iter;
2707 2732
2708 do {2733 do {
2709 u32 index = iter.bi_sector >> SECTORS_PER_PAGE_SHIFT;2734 unsigned long index = iter.bi_sector >> SECTORS_PER_PAGE_SHIFT;
2710 u32 offset = (iter.bi_sector & (SECTORS_PER_PAGE - 1)) <<2735 u32 offset = (iter.bi_sector & (SECTORS_PER_PAGE - 1)) <<
2711 SECTOR_SHIFT;2736 SECTOR_SHIFT;
2712 struct bio_vec bv = bio_iter_iovec(bio, iter);2737 struct bio_vec bv = bio_iter_iovec(bio, iter);
@@ -2737,7 +2762,7 @@ static void zram_bio_write(struct zram *zram, struct bio *bio) · 24 unmodified lines
2737 struct bvec_iter iter = bio->bi_iter;2762 struct bvec_iter iter = bio->bi_iter;
2738 2763
2739 do {2764 do {
2740 u32 index = iter.bi_sector >> SECTORS_PER_PAGE_SHIFT;2765 unsigned long index = iter.bi_sector >> SECTORS_PER_PAGE_SHIFT;
2741 u32 offset = (iter.bi_sector & (SECTORS_PER_PAGE - 1)) <<2766 u32 offset = (iter.bi_sector & (SECTORS_PER_PAGE - 1)) <<
2742 SECTOR_SHIFT;2767 SECTOR_SHIFT;
2743 struct bio_vec bv = bio_iter_iovec(bio, iter);2768 struct bio_vec bv = bio_iter_iovec(bio, iter);
@@ -2828,6 +2853,7 @@ static void zram_destroy_comps(struct zram *zram) · 84 unmodified lines
2828 zram->comp_algs[prio] = NULL;2853 zram->comp_algs[prio] = NULL;
2829 2854
2830 zram_comp_params_reset(zram);2855 zram_comp_params_reset(zram);
2856 comp_algorithm_set(zram, ZRAM_PRIMARY_COMP, default_compressor);
2831}2857}
2832 2858
2833static void zram_reset_device(struct zram *zram)2859static void zram_reset_device(struct zram *zram)
@@ -2845,13 +2871,12 @@ static void zram_reset_device(struct zram *zram) · 11 unmodified lines
2845 zram_destroy_comps(zram);2871 zram_destroy_comps(zram);
2846 memset(&zram->stats, 0, sizeof(zram->stats));2872 memset(&zram->stats, 0, sizeof(zram->stats));
2847 reset_bdev(zram);2873 reset_bdev(zram);
2848
2849 comp_algorithm_set(zram, ZRAM_PRIMARY_COMP, default_compressor);
2850}2874}
2851 2875
2852static ssize_t disksize_store(struct device *dev, struct device_attribute *attr,2876static ssize_t disksize_store(struct device *dev, struct device_attribute *attr,
2853 const char *buf, size_t len)2877 const char *buf, size_t len)
2854{2878{
2879 unsigned long num_pages;
2855 u64 disksize;2880 u64 disksize;
2856 struct zcomp *comp;2881 struct zcomp *comp;
2857 struct zram *zram = dev_to_zram(dev);2882 struct zram *zram = dev_to_zram(dev);
@@ -2869,6 +2894,11 @@ static ssize_t disksize_store(struct device *dev, struct device_attribute *attr, · 11 unmodified lines
2869 }2894 }
2870 2895
2871 disksize = PAGE_ALIGN(disksize);2896 disksize = PAGE_ALIGN(disksize);
2897 num_pages = disksize >> PAGE_SHIFT;
2898 /* Slots are addressed by an unsigned long index */
2899 if (!num_pages || ((u64)num_pages << PAGE_SHIFT) != disksize)
2900 return -EINVAL;
2901
2872 if (!zram_meta_alloc(zram, disksize))2902 if (!zram_meta_alloc(zram, disksize))
2873 return -ENOMEM;2903 return -ENOMEM;
2874 2904
drivers/block/zram/zram_drv.h+14−0
@@ -15,6 +15,7 @@ · 14 unmodified lines
15#ifndef _ZRAM_DRV_H_15#ifndef _ZRAM_DRV_H_
16#define _ZRAM_DRV_H_16#define _ZRAM_DRV_H_
17 17
18#include <asm/byteorder.h>
18#include <linux/rwsem.h>19#include <linux/rwsem.h>
19#include <linux/zsmalloc.h>20#include <linux/zsmalloc.h>
20 21
@@ -57,6 +58,19 @@ enum zram_pageflags { · 36 unmodified lines
57 __NR_ZRAM_PAGEFLAGS,58 __NR_ZRAM_PAGEFLAGS,
58};59};
59 60
61/*
62 * The slot lock is a bit-wait lock on the whole __lock word, while
63 * flags and ac_time alias that word as two u32s. The lock bit must
64 * land in the slot that ZRAM_ENTRY_LOCK reserves in attr.flags; on
65 * 64-bit big-endian the flags word maps to the upper half of __lock,
66 * so the bit position has to be shifted up.
67 */
68#if defined(CONFIG_64BIT) && defined(__BIG_ENDIAN)
69#define ZRAM_ENTRY_LOCK_BIT (ZRAM_ENTRY_LOCK + 32)
70#else
71#define ZRAM_ENTRY_LOCK_BIT ZRAM_ENTRY_LOCK
72#endif
73
60/*74/*
61 * Allocated for each disk page. We use bit-lock (ZRAM_ENTRY_LOCK bit75 * Allocated for each disk page. We use bit-lock (ZRAM_ENTRY_LOCK bit
62 * of flags) to save memory. There can be plenty of entries and standard76 * of flags) to save memory. There can be plenty of entries and standard
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c+2−2
@@ -377,9 +377,9 @@ static int amdgpu_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_str · 376 unmodified lines
377 /* Workaround for Thunk bug creating PROT_NONE,MAP_PRIVATE mappings377 /* Workaround for Thunk bug creating PROT_NONE,MAP_PRIVATE mappings
378 * for debugger access to invisible VRAM. Should have used MAP_SHARED378 * for debugger access to invisible VRAM. Should have used MAP_SHARED
379 * instead. Clearing VM_MAYWRITE prevents the mapping from ever379 * instead. Clearing VM_MAYWRITE prevents the mapping from ever
380 * becoming writable and makes is_cow_mapping(vm_flags) false.380 * becoming writable and makes vma_is_cow_mapping(vma) false.
381 */381 */
382 if (is_cow_mapping(vma->vm_flags) &&382 if (vma_is_cow_mapping(vma) &&
383 !(vma->vm_flags & VM_ACCESS_FLAGS))383 !(vma->vm_flags & VM_ACCESS_FLAGS))
384 vm_flags_clear(vma, VM_MAYWRITE);384 vm_flags_clear(vma, VM_MAYWRITE);
385 385
drivers/gpu/drm/drm_gem_shmem_helper.c+1−1
@@ -771,7 +771,7 @@ int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct · 770 unmodified lines
771 return ret;771 return ret;
772 }772 }
773 773
774 if (is_cow_mapping(vma->vm_flags))774 if (vma_is_cow_mapping(vma))
775 return -EINVAL;775 return -EINVAL;
776 776
777 dma_resv_lock(shmem->base.resv, NULL);777 dma_resv_lock(shmem->base.resv, NULL);
drivers/gpu/drm/i915/gem/i915_gem_shmem.c+1−1
@@ -325,7 +325,7 @@ void __shmem_writeback(size_t size, struct address_space *mapping) · 324 unmodified lines
325 if (folio_mapped(folio))325 if (folio_mapped(folio))
326 folio_redirty_for_writepage(&wbc, folio);326 folio_redirty_for_writepage(&wbc, folio);
327 else327 else
328 error = shmem_writeout(folio, NULL, NULL);328 error = shmem_write_folio(folio);
329 }329 }
330}330}
331 331
drivers/gpu/drm/panthor/panthor_gem.c+1−1
@@ -761,7 +761,7 @@ static int panthor_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *v · 760 unmodified lines
761 return ret;761 return ret;
762 }762 }
763 763
764 if (is_cow_mapping(vma->vm_flags))764 if (vma_is_cow_mapping(vma))
765 return -EINVAL;765 return -EINVAL;
766 766
767 if (!refcount_inc_not_zero(&bo->cmap.mmap_count)) {767 if (!refcount_inc_not_zero(&bo->cmap.mmap_count)) {
drivers/gpu/drm/ttm/ttm_backup.c+1−1
@@ -160,7 +160,7 @@ ttm_backup_backup_folio(struct file *backup, struct folio *folio, · 159 unmodified lines
160 if (writeback && !folio_mapped(to_folio) &&160 if (writeback && !folio_mapped(to_folio) &&
161 folio_clear_dirty_for_io(to_folio)) {161 folio_clear_dirty_for_io(to_folio)) {
162 folio_set_reclaim(to_folio);162 folio_set_reclaim(to_folio);
163 ret = shmem_writeout(to_folio, NULL, NULL);163 ret = shmem_write_folio(to_folio);
164 if (!folio_test_writeback(to_folio))164 if (!folio_test_writeback(to_folio))
165 folio_clear_reclaim(to_folio);165 folio_clear_reclaim(to_folio);
166 if (ret == AOP_WRITEPAGE_ACTIVATE)166 if (ret == AOP_WRITEPAGE_ACTIVATE)
drivers/gpu/drm/ttm/ttm_bo_vm.c+1−1
@@ -489,7 +489,7 @@ static const struct vm_operations_struct ttm_bo_vm_ops = { · 488 unmodified lines
489int ttm_bo_mmap_obj(struct vm_area_struct *vma, struct ttm_buffer_object *bo)489int ttm_bo_mmap_obj(struct vm_area_struct *vma, struct ttm_buffer_object *bo)
490{490{
491 /* Enforce no COW since would have really strange behavior with it. */491 /* Enforce no COW since would have really strange behavior with it. */
492 if (is_cow_mapping(vma->vm_flags))492 if (vma_is_cow_mapping(vma))
493 return -EINVAL;493 return -EINVAL;
494 494
495 drm_gem_object_get(&bo->base);495 drm_gem_object_get(&bo->base);
drivers/gpu/drm/xe/xe_device.c+1−1
@@ -331,7 +331,7 @@ static int xe_pci_barrier_mmap(struct file *filp, · 330 unmodified lines
331 if (vma->vm_end - vma->vm_start > SZ_4K)331 if (vma->vm_end - vma->vm_start > SZ_4K)
332 return -EINVAL;332 return -EINVAL;
333 333
334 if (is_cow_mapping(vma->vm_flags))334 if (vma_is_cow_mapping(vma))
335 return -EINVAL;335 return -EINVAL;
336 336
337 if (vma->vm_flags & (VM_READ | VM_EXEC))337 if (vma->vm_flags & (VM_READ | VM_EXEC))
fs/nfs/direct.c+0−20
@@ -145,26 +145,6 @@ static void nfs_direct_file_adjust_size_locked(struct inode *inode, · 144 unmodified lines
145 }145 }
146}146}
147 147
148/**
149 * nfs_swap_rw - NFS address space operation for swap I/O
150 * @iocb: target I/O control block
151 * @iter: I/O buffer
152 *
153 * Perform IO to the swap-file. This is much like direct IO.
154 */
155int nfs_swap_rw(struct kiocb *iocb, struct iov_iter *iter)
156{
157 ssize_t ret;
158
159 if (iov_iter_rw(iter) == READ)
160 ret = nfs_file_direct_read(iocb, iter, true);
161 else
162 ret = nfs_file_direct_write(iocb, iter, true);
163 if (ret < 0)
164 return ret;
165 return 0;
166}
167
168static void nfs_direct_release_pages(struct page **pages, unsigned int npages)148static void nfs_direct_release_pages(struct page **pages, unsigned int npages)
169{149{
170 unsigned int i;150 unsigned int i;
fs/nfs/file.c+38−6
@@ -29,9 +29,8 @@ · 28 unmodified lines
29#include <linux/pagemap.h>29#include <linux/pagemap.h>
30#include <linux/gfp.h>30#include <linux/gfp.h>
31#include <linux/rmap.h>31#include <linux/rmap.h>
32#include <linux/swap.h>
33#include <linux/compaction.h>32#include <linux/compaction.h>
34 33#include <linux/swap_ops.h>
35#include <linux/uaccess.h>34#include <linux/uaccess.h>
36#include <linux/filelock.h>35#include <linux/filelock.h>
37 36
@@ -575,6 +574,38 @@ static int nfs_launder_folio(struct folio *folio) · 537 unmodified lines
575 return ret;574 return ret;
576}575}
577 576
577#ifdef CONFIG_SWAP
578static void nfs_swap_submit_write(struct swap_io_ctx *ctx)
579{
580 struct swap_iocb *sio = ctx->sio;
581 struct iov_iter iter;
582 int ret;
583
584 swap_fs_prepare_rw(ctx, WRITE, &iter);
585 ret = nfs_file_direct_write(&sio->iocb, &iter, true);
586 if (ret != -EIOCBQUEUED)
587 sio->iocb.ki_complete(&sio->iocb, ret);
588}
589
590static void nfs_swap_submit_read(struct swap_io_ctx *ctx)
591{
592 struct swap_iocb *sio = ctx->sio;
593 struct iov_iter iter;
594 int ret;
595
596 swap_fs_prepare_rw(ctx, READ, &iter);
597 ret = nfs_file_direct_read(&sio->iocb, &iter, true);
598 if (ret != -EIOCBQUEUED)
599 sio->iocb.ki_complete(&sio->iocb, ret);
600}
601
602static const struct swap_ops nfs_swap_ops = {
603 .flags = SWAP_OPS_F_REQUIRE_NOFS,
604 .submit_write = nfs_swap_submit_write,
605 .submit_read = nfs_swap_submit_read,
606 .can_merge = swap_fs_can_merge,
607};
608
578static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file,609static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file,
579 sector_t *span)610 sector_t *span)
580{611{
@@ -597,7 +628,7 @@ static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file, · 16 unmodified lines
597 ret = rpc_clnt_swap_activate(clnt);628 ret = rpc_clnt_swap_activate(clnt);
598 if (ret)629 if (ret)
599 return ret;630 return ret;
600 ret = add_swap_extent(sis, 0, sis->max, 0);631 ret = swap_fs_activate(sis, &nfs_swap_ops);
601 if (ret < 0) {632 if (ret < 0) {
602 rpc_clnt_swap_deactivate(clnt);633 rpc_clnt_swap_deactivate(clnt);
603 return ret;634 return ret;
@@ -607,8 +638,6 @@ static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file, · 3 unmodified lines
607 638
608 if (cl->rpc_ops->enable_swap)639 if (cl->rpc_ops->enable_swap)
609 cl->rpc_ops->enable_swap(inode);640 cl->rpc_ops->enable_swap(inode);
610
611 sis->flags |= SWP_FS_OPS;
612 return ret;641 return ret;
613}642}
614 643
@@ -622,6 +651,10 @@ static void nfs_swap_deactivate(struct file *file) · 7 unmodified lines
622 if (cl->rpc_ops->disable_swap)651 if (cl->rpc_ops->disable_swap)
623 cl->rpc_ops->disable_swap(file_inode(file));652 cl->rpc_ops->disable_swap(file_inode(file));
624}653}
654#else
655#define nfs_swap_activate NULL
656#define nfs_swap_deactivate NULL
657#endif /* CONFIG_SWAP */
625 658
626const struct address_space_operations nfs_file_aops = {659const struct address_space_operations nfs_file_aops = {
627 .read_folio = nfs_read_folio,660 .read_folio = nfs_read_folio,
@@ -638,7 +671,6 @@ const struct address_space_operations nfs_file_aops = { · 10 unmodified lines
638 .error_remove_folio = generic_error_remove_folio,671 .error_remove_folio = generic_error_remove_folio,
639 .swap_activate = nfs_swap_activate,672 .swap_activate = nfs_swap_activate,
640 .swap_deactivate = nfs_swap_deactivate,673 .swap_deactivate = nfs_swap_deactivate,
641 .swap_rw = nfs_swap_rw,
642};674};
643 675
644/*676/*
fs/proc/task_mmu.c+1−1
@@ -1693,7 +1693,7 @@ static inline bool pte_is_pinned(struct vm_area_struct *vma, unsigned long addr, · 1692 unmodified lines
1693 1693
1694 if (!pte_write(pte))1694 if (!pte_write(pte))
1695 return false;1695 return false;
1696 if (!is_cow_mapping(vma->vm_flags))1696 if (!vma_is_cow_mapping(vma))
1697 return false;1697 return false;
1698 if (likely(!mm_flags_test(MMF_HAS_PINNED, vma->vm_mm)))1698 if (likely(!mm_flags_test(MMF_HAS_PINNED, vma->vm_mm)))
1699 return false;1699 return false;
fs/ramfs/file-nommu.c+3−0
@@ -69,6 +69,9 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) · 68 unmodified lines
69 gfp_t gfp = mapping_gfp_mask(inode->i_mapping);69 gfp_t gfp = mapping_gfp_mask(inode->i_mapping);
70 70
71 /* make various checks */71 /* make various checks */
72 if (!newsize)
73 return 0;
74
72 order = get_order(newsize);75 order = get_order(newsize);
73 if (unlikely(order > MAX_PAGE_ORDER))76 if (unlikely(order > MAX_PAGE_ORDER))
74 return -EFBIG;77 return -EFBIG;
fs/smb/client/file.c+39−26
@@ -20,7 +20,7 @@ · 19 unmodified lines
20#include <linux/delay.h>20#include <linux/delay.h>
21#include <linux/mount.h>21#include <linux/mount.h>
22#include <linux/slab.h>22#include <linux/slab.h>
23#include <linux/swap.h>23#include <linux/swap_ops.h>
24#include <linux/mm.h>24#include <linux/mm.h>
25#include <asm/div64.h>25#include <asm/div64.h>
26#include "cifsfs.h"26#include "cifsfs.h"
@@ -3406,6 +3406,38 @@ out: · 3379 unmodified lines
3406 cifs_done_oplock_break(cinode);3406 cifs_done_oplock_break(cinode);
3407}3407}
3408 3408
3409#ifdef CONFIG_SWAP
3410static void cifs_swap_submit_write(struct swap_io_ctx *ctx)
3411{
3412 struct swap_iocb *sio = ctx->sio;
3413 struct iov_iter iter;
3414 int ret;
3415
3416 swap_fs_prepare_rw(ctx, WRITE, &iter);
3417 ret = netfs_unbuffered_write_iter_locked(&sio->iocb, &iter, NULL);
3418 if (ret != -EIOCBQUEUED)
3419 sio->iocb.ki_complete(&sio->iocb, ret);
3420}
3421
3422static void cifs_swap_submit_read(struct swap_io_ctx *ctx)
3423{
3424 struct swap_iocb *sio = ctx->sio;
3425 struct iov_iter iter;
3426 int ret;
3427
3428 swap_fs_prepare_rw(ctx, READ, &iter);
3429 ret = netfs_unbuffered_read_iter_locked(&sio->iocb, &iter);
3430 if (ret != -EIOCBQUEUED)
3431 sio->iocb.ki_complete(&sio->iocb, ret);
3432}
3433
3434static const struct swap_ops cifs_swap_ops = {
3435 .flags = SWAP_OPS_F_REQUIRE_NOFS,
3436 .submit_write = cifs_swap_submit_write,
3437 .submit_read = cifs_swap_submit_read,
3438 .can_merge = swap_fs_can_merge,
3439};
3440
3409static int cifs_swap_activate(struct swap_info_struct *sis,3441static int cifs_swap_activate(struct swap_info_struct *sis,
3410 struct file *swap_file, sector_t *span)3442 struct file *swap_file, sector_t *span)
3411{3443{
@@ -3416,7 +3448,7 @@ static int cifs_swap_activate(struct swap_info_struct *sis, · 4 unmodified lines
3416 3448
3417 cifs_dbg(FYI, "swap activate\n");3449 cifs_dbg(FYI, "swap activate\n");
3418 3450
3419 if (!swap_file->f_mapping->a_ops->swap_rw)3451 if (swap_file->f_mapping->a_ops != &cifs_addr_ops)
3420 /* Cannot support swap */3452 /* Cannot support swap */
3421 return -EINVAL;3453 return -EINVAL;
3422 3454
@@ -3447,9 +3479,7 @@ static int cifs_swap_activate(struct swap_info_struct *sis, · 24 unmodified lines
3447 * but we could add call to grab a byte range lock to prevent others3479 * but we could add call to grab a byte range lock to prevent others
3448 * from reading or writing the file3480 * from reading or writing the file
3449 */3481 */
3450 3482 return swap_fs_activate(sis, &cifs_swap_ops);
3451 sis->flags |= SWP_FS_OPS;
3452 return add_swap_extent(sis, 0, sis->max, 0);
3453}3483}
3454 3484
3455static void cifs_swap_deactivate(struct file *file)3485static void cifs_swap_deactivate(struct file *file)
@@ -3465,26 +3495,10 @@ static void cifs_swap_deactivate(struct file *file) · 9 unmodified lines
3465 3495
3466 /* do we need to unpin (or unlock) the file */3496 /* do we need to unpin (or unlock) the file */
3467}3497}
3468 3498#else
3469/**3499#define cifs_swap_activate NULL
3470 * cifs_swap_rw - SMB3 address space operation for swap I/O3500#define cifs_swap_deactivate NULL
3471 * @iocb: target I/O control block3501#endif /* CONFIG_SWAP */
3472 * @iter: I/O buffer
3473 *
3474 * Perform IO to the swap-file. This is much like direct IO.
3475 */
3476static int cifs_swap_rw(struct kiocb *iocb, struct iov_iter *iter)
3477{
3478 ssize_t ret;
3479
3480 if (iov_iter_rw(iter) == READ)
3481 ret = netfs_unbuffered_read_iter_locked(iocb, iter);
3482 else
3483 ret = netfs_unbuffered_write_iter_locked(iocb, iter, NULL);
3484 if (ret < 0)
3485 return ret;
3486 return 0;
3487}
3488 3502
3489const struct address_space_operations cifs_addr_ops = {3503const struct address_space_operations cifs_addr_ops = {
3490 .read_folio = netfs_read_folio,3504 .read_folio = netfs_read_folio,
@@ -3501,7 +3515,6 @@ const struct address_space_operations cifs_addr_ops = { · 10 unmodified lines
3501 */3515 */
3502 .swap_activate = cifs_swap_activate,3516 .swap_activate = cifs_swap_activate,
3503 .swap_deactivate = cifs_swap_deactivate,3517 .swap_deactivate = cifs_swap_deactivate,
3504 .swap_rw = cifs_swap_rw,
3505};3518};
3506 3519
3507/*3520/*
include/linux/codetag.h+2−0
@@ -77,6 +77,8 @@ struct codetag_iterator { · 76 unmodified lines
77void codetag_lock_module_list(struct codetag_type *cttype);77void codetag_lock_module_list(struct codetag_type *cttype);
78bool codetag_trylock_module_list(struct codetag_type *cttype);78bool codetag_trylock_module_list(struct codetag_type *cttype);
79void codetag_unlock_module_list(struct codetag_type *cttype);79void codetag_unlock_module_list(struct codetag_type *cttype);
80unsigned long codetag_get_content_id(struct codetag_type *cttype);
81unsigned int codetag_get_count(struct codetag_type *cttype);
80struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype);82struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype);
81struct codetag *codetag_next_ct(struct codetag_iterator *iter);83struct codetag *codetag_next_ct(struct codetag_iterator *iter);
82 84
include/linux/execmem.h+1−1
@@ -89,7 +89,7 @@ static inline int execmem_restore_rox(void *ptr, size_t size) { return 0; } · 88 unmodified lines
89 * @end: address space end (inclusive)89 * @end: address space end (inclusive)
90 * @fallback_start: start of the secondary address space range for fallback90 * @fallback_start: start of the secondary address space range for fallback
91 * allocations on architectures that require it91 * allocations on architectures that require it
92 * @fallback_end: start of the secondary address space (inclusive)92 * @fallback_end: end of the secondary address space (inclusive)
93 * @pgprot: permissions for memory in this address space93 * @pgprot: permissions for memory in this address space
94 * @alignment: alignment required for text allocations94 * @alignment: alignment required for text allocations
95 * @flags: options for memory allocations for this range95 * @flags: options for memory allocations for this range
include/linux/fs.h+0−1
@@ -438,7 +438,6 @@ struct address_space_operations { · 437 unmodified lines
438 int (*swap_activate)(struct swap_info_struct *sis, struct file *file,438 int (*swap_activate)(struct swap_info_struct *sis, struct file *file,
439 sector_t *span);439 sector_t *span);
440 void (*swap_deactivate)(struct file *file);440 void (*swap_deactivate)(struct file *file);
441 int (*swap_rw)(struct kiocb *iocb, struct iov_iter *iter);
442};441};
443 442
444extern const struct address_space_operations empty_aops;443extern const struct address_space_operations empty_aops;
include/linux/lockdep.h+3−0
@@ -273,6 +273,9 @@ extern struct pin_cookie lock_pin_lock(struct lockdep_map *lock); · 272 unmodified lines
273extern void lock_repin_lock(struct lockdep_map *lock, struct pin_cookie);273extern void lock_repin_lock(struct lockdep_map *lock, struct pin_cookie);
274extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);274extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
275 275
276extern u32 lock_sequence(struct lockdep_map *lock);
277#define lockdep_sequence(lock) lock_sequence(&(lock)->dep_map)
278
276#define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0)279#define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0)
277 280
278#define lockdep_assert(cond) \281#define lockdep_assert(cond) \
include/linux/lockdep_types.h+2−1
@@ -253,7 +253,8 @@ struct held_lock { · 252 unmodified lines
253 unsigned int hardirqs_off:1;253 unsigned int hardirqs_off:1;
254 unsigned int sync:1;254 unsigned int sync:1;
255 unsigned int references:11; /* 32 bits */255 unsigned int references:11; /* 32 bits */
256 unsigned int pin_count;256 unsigned int pin_count:24;
257 unsigned int seq_count:8;
257};258};
258 259
259#else /* !CONFIG_LOCKDEP */260#else /* !CONFIG_LOCKDEP */
include/linux/maple_tree.h+9−7
@@ -11,7 +11,6 @@ · 10 unmodified lines
11#include <linux/kernel.h>11#include <linux/kernel.h>
12#include <linux/rcupdate.h>12#include <linux/rcupdate.h>
13#include <linux/spinlock.h>13#include <linux/spinlock.h>
14/* #define CONFIG_MAPLE_RCU_DISABLED */
15 14
16/*15/*
17 * Allocated nodes are mutable until they have been inserted into the tree,16 * Allocated nodes are mutable until they have been inserted into the tree,
@@ -29,13 +28,11 @@ · 11 unmodified lines
29#define MAPLE_NODE_SLOTS 31 /* 256 bytes including ->parent */28#define MAPLE_NODE_SLOTS 31 /* 256 bytes including ->parent */
30#define MAPLE_RANGE64_SLOTS 16 /* 256 bytes */29#define MAPLE_RANGE64_SLOTS 16 /* 256 bytes */
31#define MAPLE_ARANGE64_SLOTS 10 /* 240 bytes */30#define MAPLE_ARANGE64_SLOTS 10 /* 240 bytes */
32#define MAPLE_ALLOC_SLOTS (MAPLE_NODE_SLOTS - 1)
33#else31#else
34/* 32bit sizes */32/* 32bit sizes */
35#define MAPLE_NODE_SLOTS 63 /* 256 bytes including ->parent */33#define MAPLE_NODE_SLOTS 63 /* 256 bytes including ->parent */
36#define MAPLE_RANGE64_SLOTS 32 /* 256 bytes */34#define MAPLE_RANGE64_SLOTS 32 /* 256 bytes */
37#define MAPLE_ARANGE64_SLOTS 21 /* 240 bytes */35#define MAPLE_ARANGE64_SLOTS 21 /* 240 bytes */
38#define MAPLE_ALLOC_SLOTS (MAPLE_NODE_SLOTS - 2)
39#endif /* defined(CONFIG_64BIT) || defined(BUILD_VDSO32_64) */36#endif /* defined(CONFIG_64BIT) || defined(BUILD_VDSO32_64) */
40 37
41#define MAPLE_NODE_MASK 255UL38#define MAPLE_NODE_MASK 255UL
@@ -485,6 +482,12 @@ struct ma_state { · 443 unmodified lines
485 unsigned char mas_flags;482 unsigned char mas_flags;
486 unsigned char end; /* The end of the node */483 unsigned char end; /* The end of the node */
487 enum store_type store_type; /* The type of store needed for this operation */484 enum store_type store_type; /* The type of store needed for this operation */
485#ifdef CONFIG_LOCKDEP
486 u32 ld_seq;
487#ifdef CONFIG_RCU_STRICT_GRACE_PERIOD
488 unsigned long rcu_gp;
489#endif /* CONFIG_RCU_STRICT_GRACE_PERIOD */
490#endif /* CONFIG_LOCKDEP */
488};491};
489 492
490struct ma_wr_state {493struct ma_wr_state {
@@ -567,12 +570,14 @@ int mas_alloc_cyclic(struct ma_state *mas, unsigned long *startp, · 76 unmodified lines
567 unsigned long *next, gfp_t gfp);570 unsigned long *next, gfp_t gfp);
568 571
569bool mas_nomem(struct ma_state *mas, gfp_t gfp);572bool mas_nomem(struct ma_state *mas, gfp_t gfp);
573bool mas_nomem_nofail(struct ma_state *mas, unsigned long index,
574 unsigned long last);
570void mas_pause(struct ma_state *mas);575void mas_pause(struct ma_state *mas);
571void maple_tree_init(void);576void maple_tree_init(void);
572void mas_destroy(struct ma_state *mas);577void mas_destroy(struct ma_state *mas);
573 578
574void *mas_prev(struct ma_state *mas, unsigned long min);579void *mas_prev(struct ma_state *mas, unsigned long min);
575void *mas_prev_range(struct ma_state *mas, unsigned long max);580void *mas_prev_range(struct ma_state *mas, unsigned long min);
576void *mas_next(struct ma_state *mas, unsigned long max);581void *mas_next(struct ma_state *mas, unsigned long max);
577void *mas_next_range(struct ma_state *mas, unsigned long max);582void *mas_next_range(struct ma_state *mas, unsigned long max);
578 583
@@ -864,9 +869,6 @@ static inline void mt_init(struct maple_tree *mt) · 285 unmodified lines
864 869
865static inline bool mt_in_rcu(struct maple_tree *mt)870static inline bool mt_in_rcu(struct maple_tree *mt)
866{871{
867#ifdef CONFIG_MAPLE_RCU_DISABLED
868 return false;
869#endif
870 return mt->ma_flags & MT_FLAGS_USE_RCU;872 return mt->ma_flags & MT_FLAGS_USE_RCU;
871}873}
872 874
include/linux/memcontrol.h+17−4
@@ -239,8 +239,6 @@ struct mem_cgroup { · 238 unmodified lines
239 */239 */
240 bool oom_group;240 bool oom_group;
241 241
242 int swappiness;
243
244 /* memory.events and memory.events.local */242 /* memory.events and memory.events.local */
245 struct cgroup_file events_file;243 struct cgroup_file events_file;
246 struct cgroup_file events_local_file;244 struct cgroup_file events_local_file;
@@ -270,10 +268,15 @@ struct mem_cgroup { · 23 unmodified lines
270#endif268#endif
271 int kmemcg_id;269 int kmemcg_id;
272 270
273 struct memcg_vmstats_percpu __percpu *vmstats_percpu;
274
275#ifdef CONFIG_CGROUP_WRITEBACK271#ifdef CONFIG_CGROUP_WRITEBACK
276 struct list_head cgwb_list;272 struct list_head cgwb_list;
273#endif
274
275 /* Keep the hot per-CPU stats pointer away from memory event counters. */
276 struct memcg_vmstats_percpu __percpu *vmstats_percpu
277 ____cacheline_aligned_in_smp;
278
279#ifdef CONFIG_CGROUP_WRITEBACK
277 struct wb_domain cgwb_domain;280 struct wb_domain cgwb_domain;
278 struct memcg_cgwb_frn cgwb_frn[MEMCG_CGWB_FRN_CNT];281 struct memcg_cgwb_frn cgwb_frn[MEMCG_CGWB_FRN_CNT];
279#endif282#endif
@@ -318,6 +321,8 @@ struct mem_cgroup { · 38 unmodified lines
318 /* List of events which userspace want to receive */321 /* List of events which userspace want to receive */
319 struct list_head event_list;322 struct list_head event_list;
320 spinlock_t event_list_lock;323 spinlock_t event_list_lock;
324
325 int swappiness;
321#endif /* CONFIG_MEMCG_V1 */326#endif /* CONFIG_MEMCG_V1 */
322 327
323 struct mem_cgroup_per_node *nodeinfo[];328 struct mem_cgroup_per_node *nodeinfo[];
@@ -947,6 +952,8 @@ unsigned long memcg_page_state_output(struct mem_cgroup *memcg, int item); · 623 unmodified lines
947bool memcg_stat_item_valid(int idx);952bool memcg_stat_item_valid(int idx);
948bool memcg_vm_event_item_valid(enum vm_event_item idx);953bool memcg_vm_event_item_valid(enum vm_event_item idx);
949unsigned long lruvec_page_state(struct lruvec *lruvec, enum node_stat_item idx);954unsigned long lruvec_page_state(struct lruvec *lruvec, enum node_stat_item idx);
955unsigned long lruvec_page_state_monotonic(struct lruvec *lruvec,
956 enum node_stat_item idx);
950unsigned long lruvec_page_state_local(struct lruvec *lruvec,957unsigned long lruvec_page_state_local(struct lruvec *lruvec,
951 enum node_stat_item idx);958 enum node_stat_item idx);
952 959
@@ -1399,6 +1406,12 @@ static inline unsigned long lruvec_page_state(struct lruvec *lruvec, · 446 unmodified lines
1399 return node_page_state(lruvec_pgdat(lruvec), idx);1406 return node_page_state(lruvec_pgdat(lruvec), idx);
1400}1407}
1401 1408
1409static inline unsigned long lruvec_page_state_monotonic(struct lruvec *lruvec,
1410 enum node_stat_item idx)
1411{
1412 return node_page_state_monotonic(lruvec_pgdat(lruvec), idx);
1413}
1414
1402static inline unsigned long lruvec_page_state_local(struct lruvec *lruvec,1415static inline unsigned long lruvec_page_state_local(struct lruvec *lruvec,
1403 enum node_stat_item idx)1416 enum node_stat_item idx)
1404{1417{
include/linux/mm.h+125−7
@@ -1556,7 +1556,7 @@ static inline void vma_desc_set_anonymous(struct vm_area_desc *desc) · 1555 unmodified lines
1556 desc->vm_ops = NULL;1556 desc->vm_ops = NULL;
1557}1557}
1558 1558
1559static inline bool vma_is_anonymous(struct vm_area_struct *vma)1559static inline bool vma_is_anonymous(const struct vm_area_struct *vma)
1560{1560{
1561 return !vma->vm_ops;1561 return !vma->vm_ops;
1562}1562}
@@ -2271,17 +2271,76 @@ void unpin_user_pages(struct page **pages, unsigned long npages); · 708 unmodified lines
2271void unpin_user_folio(struct folio *folio, unsigned long npages);2271void unpin_user_folio(struct folio *folio, unsigned long npages);
2272void unpin_folios(struct folio **folios, unsigned long nfolios);2272void unpin_folios(struct folio **folios, unsigned long nfolios);
2273 2273
2274static inline bool is_cow_mapping(vm_flags_t flags)2274/**
2275 * vma_flags_is_cow_mapping() - Do these VMA flags imply a CoW mapping?
2276 * @flags: The VMA flags to check.
2277 *
2278 * Mappings which could be CoW'd (subject to Copy-On-Write faults) are
2279 * described as CoW mappings.
2280 *
2281 * All mappings backed by anonymous folios (all anonymous mappings and most
2282 * MAP_PRIVATE-file backed ranges) are CoW mappings.
2283 *
2284 * All other mappings (including all MAP_SHARED mappings) are non-CoW.
2285 *
2286 * The criteria are !VMA_SHARED_BIT, VMA_MAYWRITE_BIT.
2287 *
2288 * VMA_MAYWRITE_BIT is checked instead of VMA_WRITE_BIT to account for both
2289 * future mprotect() calls which can render a read-only mapping writable, and
2290 * GUP with FOLL_FORCE (e.g. ptrace) which can CoW a read-only mapping.
2291 *
2292 * - No anonymous mapping can ever clear VMA_MAYWRITE_BIT.
2293 *
2294 * - Writes to anonymous mappings do not immediately result in CoW faults but
2295 * may do so after the process is forked or if a read is followed by a
2296 * write.
2297 *
2298 * - Writes to MAP_PRIVATE file-backed mappings result in CoW faults and may
2299 * do so again after fork.
2300 *
2301 * - MAP_SHARED mappings of a file opened read-only are transformed into
2302 * VMA_MAYSHARE_BIT, !VMA_SHARED_BIT, !VMA_MAYWRITE_BIT mappings, so remain
2303 * non-CoW.
2304 *
2305 * - Drivers may clear VMA_MAYWRITE_BIT but do so at mmap() time and cannot
2306 * mark themselves anonymous. Having cleared this flag it is not valid for
2307 * them to leave the VMA_WRITE_BIT flag set.
2308 *
2309 * As a consequence, the anonymous reverse mapping only tracks CoW mappings.
2310 *
2311 * Returns: true if the flags indicate a CoW mapping, otherwise false.
2312 */
2313static inline bool vma_flags_is_cow_mapping(const vma_flags_t *flags)
2275{2314{
2276 return (flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE;2315 return vma_flags_test(flags, VMA_MAYWRITE_BIT) &&
2316 !vma_flags_test(flags, VMA_SHARED_BIT);
2277}2317}
2278 2318
2279static inline bool vma_desc_is_cow_mapping(struct vm_area_desc *desc)2319/**
2320 * vma_is_cow_mapping() - Is this VMA a CoW mapping?
2321 * @vma: The VMA to check.
2322 *
2323 * See vma_flags_is_cow_mapping() for details.
2324 *
2325 * Returns: true if the VMA is a CoW mapping, otherwise false.
2326 */
2327static inline bool vma_is_cow_mapping(const struct vm_area_struct *vma)
2280{2328{
2281 const vma_flags_t *flags = &desc->vma_flags;2329 return vma_flags_is_cow_mapping(&vma->flags);
2330}
2282 2331
2283 return vma_flags_test(flags, VMA_MAYWRITE_BIT) &&2332/**
2284 !vma_flags_test(flags, VMA_SHARED_BIT);2333 * vma_desc_is_cow_mapping() - Is this VMA descriptor a CoW mapping?
2334 * @desc: The VMA descriptor to check.
2335 *
2336 * See vma_flags_is_cow_mapping() for details.
2337 *
2338 * Returns: true if the VMA descriptor describes a CoW mapping, otherwise
2339 * false.
2340 */
2341static inline bool vma_desc_is_cow_mapping(struct vm_area_desc *desc)
2342{
2343 return vma_flags_is_cow_mapping(&desc->vma_flags);
2285}2344}
2286 2345
2287#ifndef CONFIG_MMU2346#ifndef CONFIG_MMU
@@ -4393,6 +4452,65 @@ static inline pgoff_t vma_last_pgoff(const struct vm_area_struct *vma) · 2105 unmodified lines
4393 return vma_end_pgoff(vma) - 1;4452 return vma_end_pgoff(vma) - 1;
4394}4453}
4395 4454
4455/**
4456 * vma_start_anon_pgoff() - Get the anonymous page offset of the start of @vma
4457 * @vma: The VMA whose anonymous page offset is required.
4458 *
4459 * If unfaulted, then this is vma->vm_start >> PAGE_SHIFT, if faulted then the
4460 * anonymous page offset at the time of first fault.
4461 *
4462 * If the VMA is anonymous, this returns the same value as vma_start_pgoff().
4463 *
4464 * This value is used for tracking MAP_PRIVATE file-backed mappings by their
4465 * anonymous page offset.
4466 *
4467 * Returns: The anonymous page offset of the start of @vma.
4468 */
4469static inline pgoff_t vma_start_anon_pgoff(const struct vm_area_struct *vma)
4470{
4471 pgoff_t pgoff = 0;
4472
4473#ifdef CONFIG_64BIT
4474 pgoff += vma->__vm_anon_pgoff_hi;
4475 pgoff <<= 32;
4476#endif
4477 pgoff += vma->__vm_anon_pgoff_lo;
4478 return pgoff;
4479}
4480
4481/**
4482 * vma_end_anon_pgoff() - Get the anonymous page offset of the exclusive end of
4483 * @vma.
4484 * @vma: The VMA whose end anonymous page offset is required.
4485 *
4486 * This returns the anonymous exclusive end page offset of @vma, which is useful
4487 * for expressing page offset ranges.
4488 *
4489 * See the description of vma_start_anon_pgoff() for a description of VMA
4490 * anonymous page offsets.
4491 *
4492 * Returns: The exclusive end anonymous page offset of @vma.
4493 */
4494static inline pgoff_t vma_end_anon_pgoff(const struct vm_area_struct *vma)
4495{
4496 return vma_start_anon_pgoff(vma) + vma_pages(vma);
4497}
4498
4499/**
4500 * vma_last_anon_pgoff() - Get the anonymous page offset of the last page in
4501 * @vma.
4502 * @vma: The VMA whose last anonymous page offset is required.
4503 *
4504 * See the description of vma_start_anon_pgoff() for a description of VMA
4505 * anonymous page offsets.
4506 *
4507 * Returns: The last anonymous page offset of @vma.
4508 */
4509static inline pgoff_t vma_last_anon_pgoff(const struct vm_area_struct *vma)
4510{
4511 return vma_end_anon_pgoff(vma) - 1;
4512}
4513
4396static inline unsigned long vma_desc_size(const struct vm_area_desc *desc)4514static inline unsigned long vma_desc_size(const struct vm_area_desc *desc)
4397{4515{
4398 return desc->end - desc->start;4516 return desc->end - desc->start;
include/linux/mm_types.h+26−14
@@ -967,6 +967,11 @@ struct vm_area_struct { · 966 unmodified lines
967 */967 */
968 unsigned int vm_lock_seq;968 unsigned int vm_lock_seq;
969#endif969#endif
970 /*
971 * Low 32-bits of anonymous page offset.
972 * See vma_start_anon_pgoff() comment for details.
973 */
974 unsigned int __vm_anon_pgoff_lo;
970 /*975 /*
971 * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma976 * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma
972 * list, after a COW of one of the file pages. A MAP_SHARED vma977 * list, after a COW of one of the file pages. A MAP_SHARED vma
@@ -1041,6 +1046,13 @@ struct vm_area_struct { · 68 unmodified lines
1041#ifdef CONFIG_DEBUG_LOCK_ALLOC1046#ifdef CONFIG_DEBUG_LOCK_ALLOC
1042 struct lockdep_map vmlock_dep_map;1047 struct lockdep_map vmlock_dep_map;
1043#endif1048#endif
1049#endif
1050#ifdef CONFIG_64BIT
1051 /*
1052 * High 32-bits of anonymous page offset.
1053 * See vma_start_anon_pgoff() comment for details.
1054 */
1055 unsigned int __vm_anon_pgoff_hi;
1044#endif1056#endif
1045 /*1057 /*
1046 * For areas with an address space and backing store,1058 * For areas with an address space and backing store,
@@ -1706,20 +1718,20 @@ enum vm_fault_reason { · 659 unmodified lines
1706 VM_FAULT_SIGSEGV | VM_FAULT_HWPOISON | \1718 VM_FAULT_SIGSEGV | VM_FAULT_HWPOISON | \
1707 VM_FAULT_HWPOISON_LARGE | VM_FAULT_FALLBACK)1719 VM_FAULT_HWPOISON_LARGE | VM_FAULT_FALLBACK)
1708 1720
1709#define VM_FAULT_RESULT_TRACE \1721#define VM_FAULT_RESULT_TRACE \
1710 { VM_FAULT_OOM, "OOM" }, \1722 { (__force u32)VM_FAULT_OOM, "OOM" }, \
1711 { VM_FAULT_SIGBUS, "SIGBUS" }, \1723 { (__force u32)VM_FAULT_SIGBUS, "SIGBUS" }, \
1712 { VM_FAULT_MAJOR, "MAJOR" }, \1724 { (__force u32)VM_FAULT_MAJOR, "MAJOR" }, \
1713 { VM_FAULT_HWPOISON, "HWPOISON" }, \1725 { (__force u32)VM_FAULT_HWPOISON, "HWPOISON" }, \
1714 { VM_FAULT_HWPOISON_LARGE, "HWPOISON_LARGE" }, \1726 { (__force u32)VM_FAULT_HWPOISON_LARGE, "HWPOISON_LARGE" }, \
1715 { VM_FAULT_SIGSEGV, "SIGSEGV" }, \1727 { (__force u32)VM_FAULT_SIGSEGV, "SIGSEGV" }, \
1716 { VM_FAULT_NOPAGE, "NOPAGE" }, \1728 { (__force u32)VM_FAULT_NOPAGE, "NOPAGE" }, \
1717 { VM_FAULT_LOCKED, "LOCKED" }, \1729 { (__force u32)VM_FAULT_LOCKED, "LOCKED" }, \
1718 { VM_FAULT_RETRY, "RETRY" }, \1730 { (__force u32)VM_FAULT_RETRY, "RETRY" }, \
1719 { VM_FAULT_FALLBACK, "FALLBACK" }, \1731 { (__force u32)VM_FAULT_FALLBACK, "FALLBACK" }, \
1720 { VM_FAULT_DONE_COW, "DONE_COW" }, \1732 { (__force u32)VM_FAULT_DONE_COW, "DONE_COW" }, \
1721 { VM_FAULT_NEEDDSYNC, "NEEDDSYNC" }, \1733 { (__force u32)VM_FAULT_NEEDDSYNC, "NEEDDSYNC" }, \
1722 { VM_FAULT_COMPLETED, "COMPLETED" }1734 { (__force u32)VM_FAULT_COMPLETED, "COMPLETED" }
1723 1735
1724struct vm_special_mapping {1736struct vm_special_mapping {
1725 const char *name; /* The name, e.g. "[vdso]". */1737 const char *name; /* The name, e.g. "[vdso]". */
include/linux/mmzone.h+13−3
@@ -323,6 +323,8 @@ enum node_stat_item { · 322 unmodified lines
323 PGSCAN_PROACTIVE,323 PGSCAN_PROACTIVE,
324 PGSCAN_ANON,324 PGSCAN_ANON,
325 PGSCAN_FILE,325 PGSCAN_FILE,
326 PGROTATE_ANON,
327 PGROTATE_FILE,
326 PGREFILL,328 PGREFILL,
327#ifdef CONFIG_HUGETLB_PAGE329#ifdef CONFIG_HUGETLB_PAGE
328 NR_HUGETLB,330 NR_HUGETLB,
@@ -755,6 +757,12 @@ void lru_gen_reparent_memcg(struct mem_cgroup *memcg, struct mem_cgroup *parent, · 426 unmodified lines
755 757
756#endif /* CONFIG_LRU_GEN */758#endif /* CONFIG_LRU_GEN */
757 759
760struct lru_cost {
761 unsigned long count;
762 unsigned long last_rotated;
763 unsigned long last_io;
764};
765
758struct lruvec {766struct lruvec {
759 struct list_head lists[NR_LRU_LISTS];767 struct list_head lists[NR_LRU_LISTS];
760 /* per lruvec lru_lock for memcg */768 /* per lruvec lru_lock for memcg */
@@ -763,9 +771,12 @@ struct lruvec { · 2 unmodified lines
763 * These track the cost of reclaiming one LRU - file or anon -771 * These track the cost of reclaiming one LRU - file or anon -
764 * over the other. As the observed cost of reclaiming one LRU772 * over the other. As the observed cost of reclaiming one LRU
765 * increases, the reclaim scan balance tips toward the other.773 * increases, the reclaim scan balance tips toward the other.
774 * Updated and decayed at prepare_scan_control() time; cost_lock
775 * serialises that update.
766 */776 */
767 unsigned long anon_cost;777 struct lru_cost cost[ANON_AND_FILE];
768 unsigned long file_cost;778 /* Protects cost[]. */
779 spinlock_t cost_lock;
769 /* Non-resident age, driven by LRU movement */780 /* Non-resident age, driven by LRU movement */
770 atomic_long_t nonresident_age;781 atomic_long_t nonresident_age;
771 /* Refaults at the time of last reclaim cycle */782 /* Refaults at the time of last reclaim cycle */
@@ -2058,7 +2069,6 @@ static inline struct mem_section *__nr_to_section(unsigned long nr) · 1286 unmodified lines
2058#endif2069#endif
2059 return &mem_section[root][nr & SECTION_ROOT_MASK];2070 return &mem_section[root][nr & SECTION_ROOT_MASK];
2060}2071}
2061extern size_t mem_section_usage_size(void);
2062 2072
2063/*2073/*
2064 * We use the lower bits of the mem_map pointer to store a little bit of2074 * We use the lower bits of the mem_map pointer to store a little bit of
include/linux/nfs_fs.h+0−1
@@ -552,7 +552,6 @@ static inline const struct cred *nfs_file_cred(struct file *file) · 551 unmodified lines
552/*552/*
553 * linux/fs/nfs/direct.c553 * linux/fs/nfs/direct.c
554 */554 */
555int nfs_swap_rw(struct kiocb *iocb, struct iov_iter *iter);
556ssize_t nfs_file_direct_read(struct kiocb *iocb,555ssize_t nfs_file_direct_read(struct kiocb *iocb,
557 struct iov_iter *iter, bool swap);556 struct iov_iter *iter, bool swap);
558ssize_t nfs_file_direct_write(struct kiocb *iocb,557ssize_t nfs_file_direct_write(struct kiocb *iocb,
include/linux/page_ext.h+0−5
@@ -55,7 +55,6 @@ struct page_ext { · 54 unmodified lines
55 55
56extern bool early_page_ext;56extern bool early_page_ext;
57extern unsigned long page_ext_size;57extern unsigned long page_ext_size;
58extern void pgdat_page_ext_init(struct pglist_data *pgdat);
59 58
60static inline bool early_page_ext_enabled(void)59static inline bool early_page_ext_enabled(void)
61{60{
@@ -202,10 +201,6 @@ static inline bool early_page_ext_enabled(void) · 140 unmodified lines
202 return false;201 return false;
203}202}
204 203
205static inline void pgdat_page_ext_init(struct pglist_data *pgdat)
206{
207}
208
209static inline void page_ext_init(void)204static inline void page_ext_init(void)
210{205{
211}206}
include/linux/pagemap.h+37−3
@@ -1094,10 +1094,44 @@ static inline pgoff_t linear_page_delta(const struct vm_area_struct *vma, · 1093 unmodified lines
1094static inline pgoff_t linear_page_index(const struct vm_area_struct *vma,1094static inline pgoff_t linear_page_index(const struct vm_area_struct *vma,
1095 const unsigned long address)1095 const unsigned long address)
1096{1096{
1097 pgoff_t pgoff;1097 return linear_page_delta(vma, address) + vma_start_pgoff(vma);
1098}
1099
1100static inline pgoff_t __linear_anon_page_index(const struct vm_area_struct *vma,
1101 const unsigned long address)
1102{
1103 return linear_page_delta(vma, address) + vma_start_anon_pgoff(vma);
1104}
1105
1106/**
1107 * linear_anon_page_index() - Determine the absolute anonymous page offset of
1108 * @address within @vma.
1109 * @vma: An anonymous or MAP_PRIVATE file-backed VMA in which @address resides.
1110 * @address: The address whose absolute page offset is required.
1111 *
1112 * This returns the anonymous page offset of @address, which is the page offset
1113 * the address possessed at the time the VMA was first faulted.
1114 *
1115 * For anonymous mappings, this returns the same value as linear_page_index().
1116 *
1117 * For MAP_PRIVATE file-backed mappings, this returns the anonymous page offset
1118 * of @address, which is the page offset the address possessed at the time the
1119 * VMA was first faulted.
1120 *
1121 * It is not valid to call this function for shared file-backed mappings.
1122 *
1123 * Returns: The absolute anonymous page offset of @address within @vma.
1124 */
1125static inline pgoff_t linear_anon_page_index(const struct vm_area_struct *vma,
1126 const unsigned long address)
1127{
1128 const pgoff_t pgoff = __linear_anon_page_index(vma, address);
1129
1130 VM_WARN_ON_ONCE(!vma_is_cow_mapping(vma));
1131 /* Account for MAP_PRIVATE-/dev/zero which is only semi-anonymous. */
1132 if (vma_is_anonymous(vma) && !vma->vm_file)
1133 VM_WARN_ON_ONCE(pgoff != linear_page_index(vma, address));
1098 1134
1099 pgoff = linear_page_delta(vma, address);
1100 pgoff += vma_start_pgoff(vma);
1101 return pgoff;1135 return pgoff;
1102}1136}
1103 1137
include/linux/percpu-defs.h+1−6
@@ -65,13 +65,8 @@ · 64 unmodified lines
65 *65 *
66 * Archs which need weak percpu definitions should set66 * Archs which need weak percpu definitions should set
67 * CONFIG_ARCH_MODULE_NEEDS_WEAK_PER_CPU when necessary.67 * CONFIG_ARCH_MODULE_NEEDS_WEAK_PER_CPU when necessary.
68 *
69 * To ensure that the generic code observes the above two
70 * restrictions, if CONFIG_DEBUG_FORCE_WEAK_PER_CPU is set weak
71 * definition is used for all cases.
72 */68 */
73#if (defined(CONFIG_ARCH_MODULE_NEEDS_WEAK_PER_CPU) && defined(MODULE)) || \69#if defined(CONFIG_ARCH_MODULE_NEEDS_WEAK_PER_CPU) && defined(MODULE)
74 defined(CONFIG_DEBUG_FORCE_WEAK_PER_CPU)
75/*70/*
76 * __pcpu_scope_* dummy variable is used to enforce scope. It71 * __pcpu_scope_* dummy variable is used to enforce scope. It
77 * receives the static modifier when it's used in front of72 * receives the static modifier when it's used in front of
include/linux/rmap.h+6−5
@@ -843,7 +843,7 @@ static inline int folio_try_share_anon_rmap_pmd(struct folio *folio, · 842 unmodified lines
843 * Called from mm/vmscan.c to handle paging out843 * Called from mm/vmscan.c to handle paging out
844 */844 */
845int folio_referenced(struct folio *, int is_locked,845int folio_referenced(struct folio *, int is_locked,
846 struct mem_cgroup *memcg, vm_flags_t *vm_flags);846 struct mem_cgroup *memcg, vma_flags_t *vma_flags);
847 847
848void try_to_migrate(struct folio *folio, enum ttu_flags flags);848void try_to_migrate(struct folio *folio, enum ttu_flags flags);
849void try_to_unmap(struct folio *, enum ttu_flags flags);849void try_to_unmap(struct folio *, enum ttu_flags flags);
@@ -864,13 +864,14 @@ struct page *make_device_exclusive(struct mm_struct *mm, unsigned long addr, · 14 unmodified lines
864struct page_vma_mapped_walk {864struct page_vma_mapped_walk {
865 unsigned long pfn;865 unsigned long pfn;
866 unsigned long nr_pages;866 unsigned long nr_pages;
867 pgoff_t pgoff;867 pgoff_t pgoff; /* Only meaningful if nr_pages > 1 and not a KSM walk */
868 struct vm_area_struct *vma;868 struct vm_area_struct *vma;
869 unsigned long address;869 unsigned long address;
870 pmd_t *pmd;870 pmd_t *pmd;
871 pte_t *pte;871 pte_t *pte;
872 spinlock_t *ptl;872 spinlock_t *ptl;
873 unsigned int flags;873 unsigned int flags;
874 bool pgoff_is_anon : 1;
874};875};
875 876
876#define DEFINE_FOLIO_VMA_WALK(name, _folio, _vma, _address, _flags) \877#define DEFINE_FOLIO_VMA_WALK(name, _folio, _vma, _address, _flags) \
@@ -881,6 +882,7 @@ struct page_vma_mapped_walk { · 4 unmodified lines
881 .vma = _vma, \882 .vma = _vma, \
882 .address = _address, \883 .address = _address, \
883 .flags = _flags, \884 .flags = _flags, \
885 .pgoff_is_anon = folio_test_anon(_folio), \
884 }886 }
885 887
886static inline void page_vma_mapped_walk_done(struct page_vma_mapped_walk *pvmw)888static inline void page_vma_mapped_walk_done(struct page_vma_mapped_walk *pvmw)
@@ -975,10 +977,9 @@ struct anon_vma *folio_lock_anon_vma_read(const struct folio *folio, · 88 unmodified lines
975#define anon_vma_prepare(vma) (0)977#define anon_vma_prepare(vma) (0)
976 978
977static inline int folio_referenced(struct folio *folio, int is_locked,979static inline int folio_referenced(struct folio *folio, int is_locked,
978 struct mem_cgroup *memcg,980 struct mem_cgroup *memcg, vma_flags_t *vma_flags)
979 vm_flags_t *vm_flags)
980{981{
981 *vm_flags = 0;982 vma_flags_clear_all(vma_flags);
982 return 0;983 return 0;
983}984}
984 985
include/linux/sched.h+1−0
@@ -1298,6 +1298,7 @@ struct task_struct { · 1297 unmodified lines
1298 u64 curr_chain_key;1298 u64 curr_chain_key;
1299 int lockdep_depth;1299 int lockdep_depth;
1300 unsigned int lockdep_recursion;1300 unsigned int lockdep_recursion;
1301 unsigned int lockdep_seq;
1301 struct held_lock held_locks[MAX_LOCK_DEPTH];1302 struct held_lock held_locks[MAX_LOCK_DEPTH];
1302#endif1303#endif
1303 1304
include/linux/shmem_fs.h+1−4
@@ -12,8 +12,6 @@ · 11 unmodified lines
12#include <linux/userfaultfd_k.h>12#include <linux/userfaultfd_k.h>
13#include <linux/bits.h>13#include <linux/bits.h>
14 14
15struct swap_iocb;
16
17/* inode in-kernel data */15/* inode in-kernel data */
18 16
19#ifdef CONFIG_TMPFS_QUOTA17#ifdef CONFIG_TMPFS_QUOTA
@@ -123,8 +121,7 @@ static inline bool shmem_mapping(const struct address_space *mapping) · 103 unmodified lines
123void shmem_unlock_mapping(struct address_space *mapping);121void shmem_unlock_mapping(struct address_space *mapping);
124struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,122struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,
125 pgoff_t index, gfp_t gfp_mask);123 pgoff_t index, gfp_t gfp_mask);
126int shmem_writeout(struct folio *folio, struct swap_iocb **plug,124int shmem_write_folio(struct folio *folio);
127 struct list_head *folio_list);
128void shmem_truncate_range(struct inode *inode, loff_t start, uoff_t end);125void shmem_truncate_range(struct inode *inode, loff_t start, uoff_t end);
129int shmem_unuse(unsigned int type);126int shmem_unuse(unsigned int type);
130 127
include/linux/swap.h+9−21
@@ -202,7 +202,6 @@ enum { · 201 unmodified lines
202 SWP_SOLIDSTATE = (1 << 4), /* blkdev seeks are cheap */202 SWP_SOLIDSTATE = (1 << 4), /* blkdev seeks are cheap */
203 SWP_BLKDEV = (1 << 6), /* its a block device */203 SWP_BLKDEV = (1 << 6), /* its a block device */
204 SWP_ACTIVATED = (1 << 7), /* set after swap_activate success */204 SWP_ACTIVATED = (1 << 7), /* set after swap_activate success */
205 SWP_FS_OPS = (1 << 8), /* swapfile operations go through fs */
206 SWP_AREA_DISCARD = (1 << 9), /* single-time swap area discards */205 SWP_AREA_DISCARD = (1 << 9), /* single-time swap area discards */
207 SWP_PAGE_DISCARD = (1 << 10), /* freed swap page-cluster discards */206 SWP_PAGE_DISCARD = (1 << 10), /* freed swap page-cluster discards */
208 SWP_STABLE_WRITES = (1 << 11), /* no overwrite PG_writeback pages */207 SWP_STABLE_WRITES = (1 << 11), /* no overwrite PG_writeback pages */
@@ -276,6 +275,7 @@ struct swap_info_struct { · 67 unmodified lines
276 struct work_struct reclaim_work; /* reclaim worker */275 struct work_struct reclaim_work; /* reclaim worker */
277 struct list_head discard_clusters; /* discard clusters list */276 struct list_head discard_clusters; /* discard clusters list */
278 struct plist_node avail_list; /* entry in swap_avail_head */277 struct plist_node avail_list; /* entry in swap_avail_head */
278 const struct swap_ops *ops;
279};279};
280 280
281static inline swp_entry_t page_swap_entry(struct page *page)281static inline swp_entry_t page_swap_entry(struct page *page)
@@ -298,6 +298,14 @@ void folio_add_lru(struct folio *folio); · 16 unmodified lines
298void folio_mark_accessed(struct folio *folio);298void folio_mark_accessed(struct folio *folio);
299void lru_add_drain_all(void);299void lru_add_drain_all(void);
300 300
301enum lru_cache_drained {
302 LRU_CACHE_NOT_DRAINED,
303 LRU_CACHE_DRAINED,
304 LRU_CACHE_DRAINED_ALL,
305};
306void lru_cache_drain_for_folio(const struct folio *folio,
307 unsigned int extra_refs, enum lru_cache_drained *drained);
308
301/* linux/mm/folio-compat.c */309/* linux/mm/folio-compat.c */
302void mark_page_accessed(struct page *page);310void mark_page_accessed(struct page *page);
303 311
@@ -309,7 +317,6 @@ static inline bool lru_cache_disabled(void) · 5 unmodified lines
309}317}
310 318
311extern unsigned long shrink_all_memory(unsigned long nr_pages);319extern unsigned long shrink_all_memory(unsigned long nr_pages);
312extern int vm_swappiness;
313long remove_mapping(struct address_space *mapping, struct folio *folio);320long remove_mapping(struct address_space *mapping, struct folio *folio);
314 321
315#if defined(CONFIG_SYSFS) && defined(CONFIG_NUMA)322#if defined(CONFIG_SYSFS) && defined(CONFIG_NUMA)
@@ -334,7 +341,6 @@ extern void __meminit kswapd_run(int nid); · 18 unmodified lines
334extern void __meminit kswapd_stop(int nid);341extern void __meminit kswapd_stop(int nid);
335 342
336#ifdef CONFIG_SWAP343#ifdef CONFIG_SWAP
337
338int add_swap_extent(struct swap_info_struct *sis, unsigned long start_page,344int add_swap_extent(struct swap_info_struct *sis, unsigned long start_page,
339 unsigned long nr_pages, sector_t start_block);345 unsigned long nr_pages, sector_t start_block);
340int generic_swapfile_activate(struct swap_info_struct *, struct file *,346int generic_swapfile_activate(struct swap_info_struct *, struct file *,
@@ -468,25 +474,7 @@ static inline int add_swap_extent(struct swap_info_struct *sis, · 127 unmodified lines
468}474}
469#endif /* CONFIG_SWAP */475#endif /* CONFIG_SWAP */
470#ifdef CONFIG_MEMCG476#ifdef CONFIG_MEMCG
471static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
472{
473 /* Cgroup2 doesn't have per-cgroup swappiness */
474 if (cgroup_subsys_on_dfl(memory_cgrp_subsys))
475 return READ_ONCE(vm_swappiness);
476
477 /* root ? */
478 if (mem_cgroup_disabled() || mem_cgroup_is_root(memcg))
479 return READ_ONCE(vm_swappiness);
480
481 return READ_ONCE(memcg->swappiness);
482}
483
484void lru_reparent_memcg(struct mem_cgroup *memcg, struct mem_cgroup *parent, int nid);477void lru_reparent_memcg(struct mem_cgroup *memcg, struct mem_cgroup *parent, int nid);
485#else
486static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
487{
488 return READ_ONCE(vm_swappiness);
489}
490#endif478#endif
491 479
492#if defined(CONFIG_SWAP) && defined(CONFIG_MEMCG) && defined(CONFIG_BLK_CGROUP)480#if defined(CONFIG_SWAP) && defined(CONFIG_MEMCG) && defined(CONFIG_BLK_CGROUP)
include/linux/swap_ops.h+44−0
@@ -0,0 +1,44 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _MM_SWAP_OPS_H
3#define _MM_SWAP_OPS_H
4
5#include <linux/swap.h> /* for SWAP_CLUSTER_MAX */
6
7struct swap_iocb {
8 union {
9 struct kiocb iocb;
10 struct bio bio;
11 };
12 struct bio_vec bvecs[SWAP_CLUSTER_MAX];
13 int nr_bvecs;
14 int len;
15};
16
17struct swap_io_ctx {
18 struct swap_iocb *sio;
19 struct swap_info_struct *sis;
20};
21
22/*
23 * SWAP_OPS_F_REQUIRE_NOFS:
24 * When set, all reclaim operations must operated as GFS_NOFS and not
25 * just GFP_NOIO, as GFP_NOIO allocations could recourse into the
26 * file system backing this swap file.
27 */
28#define SWAP_OPS_F_REQUIRE_NOFS (1U << 0)
29
30struct swap_ops {
31 unsigned int flags;
32
33 bool (*can_merge)(struct folio *folio, struct folio *prev_folio,
34 size_t prev_folio_size, int rw);
35 void (*submit_write)(struct swap_io_ctx *ctx);
36 void (*submit_read)(struct swap_io_ctx *ctx);
37};
38
39void swap_fs_prepare_rw(struct swap_io_ctx *ctx, int rw, struct iov_iter *iter);
40bool swap_fs_can_merge(struct folio *folio, struct folio *prev_folio,
41 size_t prev_folio_size, int rw);
42int swap_fs_activate(struct swap_info_struct *sis, const struct swap_ops *ops);
43
44#endif /* _MM_SWAP_OPS_H */
include/linux/swapops.h+4−3
@@ -5,6 +5,7 @@ · 4 unmodified lines
5#include <linux/radix-tree.h>5#include <linux/radix-tree.h>
6#include <linux/bug.h>6#include <linux/bug.h>
7#include <linux/mm_types.h>7#include <linux/mm_types.h>
8#include <linux/swap.h>
8 9
9#ifdef CONFIG_MMU10#ifdef CONFIG_MMU
10 11
@@ -325,8 +326,8 @@ struct page_vma_mapped_walk; · 314 unmodified lines
325extern int set_pmd_migration_entry(struct page_vma_mapped_walk *pvmw,326extern int set_pmd_migration_entry(struct page_vma_mapped_walk *pvmw,
326 struct page *page);327 struct page *page);
327 328
328extern void remove_migration_pmd(struct page_vma_mapped_walk *pvmw,329void remove_migration_pmd(struct page_vma_mapped_walk *pvmw,
329 struct page *new);330 struct folio *folio);
330 331
331extern void pmd_migration_entry_wait(struct mm_struct *mm, pmd_t *pmd);332extern void pmd_migration_entry_wait(struct mm_struct *mm, pmd_t *pmd);
332 333
@@ -346,7 +347,7 @@ static inline int set_pmd_migration_entry(struct page_vma_mapped_walk *pvmw, · 13 unmodified lines
346}347}
347 348
348static inline void remove_migration_pmd(struct page_vma_mapped_walk *pvmw,349static inline void remove_migration_pmd(struct page_vma_mapped_walk *pvmw,
349 struct page *new)350 struct folio *folio)
350{351{
351 BUILD_BUG();352 BUILD_BUG();
352}353}
include/linux/vm_event_item.h+4−0
@@ -175,6 +175,10 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, · 174 unmodified lines
175 KSTACK_REST,175 KSTACK_REST,
176#endif176#endif
177#endif /* CONFIG_DEBUG_STACK_USAGE */177#endif /* CONFIG_DEBUG_STACK_USAGE */
178#ifdef CONFIG_SWAP
179 NRSWPIN,
180 NRSWPOUT,
181#endif /* CONFIG_SWAP */
178 NR_VM_EVENT_ITEMS182 NR_VM_EVENT_ITEMS
179};183};
180 184
include/linux/vmalloc.h+1−1
@@ -62,7 +62,7 @@ struct vm_struct { · 61 unmodified lines
62#ifdef CONFIG_HAVE_ARCH_HUGE_VMALLOC62#ifdef CONFIG_HAVE_ARCH_HUGE_VMALLOC
63 unsigned int page_order;63 unsigned int page_order;
64#endif64#endif
65 unsigned int nr_pages;65 unsigned long nr_pages;
66 phys_addr_t phys_addr;66 phys_addr_t phys_addr;
67 const void *caller;67 const void *caller;
68 unsigned long requested_size;68 unsigned long requested_size;
include/linux/vmstat.h+16−1
@@ -20,7 +20,6 @@ struct reclaim_stat { · 19 unmodified lines
20 unsigned nr_congested;20 unsigned nr_congested;
21 unsigned nr_writeback;21 unsigned nr_writeback;
22 unsigned nr_immediate;22 unsigned nr_immediate;
23 unsigned nr_pageout;
24 unsigned nr_activate[ANON_AND_FILE];23 unsigned nr_activate[ANON_AND_FILE];
25 unsigned nr_ref_keep;24 unsigned nr_ref_keep;
26 unsigned nr_unmap_fail;25 unsigned nr_unmap_fail;
@@ -194,6 +193,19 @@ unsigned long global_node_page_state_pages(enum node_stat_item item) · 167 unmodified lines
194 return x;193 return x;
195}194}
196 195
196/*
197 * Non-clamping variant of global_node_page_state() intended for callers that
198 * snapshot a monotonically-incremented counter and subtract two samples.
199 * Returns the raw wrapping value so that unsigned modular subtraction stays
200 * correct across a signed-long overflow (a real hazard on 32-bit) that the
201 * clamp in global_node_page_state() would otherwise turn into a huge spurious
202 * delta. Do NOT use for non-monotonic page-count reads.
203 */
204static inline unsigned long global_node_page_state_monotonic(enum node_stat_item item)
205{
206 return (unsigned long)atomic_long_read(&vm_node_stat[item]);
207}
208
197static inline unsigned long global_node_page_state(enum node_stat_item item)209static inline unsigned long global_node_page_state(enum node_stat_item item)
198{210{
199 VM_WARN_ON_ONCE(vmstat_item_in_bytes(item));211 VM_WARN_ON_ONCE(vmstat_item_in_bytes(item));
@@ -259,11 +271,14 @@ extern unsigned long node_page_state(struct pglist_data *pgdat, · 59 unmodified lines
259 enum node_stat_item item);271 enum node_stat_item item);
260extern unsigned long node_page_state_pages(struct pglist_data *pgdat,272extern unsigned long node_page_state_pages(struct pglist_data *pgdat,
261 enum node_stat_item item);273 enum node_stat_item item);
274extern unsigned long node_page_state_monotonic(struct pglist_data *pgdat,
275 enum node_stat_item item);
262extern void fold_vm_numa_events(void);276extern void fold_vm_numa_events(void);
263#else277#else
264#define sum_zone_node_page_state(node, item) global_zone_page_state(item)278#define sum_zone_node_page_state(node, item) global_zone_page_state(item)
265#define node_page_state(node, item) global_node_page_state(item)279#define node_page_state(node, item) global_node_page_state(item)
266#define node_page_state_pages(node, item) global_node_page_state_pages(item)280#define node_page_state_pages(node, item) global_node_page_state_pages(item)
281#define node_page_state_monotonic(node, item) global_node_page_state_monotonic(item)
267static inline void fold_vm_numa_events(void)282static inline void fold_vm_numa_events(void)
268{283{
269}284}
include/rv/da_monitor.h+1−1
@@ -25,7 +25,7 @@ · 24 unmodified lines
25 25
26/*26/*
27 * Per-cpu variables require a unique name although static in some27 * Per-cpu variables require a unique name although static in some
28 * configurations (e.g. CONFIG_DEBUG_FORCE_WEAK_PER_CPU or alpha modules).28 * configurations (e.g. alpha modules).
29 */29 */
30#define DA_MON_NAME CONCATENATE(da_mon_, MONITOR_NAME)30#define DA_MON_NAME CONCATENATE(da_mon_, MONITOR_NAME)
31 31
include/uapi/linux/alloc_tag.h+99−0
@@ -0,0 +1,99 @@
1/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2/*
3 * alloc_tag IOCTL API definition
4 *
5 * Copyright (C) 2026 Google, LLC. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef _UAPI_ALLOC_TAG_H
13#define _UAPI_ALLOC_TAG_H
14
15#include <linux/types.h>
16
17/*
18 * Function, file and module names often have the same prefixes, therefore
19 * when filtering by these criteria, we compare the last 64 characters to
20 * minimize the chances of name collisions
21 */
22#define ALLOCINFO_STR_SIZE 64
23
24struct allocinfo_content_id {
25 __u64 id;
26};
27
28struct allocinfo_tag {
29 /* Longer names are trimmed */
30 char modname[ALLOCINFO_STR_SIZE];
31 char function[ALLOCINFO_STR_SIZE];
32 char filename[ALLOCINFO_STR_SIZE];
33 __u64 lineno;
34};
35
36/* The alignment ensures 32-bit compatible interfaces are not broken */
37struct allocinfo_counter {
38 __u64 bytes;
39 __u64 calls;
40 __u8 accurate;
41} __attribute__((aligned(8)));
42
43struct allocinfo_tag_data {
44 struct allocinfo_tag tag;
45 struct allocinfo_counter counter;
46};
47
48enum {
49 ALLOCINFO_FILTER_MODNAME,
50 ALLOCINFO_FILTER_FUNCTION,
51 ALLOCINFO_FILTER_FILENAME,
52 ALLOCINFO_FILTER_LINENO,
53 ALLOCINFO_FILTER_INACCURATE,
54 ALLOCINFO_FILTER_MIN_SIZE,
55 ALLOCINFO_FILTER_MAX_SIZE,
56 __ALLOCINFO_FILTER_LAST = ALLOCINFO_FILTER_MAX_SIZE
57};
58
59#define ALLOCINFO_FILTER_MASK_MODNAME (1 << ALLOCINFO_FILTER_MODNAME)
60#define ALLOCINFO_FILTER_MASK_FUNCTION (1 << ALLOCINFO_FILTER_FUNCTION)
61#define ALLOCINFO_FILTER_MASK_FILENAME (1 << ALLOCINFO_FILTER_FILENAME)
62#define ALLOCINFO_FILTER_MASK_LINENO (1 << ALLOCINFO_FILTER_LINENO)
63#define ALLOCINFO_FILTER_MASK_INACCURATE (1 << ALLOCINFO_FILTER_INACCURATE)
64#define ALLOCINFO_FILTER_MASK_MIN_SIZE (1 << ALLOCINFO_FILTER_MIN_SIZE)
65#define ALLOCINFO_FILTER_MASK_MAX_SIZE (1 << ALLOCINFO_FILTER_MAX_SIZE)
66
67#define ALLOCINFO_FILTER_MASKS \
68 ((1 << (__ALLOCINFO_FILTER_LAST + 1)) - 1)
69
70struct allocinfo_filter {
71 __u64 mask; /* bitmask of the filter fields used */
72 struct allocinfo_tag fields;
73 __u64 min_size;
74 __u64 max_size;
75 /* filter criteria only; see allocinfo_counter.accurate for actual accuracy */
76 __u64 inaccurate;
77};
78
79struct allocinfo_get_at {
80 /* inputs */
81 __u64 pos;
82 struct allocinfo_filter filter;
83 /* output */
84 struct allocinfo_tag_data data;
85};
86
87#define _ALLOCINFO_IOC_CONTENT_ID 0
88#define _ALLOCINFO_IOC_GET_AT 1
89#define _ALLOCINFO_IOC_GET_NEXT 2
90
91#define ALLOCINFO_IOC_BASE 0xA6
92#define ALLOCINFO_IOC_CONTENT_ID _IOR(ALLOCINFO_IOC_BASE, _ALLOCINFO_IOC_CONTENT_ID, \
93 struct allocinfo_content_id)
94#define ALLOCINFO_IOC_GET_AT _IOWR(ALLOCINFO_IOC_BASE, _ALLOCINFO_IOC_GET_AT, \
95 struct allocinfo_get_at)
96#define ALLOCINFO_IOC_GET_NEXT _IOR(ALLOCINFO_IOC_BASE, _ALLOCINFO_IOC_GET_NEXT, \
97 struct allocinfo_tag_data)
98
99#endif /* _UAPI_ALLOC_TAG_H */
kernel/events/uprobes.c+1−1
@@ -513,7 +513,7 @@ int uprobe_write(struct arch_uprobe *auprobe, struct vm_area_struct *vma, · 512 unmodified lines
513 513
514 uprobe = container_of(auprobe, struct uprobe, arch);514 uprobe = container_of(auprobe, struct uprobe, arch);
515 515
516 if (WARN_ON_ONCE(!is_cow_mapping(vma->vm_flags)))516 if (WARN_ON_ONCE(!vma_is_cow_mapping(vma)))
517 return -EINVAL;517 return -EINVAL;
518 518
519 /*519 /*
kernel/locking/lockdep.c+51−7
@@ -5093,7 +5093,7 @@ static int __lock_is_held(const struct lockdep_map *lock, int read); · 5092 unmodified lines
5093static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,5093static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
5094 int trylock, int read, int check, int hardirqs_off,5094 int trylock, int read, int check, int hardirqs_off,
5095 struct lockdep_map *nest_lock, unsigned long ip,5095 struct lockdep_map *nest_lock, unsigned long ip,
5096 int references, int pin_count, int sync)5096 int references, int pin_count, int sync, int seq)
5097{5097{
5098 struct task_struct *curr = current;5098 struct task_struct *curr = current;
5099 struct lock_class *class = NULL;5099 struct lock_class *class = NULL;
@@ -5199,6 +5199,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass, · 99 unmodified lines
5199 hlock->holdtime_stamp = lockstat_clock();5199 hlock->holdtime_stamp = lockstat_clock();
5200#endif5200#endif
5201 hlock->pin_count = pin_count;5201 hlock->pin_count = pin_count;
5202 hlock->seq_count = seq;
5202 5203
5203 if (check_wait_context(curr, hlock))5204 if (check_wait_context(curr, hlock))
5204 return 0;5205 return 0;
@@ -5404,7 +5405,7 @@ static int reacquire_held_locks(struct task_struct *curr, unsigned int depth, · 199 unmodified lines
5404 hlock->read, hlock->check,5405 hlock->read, hlock->check,
5405 hlock->hardirqs_off,5406 hlock->hardirqs_off,
5406 hlock->nest_lock, hlock->acquire_ip,5407 hlock->nest_lock, hlock->acquire_ip,
5407 hlock->references, hlock->pin_count, 0)) {5408 hlock->references, hlock->pin_count, 0, hlock->seq_count)) {
5408 case 0:5409 case 0:
5409 return 1;5410 return 1;
5410 case 1:5411 case 1:
@@ -5687,14 +5688,17 @@ static void __lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie cookie · 276 unmodified lines
5687 struct held_lock *hlock = curr->held_locks + i;5688 struct held_lock *hlock = curr->held_locks + i;
5688 5689
5689 if (match_held_lock(hlock, lock)) {5690 if (match_held_lock(hlock, lock)) {
5691 int pin_count;
5692
5690 if (WARN(!hlock->pin_count, "unpinning an unpinned lock\n"))5693 if (WARN(!hlock->pin_count, "unpinning an unpinned lock\n"))
5691 return;5694 return;
5692 5695
5693 hlock->pin_count -= cookie.val;5696 pin_count = hlock->pin_count - cookie.val;
5694 5697
5695 if (WARN((int)hlock->pin_count < 0, "pin count corrupted\n"))5698 if (WARN(pin_count < 0, "pin count corrupted\n"))
5696 hlock->pin_count = 0;5699 pin_count = 0;
5697 5700
5701 hlock->pin_count = pin_count;
5698 return;5702 return;
5699 }5703 }
5700 }5704 }
@@ -5702,6 +5706,24 @@ static void __lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie cookie · 1 unmodified line
5702 WARN(1, "unpinning an unheld lock\n");5706 WARN(1, "unpinning an unheld lock\n");
5703}5707}
5704 5708
5709static u32 __lock_sequence(struct lockdep_map *lock)
5710{
5711 struct task_struct *curr = current;
5712 int i;
5713
5714 if (unlikely(!debug_locks))
5715 return ~0;
5716
5717 for (i = 0; i < curr->lockdep_depth; i++) {
5718 struct held_lock *hlock = curr->held_locks + i;
5719
5720 if (match_held_lock(hlock, lock))
5721 return hlock->seq_count;
5722 }
5723
5724 return ~0;
5725}
5726
5705/*5727/*
5706 * Check whether we follow the irq-flags state precisely:5728 * Check whether we follow the irq-flags state precisely:
5707 */5729 */
@@ -5884,7 +5906,8 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass, · 176 unmodified lines
5884 5906
5885 lockdep_recursion_inc();5907 lockdep_recursion_inc();
5886 __lock_acquire(lock, subclass, trylock, read, check,5908 __lock_acquire(lock, subclass, trylock, read, check,
5887 irqs_disabled_flags(flags), nest_lock, ip, 0, 0, 0);5909 irqs_disabled_flags(flags), nest_lock, ip, 0, 0, 0,
5910 ++current->lockdep_seq);
5888 lockdep_recursion_finish();5911 lockdep_recursion_finish();
5889 raw_local_irq_restore(flags);5912 raw_local_irq_restore(flags);
5890}5913}
@@ -5932,7 +5955,8 @@ void lock_sync(struct lockdep_map *lock, unsigned subclass, int read, · 41 unmodified lines
5932 5955
5933 lockdep_recursion_inc();5956 lockdep_recursion_inc();
5934 __lock_acquire(lock, subclass, 0, read, check,5957 __lock_acquire(lock, subclass, 0, read, check,
5935 irqs_disabled_flags(flags), nest_lock, ip, 0, 0, 1);5958 irqs_disabled_flags(flags), nest_lock, ip, 0, 0, 1,
5959 ++current->lockdep_seq);
5936 check_chain_key(current);5960 check_chain_key(current);
5937 lockdep_recursion_finish();5961 lockdep_recursion_finish();
5938 raw_local_irq_restore(flags);5962 raw_local_irq_restore(flags);
@@ -6018,6 +6042,26 @@ void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie cookie) · 79 unmodified lines
6018}6042}
6019EXPORT_SYMBOL_GPL(lock_unpin_lock);6043EXPORT_SYMBOL_GPL(lock_unpin_lock);
6020 6044
6045u32 lock_sequence(struct lockdep_map *lock)
6046{
6047 unsigned long flags;
6048 u32 seq = ~0;
6049
6050 if (unlikely(!lockdep_enabled()))
6051 return seq;
6052
6053 raw_local_irq_save(flags);
6054 check_flags(flags);
6055
6056 lockdep_recursion_inc();
6057 seq = __lock_sequence(lock);
6058 lockdep_recursion_finish();
6059 raw_local_irq_restore(flags);
6060
6061 return seq;
6062}
6063EXPORT_SYMBOL_GPL(lock_sequence);
6064
6021#ifdef CONFIG_LOCK_STAT6065#ifdef CONFIG_LOCK_STAT
6022static void print_lock_contention_bug(struct task_struct *curr,6066static void print_lock_contention_bug(struct task_struct *curr,
6023 struct lockdep_map *lock,6067 struct lockdep_map *lock,
lib/Kconfig.debug+0−15
@@ -613,21 +613,6 @@ config BUILTIN_MODULE_RANGES · 612 unmodified lines
613 It also records an anchor symbol to determine the load address of the613 It also records an anchor symbol to determine the load address of the
614 section.614 section.
615 615
616config DEBUG_FORCE_WEAK_PER_CPU
617 bool "Force weak per-cpu definitions"
618 depends on DEBUG_KERNEL
619 help
620 s390 and alpha require percpu variables in modules to be
621 defined weak to work around addressing range issue which
622 puts the following two restrictions on percpu variable
623 definitions.
624
625 1. percpu symbols must be unique whether static or not
626 2. percpu variables can't be defined inside a function
627
628 To ensure that generic code follows the above rules, this
629 option forces all percpu variables to be defined as weak.
630
631config WARN_CONTEXT_ANALYSIS616config WARN_CONTEXT_ANALYSIS
632 bool "Compiler context-analysis warnings"617 bool "Compiler context-analysis warnings"
633 depends on CC_IS_CLANG && CLANG_VERSION >= 230000618 depends on CC_IS_CLANG && CLANG_VERSION >= 230000
lib/codetag.c+18−0
@@ -19,6 +19,8 @@ struct codetag_type { · 18 unmodified lines
19 struct codetag_type_desc desc;19 struct codetag_type_desc desc;
20 /* generates unique sequence number for module load */20 /* generates unique sequence number for module load */
21 unsigned long next_mod_seq;21 unsigned long next_mod_seq;
22 /* bumped on every module load and unload */
23 unsigned long content_id;
22};24};
23 25
24struct codetag_range {26struct codetag_range {
@@ -50,6 +52,20 @@ void codetag_unlock_module_list(struct codetag_type *cttype) · 25 unmodified lines
50 up_read(&cttype->mod_lock);52 up_read(&cttype->mod_lock);
51}53}
52 54
55unsigned long codetag_get_content_id(struct codetag_type *cttype)
56{
57 lockdep_assert_held(&cttype->mod_lock);
58
59 return cttype->content_id;
60}
61
62unsigned int codetag_get_count(struct codetag_type *cttype)
63{
64 lockdep_assert_held(&cttype->mod_lock);
65
66 return cttype->count;
67}
68
53struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype)69struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype)
54{70{
55 struct codetag_iterator iter = {71 struct codetag_iterator iter = {
@@ -204,6 +220,7 @@ static int codetag_module_init(struct codetag_type *cttype, struct module *mod) · 148 unmodified lines
204 220
205 down_write(&cttype->mod_lock);221 down_write(&cttype->mod_lock);
206 cmod->mod_seq = ++cttype->next_mod_seq;222 cmod->mod_seq = ++cttype->next_mod_seq;
223 ++cttype->content_id;
207 mod_id = idr_alloc(&cttype->mod_idr, cmod, 0, 0, GFP_KERNEL);224 mod_id = idr_alloc(&cttype->mod_idr, cmod, 0, 0, GFP_KERNEL);
208 if (mod_id >= 0) {225 if (mod_id >= 0) {
209 if (cttype->desc.module_load) {226 if (cttype->desc.module_load) {
@@ -368,6 +385,7 @@ void codetag_unload_module(struct module *mod) · 158 unmodified lines
368 cttype->count -= range_size(cttype, &cmod->range);385 cttype->count -= range_size(cttype, &cmod->range);
369 idr_remove(&cttype->mod_idr, mod_id);386 idr_remove(&cttype->mod_idr, mod_id);
370 kfree(cmod);387 kfree(cmod);
388 ++cttype->content_id;
371 }389 }
372 up_write(&cttype->mod_lock);390 up_write(&cttype->mod_lock);
373 if (found && cttype->desc.free_section_mem)391 if (found && cttype->desc.free_section_mem)
lib/maple_tree.c+280−121
@@ -261,6 +261,12 @@ static inline bool mas_is_underflow(struct ma_state *mas) · 260 unmodified lines
261 return mas->status == ma_underflow;261 return mas->status == ma_underflow;
262}262}
263 263
264static inline void mas_make_walkable(struct ma_state *mas)
265{
266 if (!mas_is_active(mas) && !mas_is_start(mas))
267 mas->status = ma_start;
268}
269
264static __always_inline struct maple_node *mte_to_node(270static __always_inline struct maple_node *mte_to_node(
265 const struct maple_enode *entry)271 const struct maple_enode *entry)
266{272{
@@ -356,11 +362,6 @@ static __always_inline bool mte_is_root(const struct maple_enode *node) · 89 unmodified lines
356 return ma_is_root(mte_to_node(node));362 return ma_is_root(mte_to_node(node));
357}363}
358 364
359static inline bool mas_is_root_limits(const struct ma_state *mas)
360{
361 return !mas->min && mas->max == ULONG_MAX;
362}
363
364static __always_inline bool mt_is_alloc(struct maple_tree *mt)365static __always_inline bool mt_is_alloc(struct maple_tree *mt)
365{366{
366 return (mt->ma_flags & MT_FLAGS_ALLOC_RANGE);367 return (mt->ma_flags & MT_FLAGS_ALLOC_RANGE);
@@ -455,46 +456,6 @@ enum maple_type mas_parent_type(struct ma_state *mas, struct maple_enode *enode) · 88 unmodified lines
455 return 0;456 return 0;
456}457}
457 458
458/*
459 * mas_set_parent() - Set the parent node and encode the slot
460 * @mas: The maple state
461 * @enode: The encoded maple node.
462 * @parent: The encoded maple node that is the parent of @enode.
463 * @slot: The slot that @enode resides in @parent.
464 *
465 * Slot number is encoded in the enode->parent bit 3-6 or 2-6, depending on the
466 * parent type.
467 */
468static inline
469void mas_set_parent(struct ma_state *mas, struct maple_enode *enode,
470 const struct maple_enode *parent, unsigned char slot)
471{
472 unsigned long val = (unsigned long)parent;
473 unsigned long shift;
474 unsigned long type;
475 enum maple_type p_type = mte_node_type(parent);
476
477 MAS_BUG_ON(mas, p_type == maple_dense);
478 MAS_BUG_ON(mas, p_type == maple_leaf_64);
479
480 switch (p_type) {
481 case maple_range_64:
482 case maple_arange_64:
483 shift = MAPLE_PARENT_SLOT_SHIFT;
484 type = MAPLE_PARENT_RANGE64;
485 break;
486 default:
487 case maple_dense:
488 case maple_leaf_64:
489 shift = type = 0;
490 break;
491 }
492
493 val &= ~MAPLE_NODE_MASK; /* Clear all node metadata in parent */
494 val |= (slot << shift) | type;
495 mte_to_node(enode)->parent = ma_parent_ptr(val);
496}
497
498/*459/*
499 * mte_parent_slot() - get the parent slot of @enode.460 * mte_parent_slot() - get the parent slot of @enode.
500 * @enode: The encoded maple node.461 * @enode: The encoded maple node.
@@ -876,6 +837,42 @@ static inline void ma_set_meta_gap(struct maple_node *mn, enum maple_type mt, · 375 unmodified lines
876 meta->gap = offset;837 meta->gap = offset;
877}838}
878 839
840/*
841 * mas_set_parent_slots() - Bulk operation to set many slot parent pointers
842 * @mas: The maple state
843 * @parent: The encoded maple node that is the parent of @enode.
844 * @slot: The slot that of the @enode.
845 * @start_slot: The offset into @slot
846 * @count: The number of slots to set (eg: exclusive)
847 */
848static inline
849void mas_set_parent_slots(struct ma_state *mas, struct maple_enode *parent,
850 void __rcu **slots, unsigned char start_slot, unsigned char count)
851{
852 unsigned long val;
853 unsigned long shift;
854 unsigned long type;
855 enum maple_type p_type = mte_node_type(parent);
856 unsigned char i;
857
858 MAS_BUG_ON(mas, p_type != maple_range_64 &&
859 p_type != maple_arange_64);
860
861 shift = MAPLE_PARENT_SLOT_SHIFT;
862 type = MAPLE_PARENT_RANGE64;
863
864 val = (unsigned long)parent;
865 val &= ~MAPLE_NODE_MASK;
866
867 for (i = 0; i < count; i++) {
868 unsigned long pval = val | ((start_slot + i) << shift) | type;
869 struct maple_enode *child;
870
871 child = mt_slot_locked(mas->tree, slots, i);
872 mte_to_node(child)->parent = ma_parent_ptr(pval);
873 }
874}
875
879/*876/*
880 * mat_add() - Add a @dead_enode to the ma_topiary of a list of dead nodes.877 * mat_add() - Add a @dead_enode to the ma_topiary of a list of dead nodes.
881 * @mat: the ma_topiary, a linked list of dead nodes.878 * @mat: the ma_topiary, a linked list of dead nodes.
@@ -1153,6 +1150,79 @@ static inline void mas_free(struct ma_state *mas, struct maple_enode *used) · 271 unmodified lines
1153 ma_free_rcu(mte_to_node(used));1150 ma_free_rcu(mte_to_node(used));
1154}1151}
1155 1152
1153
1154#ifdef CONFIG_LOCKDEP
1155static struct lockdep_map *mas_lockdep_map(struct ma_state *mas)
1156{
1157 struct maple_tree *mt = mas->tree;
1158
1159 if (mt_external_lock(mt))
1160 return mt->ma_external_lock;
1161
1162 return &(mt->ma_lock).dep_map;
1163}
1164
1165#endif
1166
1167static void mas_lock_check(struct ma_state *mas)
1168{
1169#ifdef CONFIG_LOCKDEP
1170 struct lockdep_map *map;
1171 u32 seq;
1172
1173 if (!mas_is_active(mas))
1174 return;
1175
1176#ifdef CONFIG_RCU_STRICT_GRACE_PERIOD
1177 if (!mt_locked(mas->tree)) {
1178 if (mt_in_rcu(mas->tree))
1179 WARN_ON_ONCE(poll_state_synchronize_rcu(mas->rcu_gp));
1180 }
1181#endif /* CONFIG_RCU_STRICT_GRACE_PERIOD */
1182
1183 map = mas_lockdep_map(mas);
1184 if (!map)
1185 return;
1186
1187 seq = lock_sequence(map);
1188 if (seq != UINT_MAX && mas->ld_seq != UINT_MAX)
1189 WARN_ON_ONCE(mas->ld_seq != seq);
1190#endif /* CONFIG_LOCKDEP */
1191
1192}
1193
1194static void mas_init_lock_check(struct ma_state *mas)
1195{
1196#ifdef CONFIG_LOCKDEP
1197 struct lockdep_map *map;
1198#ifdef CONFIG_RCU_STRICT_GRACE_PERIOD
1199 if (!mt_locked(mas->tree)) {
1200 if (mt_in_rcu(mas->tree))
1201 mas->rcu_gp = get_state_synchronize_rcu();
1202 return;
1203 }
1204#endif /* CONFIG_RCU_STRICT_GRACE_PERIOD */
1205
1206 map = mas_lockdep_map(mas);
1207 if (map) /* Update regardless of lock state */
1208 mas->ld_seq = lock_sequence(map);
1209#endif /* CONFIG_LOCKDEP */
1210
1211}
1212
1213static void mas_may_init_lock_check(struct ma_state *mas)
1214{
1215#ifdef CONFIG_LOCKDEP
1216#ifdef CONFIG_RCU_STRICT_GRACE_PERIOD
1217 if (mas_is_start(mas) || mas_is_paused(mas)) {
1218 mas_init_lock_check(mas);
1219 return;
1220 }
1221#endif /* CONFIG_RCU_STRICT_GRACE_PERIOD */
1222 mas_lock_check(mas);
1223#endif /* CONFIG_LOCKDEP */
1224}
1225
1156/*1226/*
1157 * mas_start() - Sets up maple state for operations.1227 * mas_start() - Sets up maple state for operations.
1158 * @mas: The maple state.1228 * @mas: The maple state.
@@ -1171,6 +1241,7 @@ static inline struct maple_enode *mas_start(struct ma_state *mas) · 12 unmodified lines
1171 if (likely(mas_is_start(mas))) {1241 if (likely(mas_is_start(mas))) {
1172 struct maple_enode *root;1242 struct maple_enode *root;
1173 1243
1244 mas_init_lock_check(mas);
1174 mas->min = 0;1245 mas->min = 0;
1175 mas->max = ULONG_MAX;1246 mas->max = ULONG_MAX;
1176 1247
@@ -1501,14 +1572,26 @@ ascend: · 324 unmodified lines
1501 goto ascend;1572 goto ascend;
1502}1573}
1503 1574
1575static __always_inline void mas_update_gap_known(struct ma_state *mas,
1576 unsigned long gap)
1577{
1578 unsigned char pslot;
1579 unsigned long p_gap;
1580
1581 pslot = mte_parent_slot(mas->node);
1582 p_gap = ma_gaps(mte_parent(mas->node),
1583 mas_parent_type(mas, mas->node))[pslot];
1584
1585 if (p_gap != gap)
1586 mas_parent_gap(mas, pslot, gap);
1587}
1588
1504/*1589/*
1505 * mas_update_gap() - Update a nodes gaps and propagate up if necessary.1590 * mas_update_gap() - Update a nodes gaps and propagate up if necessary.
1506 * @mas: the maple state.1591 * @mas: the maple state.
1507 */1592 */
1508static inline void mas_update_gap(struct ma_state *mas)1593static inline void mas_update_gap(struct ma_state *mas)
1509{1594{
1510 unsigned char pslot;
1511 unsigned long p_gap;
1512 unsigned long max_gap;1595 unsigned long max_gap;
1513 1596
1514 if (!mt_is_alloc(mas->tree))1597 if (!mt_is_alloc(mas->tree))
@@ -1518,13 +1601,7 @@ static inline void mas_update_gap(struct ma_state *mas) · 3 unmodified lines
1518 return;1601 return;
1519 1602
1520 max_gap = mas_max_gap(mas);1603 max_gap = mas_max_gap(mas);
1521 1604 mas_update_gap_known(mas, max_gap);
1522 pslot = mte_parent_slot(mas->node);
1523 p_gap = ma_gaps(mte_parent(mas->node),
1524 mas_parent_type(mas, mas->node))[pslot];
1525
1526 if (p_gap != max_gap)
1527 mas_parent_gap(mas, pslot, max_gap);
1528}1605}
1529 1606
1530/*1607/*
@@ -1540,14 +1617,10 @@ static inline void mas_adopt_children(struct ma_state *mas, · 9 unmodified lines
1540 struct maple_node *node = mte_to_node(parent);1617 struct maple_node *node = mte_to_node(parent);
1541 void __rcu **slots = ma_slots(node, type);1618 void __rcu **slots = ma_slots(node, type);
1542 unsigned long *pivots = ma_pivots(node, type);1619 unsigned long *pivots = ma_pivots(node, type);
1543 struct maple_enode *child;1620 unsigned char end;
1544 unsigned char offset;
1545 1621
1546 offset = ma_data_end(node, type, pivots, mas->max);1622 end = ma_data_end(node, type, pivots, mas->max);
1547 do {1623 mas_set_parent_slots(mas, parent, slots, 0, end + 1);
1548 child = mas_slot_locked(mas, slots, offset);
1549 mas_set_parent(mas, child, parent, offset);
1550 } while (offset--);
1551}1624}
1552 1625
1553/*1626/*
@@ -1929,15 +2002,10 @@ unsigned long node_copy(struct ma_state *mas, struct maple_node *src, · 375 unmodified lines
1929 s_slots = ma_slots(src, s_mt) + start;2002 s_slots = ma_slots(src, s_mt) + start;
1930 s_pivots = ma_pivots(src, s_mt) + start;2003 s_pivots = ma_pivots(src, s_mt) + start;
1931 memcpy(d_slots, s_slots, size * sizeof(void __rcu *));2004 memcpy(d_slots, s_slots, size * sizeof(void __rcu *));
1932 if (!ma_is_leaf(d_mt) && s_mt == maple_copy) {
1933 struct maple_enode *edst = mt_mk_node(dst, d_mt);
1934
1935 2005
1936 for (int i = 0; i < size; i++)2006 if (!ma_is_leaf(d_mt) && s_mt == maple_copy)
1937 mas_set_parent(mas,2007 mas_set_parent_slots(mas, mt_mk_node(dst, d_mt),
1938 mt_slot_locked(mas->tree, d_slots, i),2008 d_slots, d_start, size);
1939 edst, d_start + i);
1940 }
1941 2009
1942 d_gaps = ma_gaps(dst, d_mt);2010 d_gaps = ma_gaps(dst, d_mt);
1943 if (d_gaps) {2011 if (d_gaps) {
@@ -2081,8 +2149,8 @@ static inline void mas_wmb_replace(struct ma_state *mas, struct maple_copy *cp) · 137 unmodified lines
2081 mas->node = mt_slot_locked(mas->tree, cp->slot, 0);2149 mas->node = mt_slot_locked(mas->tree, cp->slot, 0);
2082 /* Insert the new data in the tree */2150 /* Insert the new data in the tree */
2083 mas_topiary_replace(mas, old_enode, cp->height);2151 mas_topiary_replace(mas, old_enode, cp->height);
2084 if (!mte_is_leaf(mas->node))2152 if (mt_is_alloc(mas->tree) && !mte_is_root(mas->node))
2085 mas_update_gap(mas);2153 mas_update_gap_known(mas, cp->gap[0]);
2086 2154
2087 mtree_range_walk(mas);2155 mtree_range_walk(mas);
2088}2156}
@@ -2928,13 +2996,6 @@ static inline void mas_extend_spanning_null(struct ma_wr_state *l_wr_mas, · 839 unmodified lines
2928 if (r_mas->last < r_wr_mas->r_max)2996 if (r_mas->last < r_wr_mas->r_max)
2929 r_mas->last = r_wr_mas->r_max;2997 r_mas->last = r_wr_mas->r_max;
2930 r_mas->offset++;2998 r_mas->offset++;
2931 } else if ((r_mas->last == r_wr_mas->r_max) &&
2932 (r_mas->last < r_mas->max) &&
2933 !mas_slot_locked(r_mas, r_wr_mas->slots, r_mas->offset + 1)) {
2934 r_mas->last = mas_safe_pivot(r_mas, r_wr_mas->pivots,
2935 r_wr_mas->type, r_mas->offset + 1);
2936 r_mas->offset++;
2937 r_wr_mas->r_max = r_mas->last;
2938 }2999 }
2939}3000}
2940 3001
@@ -3125,7 +3186,7 @@ static void mas_wr_spanning_store(struct ma_wr_state *wr_mas) · 184 unmodified lines
3125static inline void mas_wr_node_store(struct ma_wr_state *wr_mas)3186static inline void mas_wr_node_store(struct ma_wr_state *wr_mas)
3126{3187{
3127 unsigned char dst_offset, offset_end;3188 unsigned char dst_offset, offset_end;
3128 unsigned char copy_size, node_pivots;3189 unsigned char copy_size, node_pivots, node_slots;
3129 struct maple_node reuse, *newnode;3190 struct maple_node reuse, *newnode;
3130 unsigned long *dst_pivots;3191 unsigned long *dst_pivots;
3131 void __rcu **dst_slots;3192 void __rcu **dst_slots;
@@ -3138,6 +3199,7 @@ static inline void mas_wr_node_store(struct ma_wr_state *wr_mas) · 6 unmodified lines
3138 in_rcu = mt_in_rcu(mas->tree);3199 in_rcu = mt_in_rcu(mas->tree);
3139 offset_end = wr_mas->offset_end;3200 offset_end = wr_mas->offset_end;
3140 node_pivots = mt_pivots[wr_mas->type];3201 node_pivots = mt_pivots[wr_mas->type];
3202 node_slots = mt_slots[wr_mas->type];
3141 /* Assume last adds an entry */3203 /* Assume last adds an entry */
3142 new_end = mas->end + 1 - offset_end + mas->offset;3204 new_end = mas->end + 1 - offset_end + mas->offset;
3143 if (mas->last == wr_mas->end_piv) {3205 if (mas->last == wr_mas->end_piv) {
@@ -3149,7 +3211,6 @@ static inline void mas_wr_node_store(struct ma_wr_state *wr_mas) · 5 unmodified lines
3149 if (in_rcu) {3211 if (in_rcu) {
3150 newnode = mas_pop_node(mas);3212 newnode = mas_pop_node(mas);
3151 } else {3213 } else {
3152 memset(&reuse, 0, sizeof(struct maple_node));
3153 newnode = &reuse;3214 newnode = &reuse;
3154 }3215 }
3155 3216
@@ -3193,7 +3254,21 @@ static inline void mas_wr_node_store(struct ma_wr_state *wr_mas) · 37 unmodified lines
3193 dst_pivots[new_end] = mas->max;3254 dst_pivots[new_end] = mas->max;
3194 3255
3195done:3256done:
3196 mas_leaf_set_meta(newnode, maple_leaf_64, new_end);3257 if (!in_rcu && new_end + 2 < node_slots) {
3258 unsigned char clear_from = new_end + 1;
3259
3260 /*
3261 * Note that the last slot is never cleared, since the metadata
3262 * will be stored there or it has a value.
3263 */
3264 memset(dst_slots + clear_from, 0,
3265 sizeof(void __rcu *) * (node_slots - clear_from));
3266 if (clear_from < node_pivots)
3267 memset(dst_pivots + clear_from, 0,
3268 sizeof(unsigned long) * (node_pivots - clear_from));
3269 }
3270
3271 mas_leaf_set_meta(newnode, wr_mas->type, new_end);
3197 if (in_rcu) {3272 if (in_rcu) {
3198 struct maple_enode *old_enode = mas->node;3273 struct maple_enode *old_enode = mas->node;
3199 3274
@@ -3218,7 +3293,7 @@ static inline void mas_wr_slot_store(struct ma_wr_state *wr_mas) · 18 unmodified lines
3218 void __rcu **slots = wr_mas->slots;3293 void __rcu **slots = wr_mas->slots;
3219 bool gap = false;3294 bool gap = false;
3220 3295
3221 gap |= !mt_slot_locked(mas->tree, slots, offset);3296 gap |= !wr_mas->content;
3222 gap |= !mt_slot_locked(mas->tree, slots, offset + 1);3297 gap |= !mt_slot_locked(mas->tree, slots, offset + 1);
3223 3298
3224 if (wr_mas->offset_end - offset == 1) {3299 if (wr_mas->offset_end - offset == 1) {
@@ -3595,7 +3670,7 @@ set_content: · 370 unmodified lines
3595 3670
3596/**3671/**
3597 * mas_prealloc_calc() - Calculate number of nodes needed for a3672 * mas_prealloc_calc() - Calculate number of nodes needed for a
3598 * given store oepration3673 * given store operation
3599 * @wr_mas: The maple write state3674 * @wr_mas: The maple write state
3600 * @entry: The entry to store into the tree3675 * @entry: The entry to store into the tree
3601 *3676 *
@@ -3661,6 +3736,9 @@ static inline enum store_type mas_wr_store_type(struct ma_wr_state *wr_mas) · 59 unmodified lines
3661{3736{
3662 struct ma_state *mas = wr_mas->mas;3737 struct ma_state *mas = wr_mas->mas;
3663 unsigned char new_end;3738 unsigned char new_end;
3739 bool appending;
3740 bool one_slot;
3741 bool in_rcu;
3664 3742
3665 if (unlikely(mas_is_none(mas) || mas_is_ptr(mas)))3743 if (unlikely(mas_is_none(mas) || mas_is_ptr(mas)))
3666 return wr_store_root;3744 return wr_store_root;
@@ -3680,21 +3758,30 @@ static inline enum store_type mas_wr_store_type(struct ma_wr_state *wr_mas) · 13 unmodified lines
3680 return wr_new_root;3758 return wr_new_root;
3681 3759
3682 new_end = mas_wr_new_end(wr_mas);3760 new_end = mas_wr_new_end(wr_mas);
3761 in_rcu = mt_in_rcu(mas->tree);
3762 appending = mas->offset == mas->end;
3763 one_slot = wr_mas->offset_end - mas->offset == 1;
3764
3683 /* Potential spanning rebalance collapsing a node */3765 /* Potential spanning rebalance collapsing a node */
3684 if (new_end < mt_min_slots[wr_mas->type]) {3766 if (new_end < mt_min_slots[wr_mas->type]) {
3685 if (!mte_is_root(mas->node))3767 if (!mte_is_root(mas->node))
3686 return wr_rebalance;3768 return wr_rebalance;
3769 if (!in_rcu) {
3770 if (appending)
3771 return wr_append;
3772 else if (mas->end == new_end && one_slot)
3773 return wr_slot_store;
3774 }
3687 return wr_node_store;3775 return wr_node_store;
3688 }3776 }
3689 3777
3690 if (new_end >= mt_slots[wr_mas->type])3778 if (new_end >= mt_slots[wr_mas->type])
3691 return wr_split_store;3779 return wr_split_store;
3692 3780
3693 if (!mt_in_rcu(mas->tree) && (mas->offset == mas->end))3781 if (!in_rcu && appending)
3694 return wr_append;3782 return wr_append;
3695 3783
3696 if ((new_end == mas->end) && (!mt_in_rcu(mas->tree) ||3784 if (new_end == mas->end && (!in_rcu || one_slot))
3697 (wr_mas->offset_end - mas->offset == 1)))
3698 return wr_slot_store;3785 return wr_slot_store;
3699 3786
3700 return wr_node_store;3787 return wr_node_store;
@@ -3793,35 +3880,40 @@ int mas_alloc_cyclic(struct ma_state *mas, unsigned long *startp, · 92 unmodified lines
3793 void *entry, unsigned long range_lo, unsigned long range_hi,3880 void *entry, unsigned long range_lo, unsigned long range_hi,
3794 unsigned long *next, gfp_t gfp)3881 unsigned long *next, gfp_t gfp)
3795{3882{
3796 unsigned long min = range_lo;3883 int ret;
3797 int ret = 0;3884 unsigned long min;
3798
3799 range_lo = max(min, *next);
3800 ret = mas_empty_area(mas, range_lo, range_hi, 1);
3801 if ((mas->tree->ma_flags & MT_FLAGS_ALLOC_WRAPPED) && ret == 0) {
3802 mas->tree->ma_flags &= ~MT_FLAGS_ALLOC_WRAPPED;
3803 ret = 1;
3804 }
3805 if (ret < 0 && range_lo > min) {
3806 mas_reset(mas);
3807 ret = mas_empty_area(mas, min, range_hi, 1);
3808 if (ret == 0)
3809 ret = 1;
3810 }
3811 if (ret < 0)
3812 return ret;
3813 3885
3886 min = range_lo;
3814 do {3887 do {
3888 range_lo = max(min, *next);
3889 ret = mas_empty_area(mas, range_lo, range_hi, 1);
3890 if (ret < 0 && range_lo > min) {
3891 mas_reset(mas);
3892 ret = mas_empty_area(mas, min, range_hi, 1);
3893 if (ret == 0)
3894 ret = 1;
3895 }
3896 if (ret < 0)
3897 goto out;
3898
3815 mas_insert(mas, entry);3899 mas_insert(mas, entry);
3816 } while (mas_nomem(mas, gfp));3900 } while (mas_nomem(mas, gfp));
3817 if (mas_is_err(mas))
3818 return xa_err(mas->node);
3819 3901
3902 if (mas_is_err(mas)) {
3903 ret = xa_err(mas->node);
3904 goto out;
3905 }
3906
3907 if ((mas->tree->ma_flags & MT_FLAGS_ALLOC_WRAPPED) && ret == 0) {
3908 mas->tree->ma_flags &= ~MT_FLAGS_ALLOC_WRAPPED;
3909 ret = 1;
3910 }
3820 *startp = mas->index;3911 *startp = mas->index;
3821 *next = *startp + 1;3912 *next = *startp + 1;
3822 if (*next == 0)3913 if (*next == 0)
3823 mas->tree->ma_flags |= MT_FLAGS_ALLOC_WRAPPED;3914 mas->tree->ma_flags |= MT_FLAGS_ALLOC_WRAPPED;
3824 3915
3916out:
3825 mas_destroy(mas);3917 mas_destroy(mas);
3826 return ret;3918 return ret;
3827}3919}
@@ -4360,8 +4452,8 @@ void *mas_walk(struct ma_state *mas) · 532 unmodified lines
4360{4452{
4361 void *entry;4453 void *entry;
4362 4454
4363 if (!mas_is_active(mas) && !mas_is_start(mas))4455 mas_may_init_lock_check(mas);
4364 mas->status = ma_start;4456 mas_make_walkable(mas);
4365retry:4457retry:
4366 entry = mas_state_walk(mas);4458 entry = mas_state_walk(mas);
4367 if (mas_is_start(mas)) {4459 if (mas_is_start(mas)) {
@@ -4831,6 +4923,7 @@ void *mas_store(struct ma_state *mas, void *entry) · 463 unmodified lines
4831{4923{
4832 MA_WR_STATE(wr_mas, mas, entry);4924 MA_WR_STATE(wr_mas, mas, entry);
4833 4925
4926 mas_may_init_lock_check(mas);
4834 trace_ma_write(TP_FCT, mas, 0, entry);4927 trace_ma_write(TP_FCT, mas, 0, entry);
4835#ifdef CONFIG_DEBUG_MAPLE_TREE4928#ifdef CONFIG_DEBUG_MAPLE_TREE
4836 if (MAS_WARN_ON(mas, mas->index > mas->last))4929 if (MAS_WARN_ON(mas, mas->index > mas->last))
@@ -4889,6 +4982,7 @@ int mas_store_gfp(struct ma_state *mas, void *entry, gfp_t gfp) · 52 unmodified lines
4889 MA_WR_STATE(wr_mas, mas, entry);4982 MA_WR_STATE(wr_mas, mas, entry);
4890 int ret = 0;4983 int ret = 0;
4891 4984
4985 mas_may_init_lock_check(mas);
4892retry:4986retry:
4893 mas_wr_preallocate(&wr_mas, entry);4987 mas_wr_preallocate(&wr_mas, entry);
4894 if (unlikely(mas_nomem(mas, gfp))) {4988 if (unlikely(mas_nomem(mas, gfp))) {
@@ -4919,6 +5013,7 @@ void mas_store_prealloc(struct ma_state *mas, void *entry) · 24 unmodified lines
4919{5013{
4920 MA_WR_STATE(wr_mas, mas, entry);5014 MA_WR_STATE(wr_mas, mas, entry);
4921 5015
5016 mas_lock_check(mas);
4922 if (mas->store_type == wr_store_root) {5017 if (mas->store_type == wr_store_root) {
4923 mas_wr_prealloc_setup(&wr_mas);5018 mas_wr_prealloc_setup(&wr_mas);
4924 goto store;5019 goto store;
@@ -4951,6 +5046,7 @@ int mas_preallocate(struct ma_state *mas, void *entry, gfp_t gfp) · 26 unmodified lines
4951{5046{
4952 MA_WR_STATE(wr_mas, mas, entry);5047 MA_WR_STATE(wr_mas, mas, entry);
4953 5048
5049 mas_may_init_lock_check(mas);
4954 mas_wr_prealloc_setup(&wr_mas);5050 mas_wr_prealloc_setup(&wr_mas);
4955 mas->store_type = mas_wr_store_type(&wr_mas);5051 mas->store_type = mas_wr_store_type(&wr_mas);
4956 mas_prealloc_calc(&wr_mas, entry);5052 mas_prealloc_calc(&wr_mas, entry);
@@ -4997,6 +5093,7 @@ static void mas_may_activate(struct ma_state *mas) · 40 unmodified lines
4997 mas->status = ma_start;5093 mas->status = ma_start;
4998 } else {5094 } else {
4999 mas->status = ma_active;5095 mas->status = ma_active;
5096 mas_lock_check(mas);
5000 }5097 }
5001}5098}
5002 5099
@@ -5074,6 +5171,7 @@ void *mas_next(struct ma_state *mas, unsigned long max) · 71 unmodified lines
5074{5171{
5075 void *entry = NULL;5172 void *entry = NULL;
5076 5173
5174 mas_may_init_lock_check(mas);
5077 if (mas_next_setup(mas, max, &entry))5175 if (mas_next_setup(mas, max, &entry))
5078 return entry;5176 return entry;
5079 5177
@@ -5097,6 +5195,7 @@ void *mas_next_range(struct ma_state *mas, unsigned long max) · 17 unmodified lines
5097{5195{
5098 void *entry = NULL;5196 void *entry = NULL;
5099 5197
5198 mas_may_init_lock_check(mas);
5100 if (mas_next_setup(mas, max, &entry))5199 if (mas_next_setup(mas, max, &entry))
5101 return entry;5200 return entry;
5102 5201
@@ -5205,6 +5304,7 @@ void *mas_prev(struct ma_state *mas, unsigned long min) · 102 unmodified lines
5205{5304{
5206 void *entry = NULL;5305 void *entry = NULL;
5207 5306
5307 mas_may_init_lock_check(mas);
5208 if (mas_prev_setup(mas, min, &entry))5308 if (mas_prev_setup(mas, min, &entry))
5209 return entry;5309 return entry;
5210 5310
@@ -5228,6 +5328,7 @@ void *mas_prev_range(struct ma_state *mas, unsigned long min) · 17 unmodified lines
5228{5328{
5229 void *entry = NULL;5329 void *entry = NULL;
5230 5330
5331 mas_may_init_lock_check(mas);
5231 if (mas_prev_setup(mas, min, &entry))5332 if (mas_prev_setup(mas, min, &entry))
5232 return entry;5333 return entry;
5233 5334
@@ -5274,6 +5375,7 @@ EXPORT_SYMBOL_GPL(mt_prev); · 40 unmodified lines
5274 */5375 */
5275void mas_pause(struct ma_state *mas)5376void mas_pause(struct ma_state *mas)
5276{5377{
5378 mas_lock_check(mas);
5277 mas->status = ma_pause;5379 mas->status = ma_pause;
5278 mas->node = NULL;5380 mas->node = NULL;
5279}5381}
@@ -5382,6 +5484,7 @@ void *mas_find(struct ma_state *mas, unsigned long max) · 102 unmodified lines
5382{5484{
5383 void *entry = NULL;5485 void *entry = NULL;
5384 5486
5487 mas_may_init_lock_check(mas);
5385 if (mas_find_setup(mas, max, &entry))5488 if (mas_find_setup(mas, max, &entry))
5386 return entry;5489 return entry;
5387 5490
@@ -5409,6 +5512,7 @@ void *mas_find_range(struct ma_state *mas, unsigned long max) · 21 unmodified lines
5409{5512{
5410 void *entry = NULL;5513 void *entry = NULL;
5411 5514
5515 mas_may_init_lock_check(mas);
5412 if (mas_find_setup(mas, max, &entry))5516 if (mas_find_setup(mas, max, &entry))
5413 return entry;5517 return entry;
5414 5518
@@ -5428,7 +5532,6 @@ EXPORT_SYMBOL_GPL(mas_find_range); · 13 unmodified lines
5428static bool mas_find_rev_setup(struct ma_state *mas, unsigned long min,5532static bool mas_find_rev_setup(struct ma_state *mas, unsigned long min,
5429 void **entry)5533 void **entry)
5430{5534{
5431
5432 switch (mas->status) {5535 switch (mas->status) {
5433 case ma_active:5536 case ma_active:
5434 goto active;5537 goto active;
@@ -5521,6 +5624,7 @@ void *mas_find_rev(struct ma_state *mas, unsigned long min) · 86 unmodified lines
5521{5624{
5522 void *entry = NULL;5625 void *entry = NULL;
5523 5626
5627 mas_may_init_lock_check(mas);
5524 if (mas_find_rev_setup(mas, min, &entry))5628 if (mas_find_rev_setup(mas, min, &entry))
5525 return entry;5629 return entry;
5526 5630
@@ -5547,6 +5651,7 @@ void *mas_find_range_rev(struct ma_state *mas, unsigned long min) · 20 unmodified lines
5547{5651{
5548 void *entry = NULL;5652 void *entry = NULL;
5549 5653
5654 mas_may_init_lock_check(mas);
5550 if (mas_find_rev_setup(mas, min, &entry))5655 if (mas_find_rev_setup(mas, min, &entry))
5551 return entry;5656 return entry;
5552 5657
@@ -5564,6 +5669,11 @@ EXPORT_SYMBOL_GPL(mas_find_range_rev); · 11 unmodified lines
5564 * Searches for @mas->index, sets @mas->index and @mas->last to the range and5669 * Searches for @mas->index, sets @mas->index and @mas->last to the range and
5565 * erases that range.5670 * erases that range.
5566 *5671 *
5672 * Note that erase requires allocations and will use GFP_KERNEL | __GFP_NOFAIL
5673 * to do so if necessary. If the allocation fails, the internal lock will be
5674 * dropped to retry. An externally locked tree must be protected by a lock that
5675 * allows blocking for this API.
5676 *
5567 * Return: the entry that was erased or %NULL, @mas->index and @mas->last are updated.5677 * Return: the entry that was erased or %NULL, @mas->index and @mas->last are updated.
5568 */5678 */
5569void *mas_erase(struct ma_state *mas)5679void *mas_erase(struct ma_state *mas)
@@ -5572,25 +5682,25 @@ void *mas_erase(struct ma_state *mas) · 2 unmodified lines
5572 unsigned long index = mas->index;5682 unsigned long index = mas->index;
5573 MA_WR_STATE(wr_mas, mas, NULL);5683 MA_WR_STATE(wr_mas, mas, NULL);
5574 5684
5575 if (!mas_is_active(mas) || !mas_is_start(mas))5685 /*
5576 mas->status = ma_start;5686 * In low memory situations, the allocation is retried with the gfp flag
5687 * GFP_KERNEL | __GFP_NOFAIL. The internal spinlock is dropped in
5688 * mas_nomem_nofail(), however the external lock is not dropped.
5689 */
5690 if (mt_external_lock(mas->tree))
5691 might_alloc(GFP_KERNEL);
5577 5692
5693 mas_make_walkable(mas);
5578write_retry:5694write_retry:
5579 entry = mas_state_walk(mas);5695 entry = mas_state_walk(mas);
5580 if (!entry)5696 if (!entry)
5581 return NULL;5697 goto out;
5582 5698
5583 /* Must reset to ensure spanning writes of last slot are detected */5699 /* Must reset to ensure spanning writes of last slot are detected */
5584 mas_reset(mas);5700 mas_reset(mas);
5585 mas_wr_preallocate(&wr_mas, NULL);5701 mas_wr_preallocate(&wr_mas, NULL);
5586 if (mas_nomem(mas, GFP_KERNEL)) {5702 if (mas_nomem_nofail(mas, index, index))
5587 /* in case the range of entry changed when unlocked */
5588 mas->index = mas->last = index;
5589 goto write_retry;5703 goto write_retry;
5590 }
5591
5592 if (mas_is_err(mas))
5593 goto out;
5594 5704
5595 mas_wr_store_entry(&wr_mas);5705 mas_wr_store_entry(&wr_mas);
5596out:5706out:
@@ -5601,10 +5711,11 @@ EXPORT_SYMBOL_GPL(mas_erase); · 4 unmodified lines
5601 5711
5602/**5712/**
5603 * mas_nomem() - Check if there was an error allocating and do the allocation5713 * mas_nomem() - Check if there was an error allocating and do the allocation
5604 * if necessary If there are allocations, then free them.5714 * if necessary.
5715 *
5605 * @mas: The maple state5716 * @mas: The maple state
5606 * @gfp: The GFP_FLAGS to use for allocations5717 * @gfp: The GFP_FLAGS to use for allocations
5607 * Return: true on allocation, false otherwise.5718 * Return: False on no memory. True otherwise (partial success as well)
5608 */5719 */
5609bool mas_nomem(struct ma_state *mas, gfp_t gfp)5720bool mas_nomem(struct ma_state *mas, gfp_t gfp)
5610 __must_hold(mas->tree->ma_lock)5721 __must_hold(mas->tree->ma_lock)
@@ -5612,6 +5723,10 @@ bool mas_nomem(struct ma_state *mas, gfp_t gfp) · 1 unmodified line
5612 if (likely(mas->node != MA_ERROR(-ENOMEM)))5723 if (likely(mas->node != MA_ERROR(-ENOMEM)))
5613 return false;5724 return false;
5614 5725
5726 /* Allocations can fail, don't do this. */
5727 WARN_ON_ONCE(!gfpflags_allow_blocking(gfp) &&
5728 mt_external_lock(mas->tree));
5729
5615 if (gfpflags_allow_blocking(gfp) && !mt_external_lock(mas->tree)) {5730 if (gfpflags_allow_blocking(gfp) && !mt_external_lock(mas->tree)) {
5616 mtree_unlock(mas->tree);5731 mtree_unlock(mas->tree);
5617 mas_alloc_nodes(mas, gfp);5732 mas_alloc_nodes(mas, gfp);
@@ -5620,10 +5735,49 @@ bool mas_nomem(struct ma_state *mas, gfp_t gfp) · 2 unmodified lines
5620 mas_alloc_nodes(mas, gfp);5735 mas_alloc_nodes(mas, gfp);
5621 }5736 }
5622 5737
5738 /*
5739 * Return false on zero forward progress. Partial allocations are kept
5740 * so the retry path will attempt to get the rest. The failure should
5741 * not happen as we try our best to reclaim. The user would need an
5742 * external lock with a non-blocking gfp in a low memory situation.
5743 */
5623 if (!mas->sheaf && !mas->alloc)5744 if (!mas->sheaf && !mas->alloc)
5624 return false;5745 return false;
5625 5746
5626 mas->status = ma_start;5747 mas_reset(mas);
5748 return true;
5749}
5750
5751/**
5752 * mas_nomem_nofail() - Retry allocations with __GFP_NOFAIL, if the maple state
5753 * has stored the -ENOMEM error.
5754 * @mas: The maple state
5755 * @index: The start of the range for the @mas reset
5756 * @last: The end of the range for the @mas reset
5757 *
5758 * Return: false if @mas isn't in an -ENOMEM state. True if the allocation
5759 * happens, the state is reset. The internal lock will be dropped and external
5760 * locks must allow blocking.
5761 */
5762bool mas_nomem_nofail(struct ma_state *mas, unsigned long index,
5763 unsigned long last)
5764 __must_hold(mas->tree->ma_lock)
5765{
5766 gfp_t gfp;
5767
5768 if (likely(mas->node != MA_ERROR(-ENOMEM)))
5769 return false;
5770
5771 gfp = GFP_KERNEL | __GFP_NOFAIL;
5772 if (!mt_external_lock(mas->tree)) {
5773 mtree_unlock(mas->tree);
5774 mas_alloc_nodes(mas, gfp);
5775 mtree_lock(mas->tree);
5776 } else {
5777 mas_alloc_nodes(mas, gfp);
5778 }
5779
5780 mas_set_range(mas, index, last);
5627 return true;5781 return true;
5628}5782}
5629 5783
@@ -5913,6 +6067,10 @@ EXPORT_SYMBOL(mtree_alloc_rrange); · 283 unmodified lines
5913 * Erasing is the same as a walk to an entry then a store of a NULL to that6067 * Erasing is the same as a walk to an entry then a store of a NULL to that
5914 * ENTIRE range. In fact, it is implemented as such using the advanced API.6068 * ENTIRE range. In fact, it is implemented as such using the advanced API.
5915 *6069 *
6070 * Note that erase requires allocations and will use GFP_KERNEL | __GFP_NOFAIL
6071 * to do so if necessary. If the allocation fails, the internal lock will be
6072 * dropped to retry.
6073 *
5916 * Return: The entry stored at the @index or %NULL6074 * Return: The entry stored at the @index or %NULL
5917 */6075 */
5918void *mtree_erase(struct maple_tree *mt, unsigned long index)6076void *mtree_erase(struct maple_tree *mt, unsigned long index)
@@ -5922,6 +6080,7 @@ void *mtree_erase(struct maple_tree *mt, unsigned long index) · 3 unmodified lines
5922 MA_STATE(mas, mt, index, index);6080 MA_STATE(mas, mt, index, index);
5923 trace_ma_op(TP_FCT, &mas);6081 trace_ma_op(TP_FCT, &mas);
5924 6082
6083 might_alloc(GFP_KERNEL);
5925 mtree_lock(mt);6084 mtree_lock(mt);
5926 entry = mas_erase(&mas);6085 entry = mas_erase(&mas);
5927 mtree_unlock(mt);6086 mtree_unlock(mt);
lib/test_hmm.c+2−3
@@ -1151,10 +1151,9 @@ static vm_fault_t dmirror_devmem_fault_alloc_and_copy(struct migrate_vma *args, · 1150 unmodified lines
1151 if (!dpage && !order)1151 if (!dpage && !order)
1152 return VM_FAULT_OOM;1152 return VM_FAULT_OOM;
1153 1153
1154 pr_debug("migrating from sys to dev pfn src: 0x%lx pfn dst: 0x%lx\n",
1155 page_to_pfn(spage), page_to_pfn(dpage));
1156
1157 if (dpage) {1154 if (dpage) {
1155 pr_debug("migrating from dev to sys pfn src: 0x%lx pfn dst: 0x%lx\n",
1156 page_to_pfn(spage), page_to_pfn(dpage));
1158 lock_page(dpage);1157 lock_page(dpage);
1159 *dst |= migrate_pfn(page_to_pfn(dpage));1158 *dst |= migrate_pfn(page_to_pfn(dpage));
1160 }1159 }
lib/xarray.c+3−0
@@ -1053,6 +1053,9 @@ void xas_split_alloc(struct xa_state *xas, void *entry, unsigned int order, · 1052 unmodified lines
1053 if (xas->xa_shift + XA_CHUNK_SHIFT > order)1053 if (xas->xa_shift + XA_CHUNK_SHIFT > order)
1054 return;1054 return;
1055 1055
1056 if (xas->xa->xa_flags & XA_FLAGS_ACCOUNT)
1057 gfp |= __GFP_ACCOUNT;
1058
1056 do {1059 do {
1057 struct xa_node *node;1060 struct xa_node *node;
1058 1061
mm/Kconfig+11−11
@@ -125,8 +125,6 @@ config ZSWAP_COMPRESSOR_DEFAULT · 124 unmodified lines
125config ZSMALLOC125config ZSMALLOC
126 tristate126 tristate
127 127
128if ZSMALLOC
129
130menu "Zsmalloc allocator options"128menu "Zsmalloc allocator options"
131 depends on ZSMALLOC129 depends on ZSMALLOC
132 130
@@ -161,8 +159,6 @@ config ZSMALLOC_CHAIN_SIZE · 28 unmodified lines
161 159
162endmenu160endmenu
163 161
164endif
165
166menu "Slab allocator options"162menu "Slab allocator options"
167 163
168config SLUB164config SLUB
@@ -394,6 +390,7 @@ choice · 225 unmodified lines
394 390
395config FLATMEM_MANUAL391config FLATMEM_MANUAL
396 bool "Flat Memory"392 bool "Flat Memory"
393 depends on !NUMA
397 depends on !ARCH_SPARSEMEM_ENABLE || ARCH_FLATMEM_ENABLE394 depends on !ARCH_SPARSEMEM_ENABLE || ARCH_FLATMEM_ENABLE
398 help395 help
399 This option is best suited for non-NUMA systems with396 This option is best suited for non-NUMA systems with
@@ -428,6 +425,7 @@ config SPARSEMEM · 28 unmodified lines
428 425
429config FLATMEM426config FLATMEM
430 def_bool y427 def_bool y
428 depends on !NUMA
431 depends on !SPARSEMEM || FLATMEM_MANUAL429 depends on !SPARSEMEM || FLATMEM_MANUAL
432 430
433#431#
@@ -583,12 +581,10 @@ endchoice · 149 unmodified lines
583 581
584config MEMORY_HOTREMOVE582config MEMORY_HOTREMOVE
585 bool "Allow for memory hot remove"583 bool "Allow for memory hot remove"
586 depends on MEMORY_HOTPLUG
587 select MIGRATION584 select MIGRATION
588 585
589config MHP_MEMMAP_ON_MEMORY586config MHP_MEMMAP_ON_MEMORY
590 def_bool y587 def_bool y
591 depends on MEMORY_HOTPLUG && SPARSEMEM_VMEMMAP
592 depends on ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE588 depends on ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE
593 589
594endif # MEMORY_HOTPLUG590endif # MEMORY_HOTPLUG
@@ -771,6 +767,7 @@ config MEMORY_FAILURE · 176 unmodified lines
771 depends on ARCH_SUPPORTS_MEMORY_FAILURE767 depends on ARCH_SUPPORTS_MEMORY_FAILURE
772 bool "Enable recovery from hardware memory errors"768 bool "Enable recovery from hardware memory errors"
773 select INTERVAL_TREE769 select INTERVAL_TREE
770 select MIGRATION
774 help771 help
775 Enables code to recover from some memory failures on systems772 Enables code to recover from some memory failures on systems
776 with MCA recovery. This allows a system to continue running773 with MCA recovery. This allows a system to continue running
@@ -1227,9 +1224,7 @@ config ZONE_DMA32 · 450 unmodified lines
1227 1224
1228config ZONE_DEVICE1225config ZONE_DEVICE
1229 bool "Device memory (pmem, HMM, etc...) hotplug support"1226 bool "Device memory (pmem, HMM, etc...) hotplug support"
1230 depends on MEMORY_HOTPLUG
1231 depends on MEMORY_HOTREMOVE1227 depends on MEMORY_HOTREMOVE
1232 depends on SPARSEMEM_VMEMMAP
1233 select XARRAY_MULTI1228 select XARRAY_MULTI
1234 1229
1235 help1230 help
@@ -1395,17 +1390,15 @@ menuconfig USERFAULTFD · 159 unmodified lines
1395 Enable the userfaultfd() system call that allows to intercept and1390 Enable the userfaultfd() system call that allows to intercept and
1396 handle page faults in userland.1391 handle page faults in userland.
1397 1392
1398if USERFAULTFD
1399config PTE_MARKER_UFFD_WP1393config PTE_MARKER_UFFD_WP
1400 bool "Userfaultfd write protection support for shmem/hugetlbfs"1394 bool "Userfaultfd write protection support for shmem/hugetlbfs"
1401 default y1395 default y
1402 depends on HAVE_ARCH_USERFAULTFD_WP1396 depends on USERFAULTFD && HAVE_ARCH_USERFAULTFD_WP
1403 1397
1404 help1398 help
1405 Allows to create marker PTEs for userfaultfd write protection1399 Allows to create marker PTEs for userfaultfd write protection
1406 purposes. It is required to enable userfaultfd write protection on1400 purposes. It is required to enable userfaultfd write protection on
1407 file-backed memory types like shmem and hugetlbfs.1401 file-backed memory types like shmem and hugetlbfs.
1408endif # USERFAULTFD
1409 1402
1410# multi-gen LRU {1403# multi-gen LRU {
1411config LRU_GEN1404config LRU_GEN
@@ -1471,6 +1464,13 @@ config NUMA_EMU · 59 unmodified lines
1471 into virtual nodes when booted with "numa=fake=N", where N is the1464 into virtual nodes when booted with "numa=fake=N", where N is the
1472 number of nodes. This is only useful for debugging.1465 number of nodes. This is only useful for debugging.
1473 1466
1467config GENERIC_ARCH_NUMA
1468 bool
1469 select NUMA_MEMBLKS
1470 help
1471 Enable support for generic NUMA implementation. Currently, RISC-V
1472 and ARM64 use it.
1473
1474config ARCH_HAS_USER_SHADOW_STACK1474config ARCH_HAS_USER_SHADOW_STACK
1475 bool1475 bool
1476 help1476 help
mm/Kconfig.debug+0−1
@@ -326,7 +326,6 @@ config MEM_ALLOC_PROFILING · 325 unmodified lines
326 default n326 default n
327 depends on MMU327 depends on MMU
328 depends on PROC_FS328 depends on PROC_FS
329 depends on !DEBUG_FORCE_WEAK_PER_CPU
330 select CODE_TAGGING329 select CODE_TAGGING
331 select PAGE_EXTENSION330 select PAGE_EXTENSION
332 select SLAB_OBJ_EXT331 select SLAB_OBJ_EXT
mm/Makefile+1−0
@@ -122,6 +122,7 @@ obj-$(CONFIG_CMA) += cma.o · 121 unmodified lines
122obj-$(CONFIG_NUMA) += numa.o122obj-$(CONFIG_NUMA) += numa.o
123obj-$(CONFIG_NUMA_MEMBLKS) += numa_memblks.o123obj-$(CONFIG_NUMA_MEMBLKS) += numa_memblks.o
124obj-$(CONFIG_NUMA_EMU) += numa_emulation.o124obj-$(CONFIG_NUMA_EMU) += numa_emulation.o
125obj-$(CONFIG_GENERIC_ARCH_NUMA) += arch_numa.o
125obj-$(CONFIG_BALLOON) += balloon.o126obj-$(CONFIG_BALLOON) += balloon.o
126obj-$(CONFIG_PAGE_EXTENSION) += page_ext.o127obj-$(CONFIG_PAGE_EXTENSION) += page_ext.o
127obj-$(CONFIG_PAGE_TABLE_CHECK) += page_table_check.o128obj-$(CONFIG_PAGE_TABLE_CHECK) += page_table_check.o
mm/alloc_tag.c+349−2
@@ -5,6 +5,8 @@ · 4 unmodified lines
5#include <linux/gfp.h>5#include <linux/gfp.h>
6#include <linux/kallsyms.h>6#include <linux/kallsyms.h>
7#include <linux/module.h>7#include <linux/module.h>
8#include <linux/mutex.h>
9#include <linux/compat.h>
8#include <linux/page_ext.h>10#include <linux/page_ext.h>
9#include <linux/pgalloc_tag.h>11#include <linux/pgalloc_tag.h>
10#include <linux/proc_fs.h>12#include <linux/proc_fs.h>
@@ -14,6 +16,7 @@ · 3 unmodified lines
14#include <linux/string_choices.h>16#include <linux/string_choices.h>
15#include <linux/vmalloc.h>17#include <linux/vmalloc.h>
16#include <linux/kmemleak.h>18#include <linux/kmemleak.h>
19#include <uapi/linux/alloc_tag.h>
17 20
18#include "internal.h"21#include "internal.h"
19#include "page_alloc.h"22#include "page_alloc.h"
@@ -59,6 +62,11 @@ struct allocinfo_private { · 39 unmodified lines
59 struct codetag_iterator iter;62 struct codetag_iterator iter;
60 struct codetag_iterator reported_iter;63 struct codetag_iterator reported_iter;
61 bool print_header;64 bool print_header;
65 struct allocinfo_filter filter;
66 /* ioctl uses a separate iterator not to interfere with reads */
67 struct codetag_iterator ioctl_iter;
68 bool positioned; /* seq_open_private() sets to 0 */
69 struct mutex ioctl_lock;
62};70};
63 71
64static void *allocinfo_start(struct seq_file *m, loff_t *pos)72static void *allocinfo_start(struct seq_file *m, loff_t *pos)
@@ -142,6 +150,340 @@ static const struct seq_operations allocinfo_seq_op = { · 77 unmodified lines
142 .show = allocinfo_show,150 .show = allocinfo_show,
143};151};
144 152
153/*
154 * Initializes seq_file operations and allocates private state when opening
155 * the /proc/allocinfo procfs entry.
156 */
157static int allocinfo_open(struct inode *inode, struct file *file)
158{
159 int ret;
160
161 ret = seq_open_private(file, &allocinfo_seq_op,
162 sizeof(struct allocinfo_private));
163 if (!ret) {
164 struct seq_file *m = file->private_data;
165 struct allocinfo_private *priv = m->private;
166
167 mutex_init(&priv->ioctl_lock);
168 }
169 return ret;
170}
171
172/*
173 * Cleans up the seq_file state and frees up the private state allocated in
174 * allocinfo_open() when closing the /proc/allocinfo file descriptor.
175 */
176static int allocinfo_release(struct inode *inode, struct file *file)
177{
178 struct seq_file *m = file->private_data;
179 struct allocinfo_private *priv = m->private;
180
181 mutex_destroy(&priv->ioctl_lock);
182 return seq_release_private(inode, file);
183}
184
185/*
186 * Returns a pointer to the suffix of a string so that its length fits within
187 * ALLOCINFO_STR_SIZE, preserving the trailing characters.
188 * Function, file and module names often have the same prefixes, therefore
189 * when filtering by these criteria, we compare the last 64 characters to
190 * minimize the chances of name collisions
191 */
192static const char *allocinfo_str(const char *str)
193{
194 size_t len = strlen(str);
195
196 /* Keep an extra space for the trailing NULL. */
197 if (len >= ALLOCINFO_STR_SIZE)
198 str += (len - ALLOCINFO_STR_SIZE) + 1;
199 return str;
200}
201
202/* Copy a string and trim from the beginning if it's too long */
203static void allocinfo_copy_str(char *dest, const char *src)
204{
205 strscpy_pad(dest, allocinfo_str(src), ALLOCINFO_STR_SIZE);
206}
207
208/* Compare two strings and only consider the trimmed suffix if s1 is too long */
209static int allocinfo_cmp_str(const char *str, const char *template)
210{
211 return strncmp(allocinfo_str(str), template, ALLOCINFO_STR_SIZE);
212}
213
214/* Fetch the per-CPU counters */
215static inline struct alloc_tag_counters allocinfo_prefetch_counters(struct codetag *ct)
216{
217 return alloc_tag_read(ct_to_alloc_tag(ct));
218}
219
220/*
221 * Populates the UAPI allocinfo_tag_data structure with active runtime
222 * profiling counters extracted from the given kernel codetag.
223 */
224static void allocinfo_to_params(struct codetag *ct,
225 struct allocinfo_tag_data *data,
226 struct alloc_tag_counters *counters)
227{
228 if (ct->modname)
229 allocinfo_copy_str(data->tag.modname, ct->modname);
230 else
231 data->tag.modname[0] = '\0';
232 allocinfo_copy_str(data->tag.function, ct->function);
233 allocinfo_copy_str(data->tag.filename, ct->filename);
234 data->tag.lineno = ct->lineno;
235 data->counter.bytes = counters->bytes;
236 data->counter.calls = counters->calls;
237 data->counter.accurate = !alloc_tag_is_inaccurate(ct_to_alloc_tag(ct));
238}
239
240/*
241 * Retrieves the unique content ID representing the current allocation tag module
242 * layout, allowing userspace to detect if modules were loaded / unloaded.
243 */
244static int allocinfo_ioctl_get_content_id(struct seq_file *m, void __user *arg)
245{
246 struct allocinfo_content_id params;
247
248 codetag_lock_module_list(alloc_tag_cttype);
249 params.id = codetag_get_content_id(alloc_tag_cttype);
250 codetag_unlock_module_list(alloc_tag_cttype);
251 if (copy_to_user(arg, &params, sizeof(params)))
252 return -EFAULT;
253
254 return 0;
255}
256
257/*
258 * Verifies whether a given codetag satisfies the active filtering criteria by
259 * matching its characteristics against the specified filter.
260 */
261static bool matches_filter(struct codetag *ct, struct allocinfo_filter *filter,
262 struct alloc_tag_counters *counters,
263 bool *fetched_counters)
264{
265 bool inaccurate;
266
267 if (!filter || !filter->mask)
268 return true;
269
270 if (filter->mask & ALLOCINFO_FILTER_MASK_MODNAME) {
271 /* user wants to filter by modname but ct->modname is NULL */
272 if (!ct->modname) {
273 /* validate if user was attempting to filter for built-in allocations */
274 if (filter->fields.modname[0] != '\0')
275 return false;
276 } else if (allocinfo_cmp_str(ct->modname, filter->fields.modname))
277 return false;
278 }
279
280 if ((filter->mask & ALLOCINFO_FILTER_MASK_FUNCTION) &&
281 ct->function && allocinfo_cmp_str(ct->function, filter->fields.function))
282 return false;
283
284 if ((filter->mask & ALLOCINFO_FILTER_MASK_FILENAME) &&
285 ct->filename && allocinfo_cmp_str(ct->filename, filter->fields.filename))
286 return false;
287
288 if ((filter->mask & ALLOCINFO_FILTER_MASK_LINENO) &&
289 ct->lineno != filter->fields.lineno)
290 return false;
291
292 if (filter->mask & ALLOCINFO_FILTER_MASK_INACCURATE) {
293 inaccurate = !!(ct->flags & CODETAG_FLAG_INACCURATE);
294 if (inaccurate != !!(filter->inaccurate))
295 return false;
296 }
297
298 if (filter->mask & (ALLOCINFO_FILTER_MASK_MIN_SIZE | ALLOCINFO_FILTER_MASK_MAX_SIZE)) {
299 if (!*fetched_counters) {
300 *counters = allocinfo_prefetch_counters(ct);
301 *fetched_counters = true;
302 }
303 if ((filter->mask & ALLOCINFO_FILTER_MASK_MIN_SIZE) &&
304 counters->bytes < filter->min_size)
305 return false;
306 if ((filter->mask & ALLOCINFO_FILTER_MASK_MAX_SIZE) &&
307 counters->bytes > filter->max_size)
308 return false;
309 }
310
311 return true;
312}
313
314/*
315 * Seeks the ioctl iterator to the specified 0-indexed tag position, reads its
316 * profiling data and returns it to userspace.
317 */
318static int allocinfo_ioctl_get_at(struct seq_file *m, void __user *arg)
319{
320 struct allocinfo_private *priv;
321 struct codetag *ct;
322 struct allocinfo_get_at params = {0};
323 __u64 skip_count;
324 struct alloc_tag_counters counters;
325 bool fetched_counters;
326
327 if (copy_from_user(&params, arg, sizeof(params)))
328 return -EFAULT;
329
330 if (params.filter.mask & ~ALLOCINFO_FILTER_MASKS)
331 return -EINVAL;
332
333 if ((params.filter.mask & ALLOCINFO_FILTER_MASK_MIN_SIZE) &&
334 (params.filter.mask & ALLOCINFO_FILTER_MASK_MAX_SIZE) &&
335 params.filter.min_size > params.filter.max_size)
336 return -EINVAL;
337
338 priv = m->private;
339
340 mutex_lock(&priv->ioctl_lock);
341 codetag_lock_module_list(alloc_tag_cttype);
342
343 if (params.pos >= codetag_get_count(alloc_tag_cttype)) {
344 codetag_unlock_module_list(alloc_tag_cttype);
345 mutex_unlock(&priv->ioctl_lock);
346 return -ENOENT;
347 }
348
349 skip_count = params.pos;
350
351 if (params.filter.mask)
352 priv->filter = params.filter;
353 else
354 priv->filter.mask = 0;
355
356 /* Find the codetag */
357 priv->ioctl_iter = codetag_get_ct_iter(alloc_tag_cttype);
358 ct = codetag_next_ct(&priv->ioctl_iter);
359
360 while (ct) {
361 fetched_counters = false;
362 if (matches_filter(ct, &priv->filter, &counters, &fetched_counters)) {
363 if (skip_count == 0)
364 break;
365 skip_count--;
366 }
367 ct = codetag_next_ct(&priv->ioctl_iter);
368 }
369
370 if (ct) {
371 if (!fetched_counters)
372 counters = allocinfo_prefetch_counters(ct);
373 allocinfo_to_params(ct, &params.data, &counters);
374 priv->positioned = true;
375 }
376
377 codetag_unlock_module_list(alloc_tag_cttype);
378 mutex_unlock(&priv->ioctl_lock);
379
380 if (!ct)
381 return -ENOENT;
382
383 if (copy_to_user(arg, &params, sizeof(params)))
384 return -EFAULT;
385
386 return 0;
387}
388
389/*
390 * Advances the ioctl iterator to the next allocation tag in the sequence and
391 * returns its profiling data to userspace.
392 */
393static int allocinfo_ioctl_get_next(struct seq_file *m, void __user *arg)
394{
395 struct allocinfo_private *priv;
396 struct codetag *ct;
397 struct allocinfo_tag_data params;
398 int ret = 0;
399 struct alloc_tag_counters counters;
400 bool fetched_counters;
401
402 memset(&params, 0, sizeof(params));
403 priv = m->private;
404
405 mutex_lock(&priv->ioctl_lock);
406 codetag_lock_module_list(alloc_tag_cttype);
407
408 if (!priv->positioned) {
409 priv->ioctl_iter = codetag_get_ct_iter(alloc_tag_cttype);
410 priv->positioned = true;
411 }
412
413 ct = codetag_next_ct(&priv->ioctl_iter);
414 while (ct) {
415 fetched_counters = false;
416 if (matches_filter(ct, &priv->filter, &counters, &fetched_counters))
417 break;
418 ct = codetag_next_ct(&priv->ioctl_iter);
419 }
420
421 if (ct) {
422 if (!fetched_counters)
423 counters = allocinfo_prefetch_counters(ct);
424 allocinfo_to_params(ct, &params, &counters);
425 }
426 if (!ct) {
427 priv->positioned = false;
428 ret = -ENOENT;
429 }
430 codetag_unlock_module_list(alloc_tag_cttype);
431 mutex_unlock(&priv->ioctl_lock);
432
433 if (ret == 0) {
434 if (copy_to_user(arg, &params, sizeof(params)))
435 return -EFAULT;
436 }
437 return ret;
438}
439
440/*
441 * Entry point ioctl function for /proc/allocinfo routing requests to fetch the
442 * layout content ID, seek to a specific tag, or read sequential tags.
443 */
444static long allocinfo_ioctl(struct file *file, unsigned int cmd,
445 unsigned long __arg)
446{
447 void __user *arg = (void __user *)__arg;
448 int ret;
449
450 switch (cmd) {
451 case ALLOCINFO_IOC_CONTENT_ID:
452 ret = allocinfo_ioctl_get_content_id(file->private_data, arg);
453 break;
454 case ALLOCINFO_IOC_GET_AT:
455 ret = allocinfo_ioctl_get_at(file->private_data, arg);
456 break;
457 case ALLOCINFO_IOC_GET_NEXT:
458 ret = allocinfo_ioctl_get_next(file->private_data, arg);
459 break;
460 default:
461 ret = -ENOIOCTLCMD;
462 break;
463 }
464
465 return ret;
466}
467
468#ifdef CONFIG_COMPAT
469static long allocinfo_compat_ioctl(struct file *file, unsigned int cmd,
470 unsigned long arg)
471{
472 return allocinfo_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
473}
474#endif
475
476static const struct proc_ops allocinfo_proc_ops = {
477 .proc_open = allocinfo_open,
478 .proc_read_iter = seq_read_iter,
479 .proc_lseek = seq_lseek,
480 .proc_release = allocinfo_release,
481 .proc_ioctl = allocinfo_ioctl,
482#ifdef CONFIG_COMPAT
483 .proc_compat_ioctl = allocinfo_compat_ioctl,
484#endif
485};
486
145size_t alloc_tag_top_users(struct codetag_bytes *tags, size_t count, bool can_sleep)487size_t alloc_tag_top_users(struct codetag_bytes *tags, size_t count, bool can_sleep)
146{488{
147 struct codetag_iterator iter;489 struct codetag_iterator iter;
@@ -961,6 +1303,12 @@ static const struct ctl_table memory_allocation_profiling_sysctls[] = { · 813 unmodified lines
961 .mode = 0644,1303 .mode = 0644,
962 .proc_handler = proc_mem_profiling_handler,1304 .proc_handler = proc_mem_profiling_handler,
963 },1305 },
1306 {
1307 .procname = "mem_profiling_compressed",
1308 .data = &mem_profiling_compressed,
1309 .mode = 0444,
1310 .proc_handler = proc_do_static_key,
1311 },
964};1312};
965 1313
966static void __init sysctl_init(void)1314static void __init sysctl_init(void)
@@ -993,8 +1341,7 @@ static int __init alloc_tag_init(void) · 26 unmodified lines
993 return 0;1341 return 0;
994 }1342 }
995 1343
996 if (!proc_create_seq_private(ALLOCINFO_FILE_NAME, 0400, NULL, &allocinfo_seq_op,1344 if (!proc_create(ALLOCINFO_FILE_NAME, 0400, NULL, &allocinfo_proc_ops)) {
997 sizeof(struct allocinfo_private), NULL)) {
998 pr_err("Failed to create %s file\n", ALLOCINFO_FILE_NAME);1345 pr_err("Failed to create %s file\n", ALLOCINFO_FILE_NAME);
999 shutdown_mem_profiling(false);1346 shutdown_mem_profiling(false);
1000 return -ENOMEM;1347 return -ENOMEM;
mm/arch_numa.crenamed from drivers/base/arch_numa.c+12−0
@@ -105,6 +105,18 @@ static void __init setup_node_to_cpumask_map(void) · 104 unmodified lines
105 if (nr_node_ids == MAX_NUMNODES)105 if (nr_node_ids == MAX_NUMNODES)
106 setup_nr_node_ids();106 setup_nr_node_ids();
107 107
108 /*
109 * This check should never be true but it makes it clear to compilers
110 * that node_to_cpumask_map is bound by nr_node_ids, avoiding false
111 * positive fortify warnings when accessing node_to_cpumask_map in the
112 * for loop below.
113 */
114 if (unlikely(nr_node_ids > MAX_NUMNODES)) {
115 pr_err("nr_node_ids (%u) is larger than MAX_NUMNODES (%u)\n",
116 nr_node_ids, MAX_NUMNODES);
117 return;
118 }
119
108 /* allocate and clear the mapping */120 /* allocate and clear the mapping */
109 for (node = 0; node < nr_node_ids; node++) {121 for (node = 0; node < nr_node_ids; node++) {
110 alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);122 alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
mm/cma.c+1−1
@@ -242,7 +242,7 @@ static int __init cma_new_area(const char *name, phys_addr_t size, · 241 unmodified lines
242 if (name)242 if (name)
243 strscpy(cma->name, name);243 strscpy(cma->name, name);
244 else244 else
245 snprintf(cma->name, CMA_MAX_NAME, "cma%d\n", cma_area_count);245 snprintf(cma->name, CMA_MAX_NAME, "cma%d", cma_area_count);
246 246
247 cma->available_count = cma->count = size >> PAGE_SHIFT;247 cma->available_count = cma->count = size >> PAGE_SHIFT;
248 cma->order_per_bit = order_per_bit;248 cma->order_per_bit = order_per_bit;
mm/cma.h+1−0
@@ -2,6 +2,7 @@ · 1 unmodified line
2#ifndef __MM_CMA_H__2#ifndef __MM_CMA_H__
3#define __MM_CMA_H__3#define __MM_CMA_H__
4 4
5#include <linux/cma.h>
5#include <linux/debugfs.h>6#include <linux/debugfs.h>
6#include <linux/kobject.h>7#include <linux/kobject.h>
7 8
mm/debug_page_alloc.c+4−4
@@ -20,14 +20,14 @@ early_param("debug_pagealloc", early_debug_pagealloc); · 19 unmodified lines
20 20
21static int __init debug_guardpage_minorder_setup(char *buf)21static int __init debug_guardpage_minorder_setup(char *buf)
22{22{
23 unsigned long res;23 unsigned int res;
24 24
25 if (kstrtoul(buf, 10, &res) < 0 || res > MAX_PAGE_ORDER / 2) {25 if (!buf || kstrtouint(buf, 10, &res) < 0 || res > MAX_PAGE_ORDER / 2) {
26 pr_err("Bad debug_guardpage_minorder value: %s\n", buf);26 pr_err("Bad debug_guardpage_minorder value: %s\n", buf ?: "(missing)");
27 return 0;27 return 0;
28 }28 }
29 _debug_guardpage_minorder = res;29 _debug_guardpage_minorder = res;
30 pr_info("Setting debug_guardpage_minorder to %lu\n", res);30 pr_info("Setting debug_guardpage_minorder to %u\n", res);
31 return 0;31 return 0;
32}32}
33early_param("debug_guardpage_minorder", debug_guardpage_minorder_setup);33early_param("debug_guardpage_minorder", debug_guardpage_minorder_setup);
mm/folio-compat.c+1−0
@@ -41,6 +41,7 @@ void set_page_writeback(struct page *page) · 40 unmodified lines
41}41}
42EXPORT_SYMBOL(set_page_writeback);42EXPORT_SYMBOL(set_page_writeback);
43 43
44/* Read the comment above folio_mark_dirty() regarding required locks! */
44bool set_page_dirty(struct page *page)45bool set_page_dirty(struct page *page)
45{46{
46 return folio_mark_dirty(page_folio(page));47 return folio_mark_dirty(page_folio(page));
mm/folio.c+55−69
@@ -265,73 +265,6 @@ void folio_rotate_reclaimable(struct folio *folio) · 264 unmodified lines
265 folio_batch_add_and_move(folio, lru_move_tail);265 folio_batch_add_and_move(folio, lru_move_tail);
266}266}
267 267
268void lru_note_cost_unlock_irq(struct lruvec *lruvec, bool file,
269 unsigned int nr_io, unsigned int nr_rotated)
270 __releases(lruvec->lru_lock)
271 __releases(rcu)
272{
273 unsigned long cost;
274
275 /*
276 * Reflect the relative cost of incurring IO and spending CPU
277 * time on rotations. This doesn't attempt to make a precise
278 * comparison, it just says: if reloads are about comparable
279 * between the LRU lists, or rotations are overwhelmingly
280 * different between them, adjust scan balance for CPU work.
281 */
282 cost = nr_io * SWAP_CLUSTER_MAX + nr_rotated;
283 if (!cost) {
284 spin_unlock_irq(&lruvec->lru_lock);
285 rcu_read_unlock();
286 return;
287 }
288
289 for (;;) {
290 unsigned long lrusize;
291
292 /* Record cost event */
293 if (file)
294 lruvec->file_cost += cost;
295 else
296 lruvec->anon_cost += cost;
297
298 /*
299 * Decay previous events
300 *
301 * Because workloads change over time (and to avoid
302 * overflow) we keep these statistics as a floating
303 * average, which ends up weighing recent refaults
304 * more than old ones.
305 */
306 lrusize = lruvec_page_state(lruvec, NR_INACTIVE_ANON) +
307 lruvec_page_state(lruvec, NR_ACTIVE_ANON) +
308 lruvec_page_state(lruvec, NR_INACTIVE_FILE) +
309 lruvec_page_state(lruvec, NR_ACTIVE_FILE);
310
311 if (lruvec->file_cost + lruvec->anon_cost > lrusize / 4) {
312 lruvec->file_cost /= 2;
313 lruvec->anon_cost /= 2;
314 }
315
316 spin_unlock_irq(&lruvec->lru_lock);
317 lruvec = parent_lruvec(lruvec);
318 if (!lruvec) {
319 rcu_read_unlock();
320 break;
321 }
322 spin_lock_irq(&lruvec->lru_lock);
323 }
324}
325
326void lru_note_cost_refault(struct folio *folio)
327{
328 struct lruvec *lruvec;
329
330 lruvec = folio_lruvec_lock_irq(folio);
331 lru_note_cost_unlock_irq(lruvec, folio_is_file_lru(folio),
332 folio_nr_pages(folio), 0);
333}
334
335static void lru_activate(struct lruvec *lruvec, struct folio *folio)268static void lru_activate(struct lruvec *lruvec, struct folio *folio)
336{269{
337 long nr_pages = folio_nr_pages(folio);270 long nr_pages = folio_nr_pages(folio);
@@ -948,6 +881,52 @@ void lru_add_drain_all(void) · 610 unmodified lines
948}881}
949#endif /* CONFIG_SMP */882#endif /* CONFIG_SMP */
950 883
884/**
885 * lru_cache_drain_for_folio() - drain LRU caches if the caches might hold
886 * folio references
887 * @folio: The folio.
888 * @extra_refs: Extra folio references held by the caller.
889 * @drained: Drain status for batch folio processing.
890 *
891 * Drain LRU caches if the caches might hold folio references. Start
892 * with a local LRU cache drain, to then drain LRU caches on all CPUs if
893 * local draining was insufficient.
894 *
895 * This function detects LRU cache references by comparing the folio refcount
896 * with the sum of the expected folio refcount + extra references held by the
897 * caller. Note that we cannot rely on PG_lru to reliably detect all LRU
898 * cache references, and there are rare scenarios (concurrent folio (un)mapping)
899 * where this function might miss detecting LRU cache references.
900 *
901 * If @drained is not NULL, the function will avoid re-draining LRU caches
902 * when processing multiple folios in a row. In that case, the variable
903 * @drained points at must be initialized to LRU_CACHE_NOT_DRAINED before
904 * the first invocation by the caller.
905 */
906void lru_cache_drain_for_folio(const struct folio *folio,
907 unsigned int extra_refs, enum lru_cache_drained *drained)
908{
909 if (!folio_may_be_lru_cached(folio))
910 return;
911
912 if (!drained || *drained == LRU_CACHE_NOT_DRAINED) {
913 if (folio_ref_count(folio) ==
914 folio_expected_ref_count(folio) + extra_refs)
915 return;
916 lru_add_drain();
917 if (drained)
918 *drained = LRU_CACHE_DRAINED;
919 }
920 if (!drained || *drained == LRU_CACHE_DRAINED) {
921 if (folio_ref_count(folio) ==
922 folio_expected_ref_count(folio) + extra_refs)
923 return;
924 lru_add_drain_all();
925 if (drained)
926 *drained = LRU_CACHE_DRAINED_ALL;
927 }
928}
929
951atomic_t lru_disable_count = ATOMIC_INIT(0);930atomic_t lru_disable_count = ATOMIC_INIT(0);
952 931
953/*932/*
@@ -1151,7 +1130,16 @@ static void lruvec_reparent_lru(struct lruvec *child_lruvec, · 197 unmodified lines
1151 for_each_managed_zone_pgdat(zone, NODE_DATA(nid), zid, MAX_NR_ZONES - 1) {1130 for_each_managed_zone_pgdat(zone, NODE_DATA(nid), zid, MAX_NR_ZONES - 1) {
1152 unsigned long size = mem_cgroup_get_zone_lru_size(child_lruvec, lru, zid);1131 unsigned long size = mem_cgroup_get_zone_lru_size(child_lruvec, lru, zid);
1153 1132
1133 if (!size)
1134 continue;
1135
1136 /*
1137 * The folios are accounted to the parent from now on, so the
1138 * size has to be moved, not just copied. Leaving it behind
1139 * makes the dying child describe folios it no longer owns.
1140 */
1154 mem_cgroup_update_lru_size(parent_lruvec, lru, zid, size);1141 mem_cgroup_update_lru_size(parent_lruvec, lru, zid, size);
1142 mem_cgroup_update_lru_size(child_lruvec, lru, zid, -(long)size);
1155 }1143 }
1156}1144}
1157 1145
@@ -1162,8 +1150,6 @@ void lru_reparent_memcg(struct mem_cgroup *memcg, struct mem_cgroup *parent, int · 4 unmodified lines
1162 1150
1163 child_lruvec = mem_cgroup_lruvec(memcg, NODE_DATA(nid));1151 child_lruvec = mem_cgroup_lruvec(memcg, NODE_DATA(nid));
1164 parent_lruvec = mem_cgroup_lruvec(parent, NODE_DATA(nid));1152 parent_lruvec = mem_cgroup_lruvec(parent, NODE_DATA(nid));
1165 parent_lruvec->anon_cost += child_lruvec->anon_cost;
1166 parent_lruvec->file_cost += child_lruvec->file_cost;
1167 1153
1168 for_each_lru(lru)1154 for_each_lru(lru)
1169 lruvec_reparent_lru(child_lruvec, parent_lruvec, lru, nid);1155 lruvec_reparent_lru(child_lruvec, parent_lruvec, lru, nid);
mm/gup.c+9−14
@@ -1236,7 +1236,7 @@ static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags) · 1235 unmodified lines
1236 * Anon pages in shared mappings are surprising: now1236 * Anon pages in shared mappings are surprising: now
1237 * just reject it.1237 * just reject it.
1238 */1238 */
1239 if (!is_cow_mapping(vm_flags))1239 if (!vma_is_cow_mapping(vma))
1240 return -EFAULT;1240 return -EFAULT;
1241 }1241 }
1242 } else if (!(vm_flags & VM_READ)) {1242 } else if (!(vm_flags & VM_READ)) {
@@ -2266,13 +2266,14 @@ static unsigned long collect_longterm_unpinnable_folios( · 1023 unmodified lines
2266 struct list_head *movable_folio_list,2266 struct list_head *movable_folio_list,
2267 struct pages_or_folios *pofs)2267 struct pages_or_folios *pofs)
2268{2268{
2269 enum lru_cache_drained drained = LRU_CACHE_NOT_DRAINED;
2269 unsigned long collected = 0;2270 unsigned long collected = 0;
2270 struct folio *folio;2271 struct folio *folio;
2271 int drained = 0;
2272 long i = 0;2272 long i = 0;
2273 2273
2274 for (folio = pofs_get_folio(pofs, i); folio;2274 for (folio = pofs_get_folio(pofs, i); folio;
2275 folio = pofs_next_folio(folio, pofs, &i)) {2275 folio = pofs_next_folio(folio, pofs, &i)) {
2276 const int pin_refs = folio_has_pincount(folio) ? 1 : GUP_PIN_COUNTING_BIAS;
2276 2277
2277 if (folio_is_longterm_pinnable(folio))2278 if (folio_is_longterm_pinnable(folio))
2278 continue;2279 continue;
@@ -2287,18 +2288,12 @@ static unsigned long collect_longterm_unpinnable_folios( · 8 unmodified lines
2287 continue;2288 continue;
2288 }2289 }
2289 2290
2290 if (drained == 0 && folio_may_be_lru_cached(folio) &&2291 /*
2291 folio_ref_count(folio) !=2292 * We drain not only to make the folio_isolate_lru() succeed,
2292 folio_expected_ref_count(folio) + 1) {2293 * but also to remove any other folio references from LRU
2293 lru_add_drain();2294 * caches.
2294 drained = 1;2295 */
2295 }2296 lru_cache_drain_for_folio(folio, pin_refs, &drained);
2296 if (drained == 1 && folio_may_be_lru_cached(folio) &&
2297 folio_ref_count(folio) !=
2298 folio_expected_ref_count(folio) + 1) {
2299 lru_add_drain_all();
2300 drained = 2;
2301 }
2302 2297
2303 if (!folio_isolate_lru(folio))2298 if (!folio_isolate_lru(folio))
2304 continue;2299 continue;
mm/gup_test.c+62−32
@@ -8,6 +8,12 @@ · 7 unmodified lines
8#include <linux/highmem.h>8#include <linux/highmem.h>
9#include "gup_test.h"9#include "gup_test.h"
10 10
11struct gup_test_data {
12 struct mutex longterm_mutex;
13 struct page **longterm_pages;
14 unsigned long longterm_nr_pages;
15};
16
11static void put_back_pages(unsigned int cmd, struct page **pages,17static void put_back_pages(unsigned int cmd, struct page **pages,
12 unsigned long nr_pages, unsigned int gup_test_flags)18 unsigned long nr_pages, unsigned int gup_test_flags)
13{19{
@@ -208,23 +214,20 @@ free_pages: · 194 unmodified lines
208 return ret;214 return ret;
209}215}
210 216
211static DEFINE_MUTEX(pin_longterm_test_mutex);217static inline void pin_longterm_test_stop(struct gup_test_data *data)
212static struct page **pin_longterm_test_pages;
213static unsigned long pin_longterm_test_nr_pages;
214
215static inline void pin_longterm_test_stop(void)
216{218{
217 if (pin_longterm_test_pages) {219 if (data->longterm_pages) {
218 if (pin_longterm_test_nr_pages)220 if (data->longterm_nr_pages)
219 unpin_user_pages(pin_longterm_test_pages,221 unpin_user_pages(data->longterm_pages,
220 pin_longterm_test_nr_pages);222 data->longterm_nr_pages);
221 kvfree(pin_longterm_test_pages);223 kvfree(data->longterm_pages);
222 pin_longterm_test_pages = NULL;224 data->longterm_pages = NULL;
223 pin_longterm_test_nr_pages = 0;225 data->longterm_nr_pages = 0;
224 }226 }
225}227}
226 228
227static inline int pin_longterm_test_start(unsigned long arg)229static inline int pin_longterm_test_start(struct gup_test_data *data,
230 unsigned long arg)
228{231{
229 long nr_pages, cur_pages, addr, remaining_pages;232 long nr_pages, cur_pages, addr, remaining_pages;
230 int gup_flags = FOLL_LONGTERM;233 int gup_flags = FOLL_LONGTERM;
@@ -233,7 +236,7 @@ static inline int pin_longterm_test_start(unsigned long arg) · 2 unmodified lines
233 int ret = 0;236 int ret = 0;
234 bool fast;237 bool fast;
235 238
236 if (pin_longterm_test_pages)239 if (data->longterm_pages)
237 return -EINVAL;240 return -EINVAL;
238 241
239 if (copy_from_user(&args, (void __user *)arg, sizeof(args)))242 if (copy_from_user(&args, (void __user *)arg, sizeof(args)))
@@ -263,12 +266,12 @@ static inline int pin_longterm_test_start(unsigned long arg) · 23 unmodified lines
263 return -EINTR;266 return -EINTR;
264 }267 }
265 268
266 pin_longterm_test_pages = pages;269 data->longterm_pages = pages;
267 pin_longterm_test_nr_pages = 0;270 data->longterm_nr_pages = 0;
268 271
269 while (nr_pages - pin_longterm_test_nr_pages) {272 while (nr_pages - data->longterm_nr_pages) {
270 remaining_pages = nr_pages - pin_longterm_test_nr_pages;273 remaining_pages = nr_pages - data->longterm_nr_pages;
271 addr = args.addr + pin_longterm_test_nr_pages * PAGE_SIZE;274 addr = args.addr + data->longterm_nr_pages * PAGE_SIZE;
272 275
273 if (fast)276 if (fast)
274 cur_pages = pin_user_pages_fast(addr, remaining_pages,277 cur_pages = pin_user_pages_fast(addr, remaining_pages,
@@ -277,11 +280,11 @@ static inline int pin_longterm_test_start(unsigned long arg) · 2 unmodified lines
277 cur_pages = pin_user_pages(addr, remaining_pages,280 cur_pages = pin_user_pages(addr, remaining_pages,
278 gup_flags, pages);281 gup_flags, pages);
279 if (cur_pages < 0) {282 if (cur_pages < 0) {
280 pin_longterm_test_stop();283 pin_longterm_test_stop(data);
281 ret = cur_pages;284 ret = cur_pages;
282 break;285 break;
283 }286 }
284 pin_longterm_test_nr_pages += cur_pages;287 data->longterm_nr_pages += cur_pages;
285 pages += cur_pages;288 pages += cur_pages;
286 }289 }
287 290
@@ -290,19 +293,20 @@ static inline int pin_longterm_test_start(unsigned long arg) · 2 unmodified lines
290 return ret;293 return ret;
291}294}
292 295
293static inline int pin_longterm_test_read(unsigned long arg)296static inline int pin_longterm_test_read(struct gup_test_data *data,
297 unsigned long arg)
294{298{
295 __u64 user_addr;299 __u64 user_addr;
296 unsigned long i;300 unsigned long i;
297 301
298 if (!pin_longterm_test_pages)302 if (!data->longterm_pages)
299 return -EINVAL;303 return -EINVAL;
300 304
301 if (copy_from_user(&user_addr, (void __user *)arg, sizeof(user_addr)))305 if (copy_from_user(&user_addr, (void __user *)arg, sizeof(user_addr)))
302 return -EFAULT;306 return -EFAULT;
303 307
304 for (i = 0; i < pin_longterm_test_nr_pages; i++) {308 for (i = 0; i < data->longterm_nr_pages; i++) {
305 void *addr = kmap_local_page(pin_longterm_test_pages[i]);309 void *addr = kmap_local_page(data->longterm_pages[i]);
306 unsigned long ret;310 unsigned long ret;
307 311
308 ret = copy_to_user((void __user *)(unsigned long)user_addr, addr,312 ret = copy_to_user((void __user *)(unsigned long)user_addr, addr,
@@ -318,25 +322,26 @@ static inline int pin_longterm_test_read(unsigned long arg) · 9 unmodified lines
318static long pin_longterm_test_ioctl(struct file *filep, unsigned int cmd,322static long pin_longterm_test_ioctl(struct file *filep, unsigned int cmd,
319 unsigned long arg)323 unsigned long arg)
320{324{
325 struct gup_test_data *data = filep->private_data;
321 int ret = -EINVAL;326 int ret = -EINVAL;
322 327
323 if (mutex_lock_killable(&pin_longterm_test_mutex))328 if (mutex_lock_killable(&data->longterm_mutex))
324 return -EINTR;329 return -EINTR;
325 330
326 switch (cmd) {331 switch (cmd) {
327 case PIN_LONGTERM_TEST_START:332 case PIN_LONGTERM_TEST_START:
328 ret = pin_longterm_test_start(arg);333 ret = pin_longterm_test_start(data, arg);
329 break;334 break;
330 case PIN_LONGTERM_TEST_STOP:335 case PIN_LONGTERM_TEST_STOP:
331 pin_longterm_test_stop();336 pin_longterm_test_stop(data);
332 ret = 0;337 ret = 0;
333 break;338 break;
334 case PIN_LONGTERM_TEST_READ:339 case PIN_LONGTERM_TEST_READ:
335 ret = pin_longterm_test_read(arg);340 ret = pin_longterm_test_read(data, arg);
336 break;341 break;
337 }342 }
338 343
339 mutex_unlock(&pin_longterm_test_mutex);344 mutex_unlock(&data->longterm_mutex);
340 return ret;345 return ret;
341}346}
342 347
@@ -375,15 +380,40 @@ static long gup_test_ioctl(struct file *filep, unsigned int cmd, · 32 unmodified lines
375 return 0;380 return 0;
376}381}
377 382
383static int gup_test_open(struct inode *inode, struct file *file)
384{
385 struct gup_test_data *data;
386 int ret;
387
388 data = kzalloc_obj(*data);
389 if (!data)
390 return -ENOMEM;
391
392 ret = nonseekable_open(inode, file);
393 if (ret) {
394 kfree(data);
395 return ret;
396 }
397
398 mutex_init(&data->longterm_mutex);
399 file->private_data = data;
400 return 0;
401}
402
378static int gup_test_release(struct inode *inode, struct file *file)403static int gup_test_release(struct inode *inode, struct file *file)
379{404{
380 pin_longterm_test_stop();405 struct gup_test_data *data = file->private_data;
406
407 pin_longterm_test_stop(data);
408 mutex_destroy(&data->longterm_mutex);
409 kfree(data);
410 file->private_data = NULL;
381 411
382 return 0;412 return 0;
383}413}
384 414
385static const struct file_operations gup_test_fops = {415static const struct file_operations gup_test_fops = {
386 .open = nonseekable_open,416 .open = gup_test_open,
387 .unlocked_ioctl = gup_test_ioctl,417 .unlocked_ioctl = gup_test_ioctl,
388 .compat_ioctl = compat_ptr_ioctl,418 .compat_ioctl = compat_ptr_ioctl,
389 .release = gup_test_release,419 .release = gup_test_release,
mm/hmm.c+4−1
@@ -670,7 +670,10 @@ static int hmm_do_fault(struct mm_struct *mm, · 669 unmodified lines
670 ret = handle_mm_fault(vma, addr, fault_flags, NULL);670 ret = handle_mm_fault(vma, addr, fault_flags, NULL);
671 671
672 if (ret & (VM_FAULT_COMPLETED | VM_FAULT_RETRY)) {672 if (ret & (VM_FAULT_COMPLETED | VM_FAULT_RETRY)) {
673 *hmm_vma_walk->locked = false;673 if (hmm_vma_walk->locked) /* needed by sparse */
674 *hmm_vma_walk->locked = false;
675 else
676 WARN_ON_ONCE(1); /* broken fault handler */
674 return HMM_FAULT_UNLOCKED;677 return HMM_FAULT_UNLOCKED;
675 }678 }
676 679
mm/huge_memory.c+28−18
@@ -1681,7 +1681,7 @@ vm_fault_t vmf_insert_pfn_pmd(struct vm_fault *vmf, unsigned long pfn, · 1680 unmodified lines
1681 BUG_ON(!(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)));1681 BUG_ON(!(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)));
1682 BUG_ON((vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) ==1682 BUG_ON((vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) ==
1683 (VM_PFNMAP|VM_MIXEDMAP));1683 (VM_PFNMAP|VM_MIXEDMAP));
1684 BUG_ON((vma->vm_flags & VM_PFNMAP) && is_cow_mapping(vma->vm_flags));1684 BUG_ON((vma->vm_flags & VM_PFNMAP) && vma_is_cow_mapping(vma));
1685 1685
1686 pfnmap_setup_cachemode_pfn(pfn, &pgprot);1686 pfnmap_setup_cachemode_pfn(pfn, &pgprot);
1687 1687
@@ -1789,7 +1789,7 @@ vm_fault_t vmf_insert_pfn_pud(struct vm_fault *vmf, unsigned long pfn, · 101 unmodified lines
1789 BUG_ON(!(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)));1789 BUG_ON(!(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)));
1790 BUG_ON((vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) ==1790 BUG_ON((vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) ==
1791 (VM_PFNMAP|VM_MIXEDMAP));1791 (VM_PFNMAP|VM_MIXEDMAP));
1792 BUG_ON((vma->vm_flags & VM_PFNMAP) && is_cow_mapping(vma->vm_flags));1792 BUG_ON((vma->vm_flags & VM_PFNMAP) && vma_is_cow_mapping(vma));
1793 1793
1794 pfnmap_setup_cachemode_pfn(pfn, &pgprot);1794 pfnmap_setup_cachemode_pfn(pfn, &pgprot);
1795 1795
@@ -1931,7 +1931,7 @@ int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm, · 135 unmodified lines
1931 * applied special bit, or we made the PRIVATE mapping be1931 * applied special bit, or we made the PRIVATE mapping be
1932 * able to wrongly write to the backend MMIO.1932 * able to wrongly write to the backend MMIO.
1933 */1933 */
1934 VM_WARN_ON_ONCE(is_cow_mapping(src_vma->vm_flags) && pmd_write(pmd));1934 VM_WARN_ON_ONCE(vma_is_cow_mapping(src_vma) && pmd_write(pmd));
1935 goto set_pmd;1935 goto set_pmd;
1936 }1936 }
1937 1937
@@ -2052,7 +2052,7 @@ int copy_huge_pud(struct mm_struct *dst_mm, struct mm_struct *src_mm, · 114 unmodified lines
2052 * TODO: once we support anonymous pages, use2052 * TODO: once we support anonymous pages, use
2053 * folio_try_dup_anon_rmap_*() and split if duplicating fails.2053 * folio_try_dup_anon_rmap_*() and split if duplicating fails.
2054 */2054 */
2055 if (is_cow_mapping(vma->vm_flags) && pud_write(pud)) {2055 if (vma_is_cow_mapping(vma) && pud_write(pud)) {
2056 pudp_set_wrprotect(src_mm, addr, src_pud);2056 pudp_set_wrprotect(src_mm, addr, src_pud);
2057 pud = pud_wrprotect(pud);2057 pud = pud_wrprotect(pud);
2058 }2058 }
@@ -2930,7 +2930,7 @@ int move_pages_huge_pmd(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd, pm · 871 unmodified lines
2930 }2930 }
2931 2931
2932 folio_move_anon_rmap(src_folio, dst_vma);2932 folio_move_anon_rmap(src_folio, dst_vma);
2933 src_folio->index = linear_page_index(dst_vma, dst_addr);2933 src_folio->index = linear_anon_page_index(dst_vma, dst_addr);
2934 2934
2935 _dst_pmd = folio_mk_pmd(src_folio, dst_vma->vm_page_prot);2935 _dst_pmd = folio_mk_pmd(src_folio, dst_vma->vm_page_prot);
2936 /* Follow mremap() behavior and treat the entry dirty after the move */2936 /* Follow mremap() behavior and treat the entry dirty after the move */
@@ -4105,34 +4105,42 @@ static int __folio_split(struct folio *folio, unsigned int new_order, · 1168 unmodified lines
4105 XA_STATE(xas, &folio->mapping->i_pages, folio->index);4105 XA_STATE(xas, &folio->mapping->i_pages, folio->index);
4106 struct folio *end_folio = folio_next(folio);4106 struct folio *end_folio = folio_next(folio);
4107 bool is_anon = folio_test_anon(folio);4107 bool is_anon = folio_test_anon(folio);
4108 struct mem_cgroup *memcg, *old_memcg;
4108 struct address_space *mapping = NULL;4109 struct address_space *mapping = NULL;
4109 struct anon_vma *anon_vma = NULL;4110 struct anon_vma *anon_vma = NULL;
4110 int old_order = folio_order(folio);4111 int old_order = folio_order(folio);
4111 struct folio *new_folio, *next;4112 struct folio *new_folio, *next;
4112 int nr_shmem_dropped = 0;4113 int nr_shmem_dropped = 0;
4113 enum ttu_flags ttu_flags = 0;4114 enum ttu_flags ttu_flags = 0;
4114 int ret;
4115 pgoff_t end = 0;4115 pgoff_t end = 0;
4116 int ret;
4116 4117
4117 VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio);4118 VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio);
4118 VM_WARN_ON_ONCE_FOLIO(!folio_test_large(folio), folio);4119 VM_WARN_ON_ONCE_FOLIO(!folio_test_large(folio), folio);
4119 4120
4120 if (folio != page_folio(split_at) || folio != page_folio(lock_at)) {4121 if (folio != page_folio(split_at) || folio != page_folio(lock_at)) {
4121 ret = -EINVAL;4122 ret = -EINVAL;
4122 goto out;4123 goto out_no_memcg;
4123 }4124 }
4124 4125
4125 if (new_order >= old_order) {4126 if (new_order >= old_order) {
4126 ret = -EINVAL;4127 ret = -EINVAL;
4127 goto out;4128 goto out_no_memcg;
4128 }4129 }
4129 4130
4130 ret = folio_check_splittable(folio, new_order, split_type);4131 ret = folio_check_splittable(folio, new_order, split_type);
4131 if (ret) {4132 if (ret) {
4132 VM_WARN_ONCE(ret == -EINVAL, "Tried to split an unsplittable folio");4133 VM_WARN_ONCE(ret == -EINVAL, "Tried to split an unsplittable folio");
4133 goto out;4134 goto out_no_memcg;
4134 }4135 }
4135 4136
4137 /*
4138 * switch to folio's memcg as xarray node allocation can happen and
4139 * needs to charge to it.
4140 */
4141 memcg = get_mem_cgroup_from_folio(folio);
4142 old_memcg = set_active_memcg(memcg);
4143
4136 if (is_anon) {4144 if (is_anon) {
4137 /*4145 /*
4138 * The caller does not necessarily hold an mmap_lock that would4146 * The caller does not necessarily hold an mmap_lock that would
@@ -4275,6 +4283,10 @@ out_unlock: · 136 unmodified lines
4275 if (mapping)4283 if (mapping)
4276 i_mmap_unlock_read(mapping);4284 i_mmap_unlock_read(mapping);
4277out:4285out:
4286 /* restore to caller's old_memcg */
4287 set_active_memcg(old_memcg);
4288 mem_cgroup_put(memcg);
4289out_no_memcg:
4278 xas_destroy(&xas);4290 xas_destroy(&xas);
4279 if (is_pmd_order(old_order))4291 if (is_pmd_order(old_order))
4280 count_vm_event(!ret ? THP_SPLIT_PAGE : THP_SPLIT_PAGE_FAILED);4292 count_vm_event(!ret ? THP_SPLIT_PAGE : THP_SPLIT_PAGE_FAILED);
@@ -5077,9 +5089,8 @@ int set_pmd_migration_entry(struct page_vma_mapped_walk *pvmw, · 796 unmodified lines
5077 return 0;5089 return 0;
5078}5090}
5079 5091
5080void remove_migration_pmd(struct page_vma_mapped_walk *pvmw, struct page *new)5092void remove_migration_pmd(struct page_vma_mapped_walk *pvmw, struct folio *folio)
5081{5093{
5082 struct folio *folio = page_folio(new);
5083 struct vm_area_struct *vma = pvmw->vma;5094 struct vm_area_struct *vma = pvmw->vma;
5084 struct mm_struct *mm = vma->vm_mm;5095 struct mm_struct *mm = vma->vm_mm;
5085 unsigned long address = pvmw->address;5096 unsigned long address = pvmw->address;
@@ -5115,11 +5126,9 @@ void remove_migration_pmd(struct page_vma_mapped_walk *pvmw, struct page *new) · 29 unmodified lines
5115 swp_entry_t entry;5126 swp_entry_t entry;
5116 5127
5117 if (pmd_write(pmde))5128 if (pmd_write(pmde))
5118 entry = make_writable_device_private_entry(5129 entry = make_writable_device_private_entry(folio_pfn(folio));
5119 page_to_pfn(new));
5120 else5130 else
5121 entry = make_readable_device_private_entry(5131 entry = make_readable_device_private_entry(folio_pfn(folio));
5122 page_to_pfn(new));
5123 pmde = softleaf_to_pmd(entry);5132 pmde = softleaf_to_pmd(entry);
5124 5133
5125 if (pmd_swp_soft_dirty(*pvmw->pmd))5134 if (pmd_swp_soft_dirty(*pvmw->pmd))
@@ -5134,11 +5143,12 @@ void remove_migration_pmd(struct page_vma_mapped_walk *pvmw, struct page *new) · 8 unmodified lines
5134 if (!softleaf_is_migration_read(entry))5143 if (!softleaf_is_migration_read(entry))
5135 rmap_flags |= RMAP_EXCLUSIVE;5144 rmap_flags |= RMAP_EXCLUSIVE;
5136 5145
5137 folio_add_anon_rmap_pmd(folio, new, vma, haddr, rmap_flags);5146 folio_add_anon_rmap_pmd(folio, &folio->page, vma, haddr, rmap_flags);
5138 } else {5147 } else {
5139 folio_add_file_rmap_pmd(folio, new, vma);5148 folio_add_file_rmap_pmd(folio, &folio->page, vma);
5140 }5149 }
5141 VM_BUG_ON(pmd_write(pmde) && folio_test_anon(folio) && !PageAnonExclusive(new));5150 VM_WARN_ON_ONCE(pmd_write(pmde) && folio_test_anon(folio) &&
5151 !PageAnonExclusive(&folio->page));
5142 set_pmd_at(mm, haddr, pvmw->pmd, pmde);5152 set_pmd_at(mm, haddr, pvmw->pmd, pmde);
5143 5153
5144 /* No need to invalidate - it was non-present before */5154 /* No need to invalidate - it was non-present before */
mm/hugetlb.c+7−3
@@ -4888,7 +4888,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, · 4887 unmodified lines
4888 pte_t *src_pte, *dst_pte, entry;4888 pte_t *src_pte, *dst_pte, entry;
4889 struct folio *pte_folio;4889 struct folio *pte_folio;
4890 unsigned long addr;4890 unsigned long addr;
4891 bool cow = is_cow_mapping(src_vma->vm_flags);4891 bool cow = vma_is_cow_mapping(src_vma);
4892 struct hstate *h = hstate_vma(src_vma);4892 struct hstate *h = hstate_vma(src_vma);
4893 unsigned long sz = huge_page_size(h);4893 unsigned long sz = huge_page_size(h);
4894 unsigned long npages = pages_per_huge_page(h);4894 unsigned long npages = pages_per_huge_page(h);
@@ -5208,6 +5208,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma, · 313 unmodified lines
5208 bool adjust_reservation;5208 bool adjust_reservation;
5209 unsigned long last_addr_mask;5209 unsigned long last_addr_mask;
5210 5210
5211 i_mmap_assert_write_locked(vma->vm_file->f_mapping);
5211 WARN_ON(!is_vm_hugetlb_page(vma));5212 WARN_ON(!is_vm_hugetlb_page(vma));
5212 BUG_ON(start & ~huge_page_mask(h));5213 BUG_ON(start & ~huge_page_mask(h));
5213 BUG_ON(end & ~huge_page_mask(h));5214 BUG_ON(end & ~huge_page_mask(h));
@@ -5299,7 +5300,10 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma, · 85 unmodified lines
5299 5300
5300 /*5301 /*
5301 * Restore the reservation for anonymous page, otherwise the5302 * Restore the reservation for anonymous page, otherwise the
5302 * backing page could be stolen by someone.5303 * backing page could be stolen by someone. Restore only on the
5304 * last unmap, otherwise the owner could empty its resv map
5305 * while the folio is still mapped by a child. Note that holding
5306 * i_mmap_lock_write is needed to check the number of mappings.
5303 * If there we are freeing a surplus, do not set the restore5307 * If there we are freeing a surplus, do not set the restore
5304 * reservation bit.5308 * reservation bit.
5305 */5309 */
@@ -5307,7 +5311,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma, · 1 unmodified line
5307 5311
5308 spin_lock_irq(&hugetlb_lock);5312 spin_lock_irq(&hugetlb_lock);
5309 if (!h->surplus_huge_pages && __vma_private_lock(vma) &&5313 if (!h->surplus_huge_pages && __vma_private_lock(vma) &&
5310 folio_test_anon(folio)) {5314 !folio_mapped(folio) && folio_test_anon(folio)) {
5311 folio_set_hugetlb_restore_reserve(folio);5315 folio_set_hugetlb_restore_reserve(folio);
5312 /* Reservation to be adjusted after the spin lock */5316 /* Reservation to be adjusted after the spin lock */
5313 adjust_reservation = true;5317 adjust_reservation = true;
mm/hugetlb_cma.c+134−8
@@ -9,6 +9,9 @@ · 8 unmodified lines
9#include <asm/setup.h>9#include <asm/setup.h>
10 10
11#include <linux/hugetlb.h>11#include <linux/hugetlb.h>
12#include <linux/memblock.h>
13#include <linux/math.h>
14#include <linux/math64.h>
12#include "internal.h"15#include "internal.h"
13#include "hugetlb_cma.h"16#include "hugetlb_cma.h"
14 17
@@ -18,6 +21,28 @@ static unsigned long hugetlb_cma_size_in_node[MAX_NUMNODES] __initdata; · 3 unmodified lines
18static bool hugetlb_cma_only __ro_after_init;21static bool hugetlb_cma_only __ro_after_init;
19static unsigned long hugetlb_cma_size __ro_after_init;22static unsigned long hugetlb_cma_size __ro_after_init;
20 23
24static unsigned int hugetlb_cma_percent __initdata;
25static unsigned int hugetlb_cma_percent_in_node[MAX_NUMNODES] __initdata;
26
27#ifdef CONFIG_NUMA
28static phys_addr_t __init memblock_node_memory_size(int nid)
29{
30 struct memblock_region *reg;
31 phys_addr_t size = 0;
32
33 for_each_mem_region(reg) {
34 if (reg->nid == nid)
35 size += reg->size;
36 }
37 return size;
38}
39#else
40static phys_addr_t __init memblock_node_memory_size(int nid)
41{
42 return memblock_phys_mem_size();
43}
44#endif
45
21void hugetlb_cma_free_frozen_folio(struct folio *folio)46void hugetlb_cma_free_frozen_folio(struct folio *folio)
22{47{
23 WARN_ON_ONCE(!cma_release_frozen(hugetlb_cma[folio_nid(folio)],48 WARN_ON_ONCE(!cma_release_frozen(hugetlb_cma[folio_nid(folio)],
@@ -90,14 +115,31 @@ static int __init cmdline_parse_hugetlb_cma(char *p) · 66 unmodified lines
90 break;115 break;
91 116
92 if (s[count] == ':') {117 if (s[count] == ':') {
118 char *next;
119
93 if (tmp >= MAX_NUMNODES)120 if (tmp >= MAX_NUMNODES)
94 break;121 break;
95 nid = array_index_nospec(tmp, MAX_NUMNODES);122 nid = array_index_nospec(tmp, MAX_NUMNODES);
96 123
124 hugetlb_cma_size = 0;
125 hugetlb_cma_percent = 0;
126
97 s += count + 1;127 s += count + 1;
98 tmp = memparse(s, &s);128 tmp = memparse(s, &next);
99 hugetlb_cma_size_in_node[nid] = tmp;129 if (*next == '%') {
100 hugetlb_cma_size += tmp;130 if (tmp > 100) {
131 pr_warn("hugetlb_cma: invalid percentage %lu for node %d\n",
132 tmp, nid);
133 break;
134 }
135 hugetlb_cma_percent_in_node[nid] = tmp;
136 hugetlb_cma_size_in_node[nid] = 0;
137 s = next + 1;
138 } else {
139 hugetlb_cma_size_in_node[nid] = tmp;
140 hugetlb_cma_percent_in_node[nid] = 0;
141 s = next;
142 }
101 143
102 /*144 /*
103 * Skip the separator if have one, otherwise145 * Skip the separator if have one, otherwise
@@ -108,7 +150,28 @@ static int __init cmdline_parse_hugetlb_cma(char *p) · 4 unmodified lines
108 else150 else
109 break;151 break;
110 } else {152 } else {
111 hugetlb_cma_size = memparse(p, &p);153 char *next;
154
155 tmp = memparse(p, &next);
156 if (*next == '%') {
157 if (tmp > 100) {
158 pr_warn("hugetlb_cma: invalid percentage %lu\n", tmp);
159 } else {
160 hugetlb_cma_percent = tmp;
161 hugetlb_cma_size = 0;
162 for (nid = 0; nid < MAX_NUMNODES; nid++) {
163 hugetlb_cma_size_in_node[nid] = 0;
164 hugetlb_cma_percent_in_node[nid] = 0;
165 }
166 }
167 } else {
168 hugetlb_cma_size = tmp;
169 hugetlb_cma_percent = 0;
170 for (nid = 0; nid < MAX_NUMNODES; nid++) {
171 hugetlb_cma_size_in_node[nid] = 0;
172 hugetlb_cma_percent_in_node[nid] = 0;
173 }
174 }
112 break;175 break;
113 }176 }
114 }177 }
@@ -134,8 +197,36 @@ void __init hugetlb_cma_reserve(void) · 19 unmodified lines
134{197{
135 unsigned long size, reserved, per_node, order, gigantic_page_size;198 unsigned long size, reserved, per_node, order, gigantic_page_size;
136 bool node_specific_cma_alloc = false;199 bool node_specific_cma_alloc = false;
200 bool has_node_specific_param = false;
137 int nid;201 int nid;
138 202
203 for (nid = 0; nid < MAX_NUMNODES; nid++) {
204 if (hugetlb_cma_size_in_node[nid] || hugetlb_cma_percent_in_node[nid]) {
205 has_node_specific_param = true;
206 break;
207 }
208 }
209
210 if (has_node_specific_param) {
211 hugetlb_cma_size = 0;
212 for (nid = 0; nid < MAX_NUMNODES; nid++) {
213 if (hugetlb_cma_percent_in_node[nid]) {
214 phys_addr_t node_gfp_mem = memblock_node_memory_size(nid);
215 u64 s;
216
217 s = mul_u64_u32_div((u64)node_gfp_mem,
218 hugetlb_cma_percent_in_node[nid],
219 100);
220
221 hugetlb_cma_size_in_node[nid] = s;
222 }
223 hugetlb_cma_size += hugetlb_cma_size_in_node[nid];
224 }
225 } else if (hugetlb_cma_percent) {
226 hugetlb_cma_size = mul_u64_u32_div((u64)memblock_phys_mem_size(),
227 hugetlb_cma_percent, 100);
228 }
229
139 if (!hugetlb_cma_size)230 if (!hugetlb_cma_size)
140 return;231 return;
141 232
@@ -154,6 +245,32 @@ void __init hugetlb_cma_reserve(void) · 12 unmodified lines
154 VM_WARN_ON(order <= MAX_PAGE_ORDER);245 VM_WARN_ON(order <= MAX_PAGE_ORDER);
155 gigantic_page_size = PAGE_SIZE << order;246 gigantic_page_size = PAGE_SIZE << order;
156 247
248 if (hugetlb_cma_percent) {
249 unsigned long orig_size = hugetlb_cma_size;
250
251 hugetlb_cma_size = ALIGN_DOWN(hugetlb_cma_size, PAGE_SIZE << order);
252 if (orig_size && !hugetlb_cma_size)
253 pr_warn("hugetlb_cma: reservation size rounded down to 0 from %lu MiB (%u%%)\n",
254 orig_size / SZ_1M, hugetlb_cma_percent);
255 } else if (has_node_specific_param) {
256 hugetlb_cma_size = 0;
257 for (nid = 0; nid < MAX_NUMNODES; nid++) {
258 if (hugetlb_cma_percent_in_node[nid]) {
259 unsigned long orig_size = hugetlb_cma_size_in_node[nid];
260
261 hugetlb_cma_size_in_node[nid] =
262 ALIGN_DOWN(hugetlb_cma_size_in_node[nid],
263 PAGE_SIZE << order);
264 if (orig_size && !hugetlb_cma_size_in_node[nid])
265 pr_warn("hugetlb_cma: reservation size rounded down to 0 from %lu MiB (%u%%) on node %d\n",
266 orig_size / SZ_1M,
267 hugetlb_cma_percent_in_node[nid],
268 nid);
269 }
270 hugetlb_cma_size += hugetlb_cma_size_in_node[nid];
271 }
272 }
273
157 hugetlb_bootmem_set_nodes();274 hugetlb_bootmem_set_nodes();
158 275
159 for (nid = 0; nid < MAX_NUMNODES; nid++) {276 for (nid = 0; nid < MAX_NUMNODES; nid++) {
@@ -194,8 +311,13 @@ void __init hugetlb_cma_reserve(void) · 34 unmodified lines
194 per_node = DIV_ROUND_UP(hugetlb_cma_size,311 per_node = DIV_ROUND_UP(hugetlb_cma_size,
195 nodes_weight(hugetlb_bootmem_nodes));312 nodes_weight(hugetlb_bootmem_nodes));
196 per_node = round_up(per_node, gigantic_page_size);313 per_node = round_up(per_node, gigantic_page_size);
197 pr_info("hugetlb_cma: reserve %lu MiB, up to %lu MiB per node\n",314 if (hugetlb_cma_percent)
198 hugetlb_cma_size / SZ_1M, per_node / SZ_1M);315 pr_info("hugetlb_cma: reserve %lu MiB (%u%%), up to %lu MiB per node\n",
316 hugetlb_cma_size / SZ_1M, hugetlb_cma_percent,
317 per_node / SZ_1M);
318 else
319 pr_info("hugetlb_cma: reserve %lu MiB, up to %lu MiB per node\n",
320 hugetlb_cma_size / SZ_1M, per_node / SZ_1M);
199 }321 }
200 322
201 reserved = 0;323 reserved = 0;
@@ -230,8 +352,12 @@ void __init hugetlb_cma_reserve(void) · 28 unmodified lines
230 }352 }
231 353
232 reserved += size;354 reserved += size;
233 pr_info("hugetlb_cma: reserved %lu MiB on node %d\n",355 if (hugetlb_cma_percent_in_node[nid])
234 size / SZ_1M, nid);356 pr_info("hugetlb_cma: reserved %lu MiB (%u%%) on node %d\n",
357 size / SZ_1M, hugetlb_cma_percent_in_node[nid], nid);
358 else
359 pr_info("hugetlb_cma: reserved %lu MiB on node %d\n",
360 size / SZ_1M, nid);
235 361
236 if (reserved >= hugetlb_cma_size)362 if (reserved >= hugetlb_cma_size)
237 break;363 break;
mm/hugetlb_cma.h+2−0
@@ -2,6 +2,8 @@ · 1 unmodified line
2#ifndef _LINUX_HUGETLB_CMA_H2#ifndef _LINUX_HUGETLB_CMA_H
3#define _LINUX_HUGETLB_CMA_H3#define _LINUX_HUGETLB_CMA_H
4 4
5#include <linux/hugetlb.h>
6
5#ifdef CONFIG_CMA7#ifdef CONFIG_CMA
6void hugetlb_cma_free_frozen_folio(struct folio *folio);8void hugetlb_cma_free_frozen_folio(struct folio *folio);
7struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,9struct folio *hugetlb_cma_alloc_frozen_folio(int order, gfp_t gfp_mask,
mm/internal.h+54−23
@@ -41,12 +41,9 @@ void workingset_refault(struct folio *folio, void *shadow); · 40 unmodified lines
41void workingset_activation(struct folio *folio);41void workingset_activation(struct folio *folio);
42 42
43/* mm/folio.c */43/* mm/folio.c */
44void lru_note_cost_unlock_irq(struct lruvec *lruvec, bool file,
45 unsigned int nr_io, unsigned int nr_rotated);
46void lru_note_cost_refault(struct folio *folio);
47void folio_add_lru_vma(struct folio *folio, struct vm_area_struct *vma);44void folio_add_lru_vma(struct folio *folio, struct vm_area_struct *vma);
48 45
49static inline bool folio_may_be_lru_cached(struct folio *folio)46static inline bool folio_may_be_lru_cached(const struct folio *folio)
50{47{
51 /*48 /*
52 * Holding PMD-sized folios in per-CPU LRU cache unbalances accounting.49 * Holding PMD-sized folios in per-CPU LRU cache unbalances accounting.
@@ -945,7 +942,8 @@ folio_within_range(struct folio *folio, struct vm_area_struct *vma, · 892 unmodified lines
945 return false;942 return false;
946 943
947 pgoff_folio = folio_pgoff(folio);944 pgoff_folio = folio_pgoff(folio);
948 pgoff_vma_start = vma_start_pgoff(vma);945 pgoff_vma_start = folio_test_anon(folio) ?
946 vma_start_anon_pgoff(vma) : vma_start_pgoff(vma);
949 947
950 if (start < vma->vm_start)948 if (start < vma->vm_start)
951 start = vma->vm_start;949 start = vma->vm_start;
@@ -1017,19 +1015,9 @@ void mlock_drain_remote(int cpu); · 65 unmodified lines
1017 1015
1018extern pmd_t maybe_pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma);1016extern pmd_t maybe_pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma);
1019 1017
1020/**1018static inline unsigned long __vma_address(const struct vm_area_struct *vma,
1021 * vma_address - Find the virtual address a page range is mapped at1019 pgoff_t pgoff, pgoff_t pgoff_start, unsigned long nr_pages)
1022 * @vma: The vma which maps this object.
1023 * @pgoff: The page offset within its object.
1024 * @nr_pages: The number of pages to consider.
1025 *
1026 * If any page in this range is mapped by this VMA, return the first address
1027 * where any of these pages appear. Otherwise, return -EFAULT.
1028 */
1029static inline unsigned long vma_address(const struct vm_area_struct *vma,
1030 pgoff_t pgoff, unsigned long nr_pages)
1031{1020{
1032 const pgoff_t pgoff_start = vma_start_pgoff(vma);
1033 unsigned long address;1021 unsigned long address;
1034 1022
1035 if (pgoff >= pgoff_start) {1023 if (pgoff >= pgoff_start) {
@@ -1047,23 +1035,66 @@ static inline unsigned long vma_address(const struct vm_area_struct *vma, · 11 unmodified lines
1047 return address;1035 return address;
1048}1036}
1049 1037
1038/**
1039 * vma_filebacked_address - Find the virtual address a file-backed page range is
1040 * mapped at.
1041 * @vma: The vma which maps this object.
1042 * @pgoff: The page offset within its object.
1043 * @nr_pages: The number of pages to consider.
1044 *
1045 * Returns: If any page in this range is mapped by this VMA, return the first
1046 * address where any of these pages appear. Otherwise, return -EFAULT.
1047 */
1048static inline unsigned long vma_filebacked_address(const struct vm_area_struct *vma,
1049 pgoff_t pgoff, unsigned long nr_pages)
1050{
1051 VM_WARN_ON_ONCE(vma_is_anonymous(vma));
1052
1053 return __vma_address(vma, pgoff, vma_start_pgoff(vma), nr_pages);
1054}
1055
1056/**
1057 * vma_anon_address - Find the virtual address an anonymous page range is mapped
1058 * at.
1059 * @vma: The vma which maps this object.
1060 * @pgoff_anon: The anonymous page index belonging to the folio.
1061 * @nr_pages: The number of pages to consider.
1062 *
1063 * This is only valid for anonymous or MAP_PRIVATE-mapped file-backed VMAs.
1064 *
1065 * Returns: If any page in this range is mapped by this VMA, return the first
1066 * address where any of these pages appear. Otherwise, return -EFAULT.
1067 */
1068static inline unsigned long vma_anon_address(const struct vm_area_struct *vma,
1069 pgoff_t pgoff_anon, unsigned long nr_pages)
1070{
1071 VM_WARN_ON_ONCE(!vma_is_cow_mapping(vma));
1072
1073 return __vma_address(vma, pgoff_anon, vma_start_anon_pgoff(vma), nr_pages);
1074}
1075
1050/*1076/*
1051 * Then at what user virtual address will none of the range be found in vma?1077 * At what user virtual address will none of the range be found in vma?
1052 * Assumes that vma_address() already returned a good starting address.1078 * Assumes that vma_address() already returned a good starting address.
1053 */1079 */
1054static inline unsigned long vma_address_end(struct page_vma_mapped_walk *pvmw)1080static inline unsigned long vma_address_end(struct page_vma_mapped_walk *pvmw)
1055{1081{
1056 struct vm_area_struct *vma = pvmw->vma;1082 const pgoff_t pgoff_end = pvmw->pgoff + pvmw->nr_pages;
1057 pgoff_t pgoff;1083 const struct vm_area_struct *vma = pvmw->vma;
1084 pgoff_t pgoff_vma_start;
1058 unsigned long address;1085 unsigned long address;
1059 1086
1060 /* Common case, plus ->pgoff is invalid for KSM */1087 /* Common case, plus ->pgoff is invalid for KSM */
1061 if (pvmw->nr_pages == 1)1088 if (pvmw->nr_pages == 1)
1062 return pvmw->address + PAGE_SIZE;1089 return pvmw->address + PAGE_SIZE;
1063 1090
1064 pgoff = pvmw->pgoff + pvmw->nr_pages;1091 if (pvmw->pgoff_is_anon)
1092 pgoff_vma_start = vma_start_anon_pgoff(vma);
1093 else
1094 pgoff_vma_start = vma_start_pgoff(vma);
1095
1065 address = vma->vm_start +1096 address = vma->vm_start +
1066 ((pgoff - vma_start_pgoff(vma)) << PAGE_SHIFT);1097 ((pgoff_end - pgoff_vma_start) << PAGE_SHIFT);
1067 /* Check for address beyond vma (or wrapped through 0?) */1098 /* Check for address beyond vma (or wrapped through 0?) */
1068 if (address < vma->vm_start || address > vma->vm_end)1099 if (address < vma->vm_start || address > vma->vm_end)
1069 address = vma->vm_end;1100 address = vma->vm_end;
@@ -1353,7 +1384,7 @@ static inline bool gup_must_unshare(struct vm_area_struct *vma, · 283 unmodified lines
1353 * ... because we only care about writable private ("COW")1384 * ... because we only care about writable private ("COW")
1354 * mappings where we have to break COW early.1385 * mappings where we have to break COW early.
1355 */1386 */
1356 return is_cow_mapping(vma->vm_flags);1387 return vma_is_cow_mapping(vma);
1357 }1388 }
1358 1389
1359 /* Paired with a memory barrier in folio_try_share_anon_rmap_*(). */1390 /* Paired with a memory barrier in folio_try_share_anon_rmap_*(). */
mm/interval_tree.c+2−2
@@ -83,12 +83,12 @@ mapping_rmap_tree_iter_next(struct vm_area_struct *vma, · 82 unmodified lines
83 83
84static pgoff_t avc_start_pgoff(struct anon_vma_chain *avc)84static pgoff_t avc_start_pgoff(struct anon_vma_chain *avc)
85{85{
86 return vma_start_pgoff(avc->vma);86 return vma_start_anon_pgoff(avc->vma);
87}87}
88 88
89static pgoff_t avc_last_pgoff(struct anon_vma_chain *avc)89static pgoff_t avc_last_pgoff(struct anon_vma_chain *avc)
90{90{
91 return vma_last_pgoff(avc->vma);91 return vma_last_anon_pgoff(avc->vma);
92}92}
93 93
94INTERVAL_TREE_DEFINE(struct anon_vma_chain, rb, pgoff_t, rb_subtree_last,94INTERVAL_TREE_DEFINE(struct anon_vma_chain, rb, pgoff_t, rb_subtree_last,
mm/kasan/quarantine.c+11−1
@@ -355,7 +355,12 @@ void kasan_quarantine_remove_cache(struct kmem_cache *cache) · 354 unmodified lines
355 */355 */
356 on_each_cpu(per_cpu_remove_cache, cache, 1);356 on_each_cpu(per_cpu_remove_cache, cache, 1);
357 357
358 for_each_online_cpu(cpu) {358 /*
359 * A CPU can go offline after on_each_cpu() returns, leaving cache
360 * objects on that CPU's shrink list. Scan all possible CPUs to
361 * drain those lists.
362 */
363 for_each_possible_cpu(cpu) {
359 sq = per_cpu_ptr(&shrink_qlist, cpu);364 sq = per_cpu_ptr(&shrink_qlist, cpu);
360 raw_spin_lock_irqsave(&sq->lock, flags);365 raw_spin_lock_irqsave(&sq->lock, flags);
361 qlist_move_cache(&sq->qlist, &to_free, cache);366 qlist_move_cache(&sq->qlist, &to_free, cache);
@@ -365,9 +370,14 @@ void kasan_quarantine_remove_cache(struct kmem_cache *cache) · 3 unmodified lines
365 370
366 raw_spin_lock_irqsave(&quarantine_lock, flags);371 raw_spin_lock_irqsave(&quarantine_lock, flags);
367 for (i = 0; i < QUARANTINE_BATCHES; i++) {372 for (i = 0; i < QUARANTINE_BATCHES; i++) {
373 size_t old_bytes;
374
368 if (qlist_empty(&global_quarantine[i]))375 if (qlist_empty(&global_quarantine[i]))
369 continue;376 continue;
377 old_bytes = global_quarantine[i].bytes;
370 qlist_move_cache(&global_quarantine[i], &to_free, cache);378 qlist_move_cache(&global_quarantine[i], &to_free, cache);
379 WRITE_ONCE(quarantine_size, quarantine_size -
380 (old_bytes - global_quarantine[i].bytes));
371 /* Scanning whole quarantine can take a while. */381 /* Scanning whole quarantine can take a while. */
372 raw_spin_unlock_irqrestore(&quarantine_lock, flags);382 raw_spin_unlock_irqrestore(&quarantine_lock, flags);
373 cond_resched();383 cond_resched();
mm/khugepaged.c+65−65
@@ -620,7 +620,7 @@ void __khugepaged_exit(struct mm_struct *mm) · 619 unmodified lines
620 /*620 /*
621 * This is required to serialize against621 * This is required to serialize against
622 * collapse_test_exit() (which is guaranteed to run622 * collapse_test_exit() (which is guaranteed to run
623 * under mmap sem read mode). Stop here (after we return all623 * under mmap_lock read mode). Stop here (after we return all
624 * pagetables will be destroyed) until khugepaged has finished624 * pagetables will be destroyed) until khugepaged has finished
625 * working on the pagetables under the mmap_lock.625 * working on the pagetables under the mmap_lock.
626 */626 */
@@ -629,6 +629,13 @@ void __khugepaged_exit(struct mm_struct *mm) · 2 unmodified lines
629 }629 }
630}630}
631 631
632static void collapse_control_init_scan(struct collapse_control *cc)
633{
634 memset(cc->node_load, 0, sizeof(cc->node_load));
635 nodes_clear(cc->alloc_nmask);
636 bitmap_zero(cc->mthp_present_ptes, MAX_PTRS_PER_PTE);
637}
638
632static void release_pte_folio(struct folio *folio)639static void release_pte_folio(struct folio *folio)
633{640{
634 node_stat_mod_folio(folio,641 node_stat_mod_folio(folio,
@@ -665,6 +672,24 @@ static void release_pte_pages(pte_t *pte, pte_t *_pte, · 30 unmodified lines
665 }672 }
666}673}
667 674
675static bool folio_pte_referenced(struct folio *folio,
676 struct vm_area_struct *vma, unsigned long addr, pte_t pteval)
677{
678 /* The folio was referenced previously ... */
679 if (folio_test_young(folio) || folio_test_referenced(folio))
680 return true;
681 /* ... or the PTE mapping was recently used */
682 return pte_young(pteval) || mmu_notifier_test_young(vma->vm_mm, addr);
683}
684
685static void count_collapse_event(unsigned int order, enum vm_event_item vm_event,
686 enum mthp_stat_item mthp_event)
687{
688 if (is_pmd_order(order))
689 count_vm_event(vm_event);
690 count_mthp_stat(order, mthp_event);
691}
692
668static enum scan_result __collapse_huge_page_isolate(struct vm_area_struct *vma,693static enum scan_result __collapse_huge_page_isolate(struct vm_area_struct *vma,
669 unsigned long start_addr, pte_t *pte, struct collapse_control *cc,694 unsigned long start_addr, pte_t *pte, struct collapse_control *cc,
670 unsigned int order, struct list_head *compound_pagelist)695 unsigned int order, struct list_head *compound_pagelist)
@@ -685,9 +710,8 @@ static enum scan_result __collapse_huge_page_isolate(struct vm_area_struct *vma, · 14 unmodified lines
685 if (pte_none_or_zero(pteval)) {710 if (pte_none_or_zero(pteval)) {
686 if (++none_or_zero > max_ptes_none) {711 if (++none_or_zero > max_ptes_none) {
687 result = SCAN_EXCEED_NONE_PTE;712 result = SCAN_EXCEED_NONE_PTE;
688 if (is_pmd_order(order))713 count_collapse_event(order, THP_SCAN_EXCEED_NONE_PTE,
689 count_vm_event(THP_SCAN_EXCEED_NONE_PTE);714 MTHP_STAT_COLLAPSE_EXCEED_NONE);
690 count_mthp_stat(order, MTHP_STAT_COLLAPSE_EXCEED_NONE);
691 goto out;715 goto out;
692 }716 }
693 continue;717 continue;
@@ -729,9 +753,8 @@ static enum scan_result __collapse_huge_page_isolate(struct vm_area_struct *vma, · 35 unmodified lines
729 */753 */
730 if (++shared > max_ptes_shared) {754 if (++shared > max_ptes_shared) {
731 result = SCAN_EXCEED_SHARED_PTE;755 result = SCAN_EXCEED_SHARED_PTE;
732 if (is_pmd_order(order))756 count_collapse_event(order, THP_SCAN_EXCEED_SHARED_PTE,
733 count_vm_event(THP_SCAN_EXCEED_SHARED_PTE);757 MTHP_STAT_COLLAPSE_EXCEED_SHARED);
734 count_mthp_stat(order, MTHP_STAT_COLLAPSE_EXCEED_SHARED);
735 goto out;758 goto out;
736 }759 }
737 }760 }
@@ -759,8 +782,8 @@ static enum scan_result __collapse_huge_page_isolate(struct vm_area_struct *vma, · 21 unmodified lines
759 782
760 /*783 /*
761 * We can do it before folio_isolate_lru because the784 * We can do it before folio_isolate_lru because the
762 * folio can't be freed from under us. NOTE: PG_lock785 * folio can't be freed from under us. NOTE: folio lock
763 * is needed to serialize against split_huge_page786 * is needed to serialize against split_huge_page()
764 * when invoked from the VM.787 * when invoked from the VM.
765 */788 */
766 if (!folio_trylock(folio)) {789 if (!folio_trylock(folio)) {
@@ -786,7 +809,7 @@ static enum scan_result __collapse_huge_page_isolate(struct vm_area_struct *vma, · 19 unmodified lines
786 }809 }
787 810
788 /*811 /*
789 * Isolate the page to avoid collapsing an hugepage812 * Isolate the folio to avoid collapsing a hugepage
790 * currently in use by the VM.813 * currently in use by the VM.
791 */814 */
792 if (!folio_isolate_lru(folio)) {815 if (!folio_isolate_lru(folio)) {
@@ -803,14 +826,8 @@ static enum scan_result __collapse_huge_page_isolate(struct vm_area_struct *vma, · 10 unmodified lines
803 if (folio_test_large(folio))826 if (folio_test_large(folio))
804 list_add_tail(&folio->lru, compound_pagelist);827 list_add_tail(&folio->lru, compound_pagelist);
805next:828next:
806 /*
807 * If collapse was initiated by khugepaged, check that there is
808 * enough young pte to justify collapsing the page
809 */
810 if (cc->is_khugepaged &&829 if (cc->is_khugepaged &&
811 (pte_young(pteval) || folio_test_young(folio) ||830 folio_pte_referenced(folio, vma, addr, pteval))
812 folio_test_referenced(folio) ||
813 mmu_notifier_test_young(vma->vm_mm, addr)))
814 referenced++;831 referenced++;
815 }832 }
816 833
@@ -904,7 +921,7 @@ static void __collapse_huge_page_copy_failed(pte_t *pte, · 87 unmodified lines
904 * Re-establish the PMD to point to the original page table921 * Re-establish the PMD to point to the original page table
905 * entry. Restoring PMD needs to be done prior to releasing922 * entry. Restoring PMD needs to be done prior to releasing
906 * pages. Since pages are still isolated and locked here,923 * pages. Since pages are still isolated and locked here,
907 * acquiring anon_vma_lock_write is unnecessary.924 * acquiring anon_vma_lock_write() is unnecessary.
908 */925 */
909 pmd_ptl = pmd_lock(vma->vm_mm, pmd);926 pmd_ptl = pmd_lock(vma->vm_mm, pmd);
910 pmd_populate(vma->vm_mm, pmd, pmd_pgtable(orig_pmd));927 pmd_populate(vma->vm_mm, pmd, pmd_pgtable(orig_pmd));
@@ -1078,9 +1095,9 @@ static enum scan_result hugepage_vma_revalidate(struct mm_struct *mm, unsigned l · 167 unmodified lines
1078 return SCAN_VMA_CHECK;1095 return SCAN_VMA_CHECK;
1079 /*1096 /*
1080 * Anon VMA expected, the address may be unmapped then1097 * Anon VMA expected, the address may be unmapped then
1081 * remapped to file after khugepaged reaquired the mmap_lock.1098 * remapped to file after khugepaged reacquired the mmap_lock.
1082 *1099 *
1083 * thp_vma_allowable_orders may return true for qualified file1100 * thp_vma_allowable_orders() may return true for qualified file
1084 * vmas.1101 * vmas.
1085 */1102 */
1086 if (expect_anon && (!(*vmap)->anon_vma || !vma_is_anonymous(*vmap)))1103 if (expect_anon && (!(*vmap)->anon_vma || !vma_is_anonymous(*vmap)))
@@ -1136,7 +1153,7 @@ static enum scan_result check_pmd_still_valid(struct mm_struct *mm, · 49 unmodified lines
1136 1153
1137/*1154/*
1138 * Bring missing pages in from swap, to complete THP collapse.1155 * Bring missing pages in from swap, to complete THP collapse.
1139 * Only done if khugepaged_scan_pmd believes it is worthwhile.1156 * Only done if collapse_scan_pmd() believes it is worthwhile.
1140 *1157 *
1141 * For mTHP orders the function bails on the first swap entry, because1158 * For mTHP orders the function bails on the first swap entry, because
1142 * faulting pages back in during collapse could re-populate PTEs that1159 * faulting pages back in during collapse could re-populate PTEs that
@@ -1204,7 +1221,7 @@ static enum scan_result __collapse_huge_page_swapin(struct mm_struct *mm, · 61 unmodified lines
1204 pte = NULL;1221 pte = NULL;
1205 1222
1206 /*1223 /*
1207 * do_swap_page returns VM_FAULT_RETRY with released mmap_lock.1224 * do_swap_page() returns VM_FAULT_RETRY with released mmap_lock.
1208 * Note we treat VM_FAULT_RETRY as VM_FAULT_ERROR here because1225 * Note we treat VM_FAULT_RETRY as VM_FAULT_ERROR here because
1209 * we do not retry here and swap entry will remain in pagetable1226 * we do not retry here and swap entry will remain in pagetable
1210 * resulting in later failure.1227 * resulting in later failure.
@@ -1247,15 +1264,12 @@ static enum scan_result alloc_charge_folio(struct folio **foliop, struct mm_stru · 36 unmodified lines
1247 folio = __folio_alloc(gfp, order, node, &cc->alloc_nmask);1264 folio = __folio_alloc(gfp, order, node, &cc->alloc_nmask);
1248 if (!folio) {1265 if (!folio) {
1249 *foliop = NULL;1266 *foliop = NULL;
1250 if (is_pmd_order(order))1267 count_collapse_event(order, THP_COLLAPSE_ALLOC_FAILED,
1251 count_vm_event(THP_COLLAPSE_ALLOC_FAILED);1268 MTHP_STAT_COLLAPSE_ALLOC_FAILED);
1252 count_mthp_stat(order, MTHP_STAT_COLLAPSE_ALLOC_FAILED);
1253 return SCAN_ALLOC_HUGE_PAGE_FAIL;1269 return SCAN_ALLOC_HUGE_PAGE_FAIL;
1254 }1270 }
1255 1271
1256 if (is_pmd_order(order))1272 count_collapse_event(order, THP_COLLAPSE_ALLOC, MTHP_STAT_COLLAPSE_ALLOC);
1257 count_vm_event(THP_COLLAPSE_ALLOC);
1258 count_mthp_stat(order, MTHP_STAT_COLLAPSE_ALLOC);
1259 1273
1260 if (unlikely(mem_cgroup_charge(folio, mm, gfp))) {1274 if (unlikely(mem_cgroup_charge(folio, mm, gfp))) {
1261 folio_put(folio);1275 folio_put(folio);
@@ -1271,7 +1285,7 @@ static enum scan_result alloc_charge_folio(struct folio **foliop, struct mm_stru · 9 unmodified lines
1271}1285}
1272 1286
1273/*1287/*
1274 * collapse_huge_page expects the mmap_lock to be unlocked before entering and1288 * collapse_huge_page() expects the mmap_lock to be unlocked before entering and
1275 * will always return with the lock unlocked, to avoid holding the mmap_lock1289 * will always return with the lock unlocked, to avoid holding the mmap_lock
1276 * while allocating a THP, as that could trigger direct reclaim/compaction.1290 * while allocating a THP, as that could trigger direct reclaim/compaction.
1277 * Note that the VMA must be rechecked after grabbing the mmap_lock again.1291 * Note that the VMA must be rechecked after grabbing the mmap_lock again.
@@ -1318,7 +1332,7 @@ static enum scan_result collapse_huge_page(struct mm_struct *mm, unsigned long s · 40 unmodified lines
1318 1332
1319 if (unmapped) {1333 if (unmapped) {
1320 /*1334 /*
1321 * __collapse_huge_page_swapin will return with mmap_lock1335 * __collapse_huge_page_swapin() will return with mmap_lock
1322 * released when it fails. So we jump out_nolock directly in1336 * released when it fails. So we jump out_nolock directly in
1323 * that case. Continuing to collapse causes inconsistency.1337 * that case. Continuing to collapse causes inconsistency.
1324 */1338 */
@@ -1331,8 +1345,8 @@ static enum scan_result collapse_huge_page(struct mm_struct *mm, unsigned long s · 6 unmodified lines
1331 mmap_read_unlock(mm);1345 mmap_read_unlock(mm);
1332 /*1346 /*
1333 * Prevent all access to pagetables with the exception of1347 * Prevent all access to pagetables with the exception of
1334 * gup_fast later handled by the ptep_clear_flush and the VM1348 * gup_fast later handled by the pmdp_collapse_flush() and the VM
1335 * handled by the anon_vma lock + PG_lock.1349 * handled by the anon_vma lock + folio lock.
1336 *1350 *
1337 * UFFDIO_MOVE is prevented to race as well thanks to the1351 * UFFDIO_MOVE is prevented to race as well thanks to the
1338 * mmap_lock.1352 * mmap_lock.
@@ -1389,9 +1403,9 @@ static enum scan_result collapse_huge_page(struct mm_struct *mm, unsigned long s · 50 unmodified lines
1389 spin_lock(pmd_ptl);1403 spin_lock(pmd_ptl);
1390 VM_WARN_ON_ONCE(!pmd_none(*pmd));1404 VM_WARN_ON_ONCE(!pmd_none(*pmd));
1391 /*1405 /*
1392 * We can only use set_pmd_at when establishing1406 * We can only use set_pmd_at() when establishing
1393 * hugepmds and never for establishing regular pmds that1407 * hugepmds and never for establishing regular pmds that
1394 * points to regular pagetables. Use pmd_populate for that1408 * points to regular pagetables. Use pmd_populate() for that
1395 */1409 */
1396 pmd_populate(mm, pmd, pmd_pgtable(_pmd));1410 pmd_populate(mm, pmd, pmd_pgtable(_pmd));
1397 spin_unlock(pmd_ptl);1411 spin_unlock(pmd_ptl);
@@ -1449,10 +1463,10 @@ static enum scan_result collapse_huge_page(struct mm_struct *mm, unsigned long s · 51 unmodified lines
1449 1463
1450 result = SCAN_SUCCEED;1464 result = SCAN_SUCCEED;
1451out_up_write:1465out_up_write:
1452 if (anon_vma_locked)
1453 anon_vma_unlock_write(vma->anon_vma);
1454 if (pte)1466 if (pte)
1455 pte_unmap(pte);1467 pte_unmap(pte);
1468 if (anon_vma_locked)
1469 anon_vma_unlock_write(vma->anon_vma);
1456 mmap_write_unlock(mm);1470 mmap_write_unlock(mm);
1457out_nolock:1471out_nolock:
1458 if (folio)1472 if (folio)
@@ -1617,15 +1631,14 @@ static enum scan_result collapse_scan_pmd(struct mm_struct *mm, · 158 unmodified lines
1617 goto out;1631 goto out;
1618 }1632 }
1619 1633
1620 bitmap_zero(cc->mthp_present_ptes, MAX_PTRS_PER_PTE);1634 collapse_control_init_scan(cc);
1621 memset(cc->node_load, 0, sizeof(cc->node_load));
1622 nodes_clear(cc->alloc_nmask);
1623 1635
1624 enabled_orders = collapse_possible_orders(vma, vma->vm_flags, tva_flags);1636 enabled_orders = collapse_possible_orders(vma, vma->vm_flags, tva_flags);
1625 1637
1626 /*1638 /*
1627 * If PMD is the only enabled order, enforce max_ptes_none, otherwise1639 * If PMD is the only enabled order, enforce max_ptes_none, otherwise
1628 * scan all pages to populate the bitmap for mTHP collapse.1640 * scan all pages to populate the bitmap for mTHP collapse. The bitmap
1641 * is then checked again in mthp_collapse() for each attempted order.
1629 */1642 */
1630 if (enabled_orders != BIT(HPAGE_PMD_ORDER))1643 if (enabled_orders != BIT(HPAGE_PMD_ORDER))
1631 max_ptes_none = KHUGEPAGED_MAX_PTES_LIMIT;1644 max_ptes_none = KHUGEPAGED_MAX_PTES_LIMIT;
@@ -1647,9 +1660,8 @@ static enum scan_result collapse_scan_pmd(struct mm_struct *mm, · 15 unmodified lines
1647 if (pte_none_or_zero(pteval)) {1660 if (pte_none_or_zero(pteval)) {
1648 if (++none_or_zero > max_ptes_none) {1661 if (++none_or_zero > max_ptes_none) {
1649 result = SCAN_EXCEED_NONE_PTE;1662 result = SCAN_EXCEED_NONE_PTE;
1650 count_vm_event(THP_SCAN_EXCEED_NONE_PTE);1663 count_collapse_event(HPAGE_PMD_ORDER, THP_SCAN_EXCEED_NONE_PTE,
1651 count_mthp_stat(HPAGE_PMD_ORDER,1664 MTHP_STAT_COLLAPSE_EXCEED_NONE);
1652 MTHP_STAT_COLLAPSE_EXCEED_NONE);
1653 goto out_unmap;1665 goto out_unmap;
1654 }1666 }
1655 continue;1667 continue;
@@ -1657,9 +1669,8 @@ static enum scan_result collapse_scan_pmd(struct mm_struct *mm, · 1 unmodified line
1657 if (!pte_present(pteval)) {1669 if (!pte_present(pteval)) {
1658 if (++unmapped > max_ptes_swap) {1670 if (++unmapped > max_ptes_swap) {
1659 result = SCAN_EXCEED_SWAP_PTE;1671 result = SCAN_EXCEED_SWAP_PTE;
1660 count_vm_event(THP_SCAN_EXCEED_SWAP_PTE);1672 count_collapse_event(HPAGE_PMD_ORDER, THP_SCAN_EXCEED_SWAP_PTE,
1661 count_mthp_stat(HPAGE_PMD_ORDER,1673 MTHP_STAT_COLLAPSE_EXCEED_SWAP);
1662 MTHP_STAT_COLLAPSE_EXCEED_SWAP);
1663 goto out_unmap;1674 goto out_unmap;
1664 }1675 }
1665 /*1676 /*
@@ -1716,9 +1727,8 @@ static enum scan_result collapse_scan_pmd(struct mm_struct *mm, · 50 unmodified lines
1716 if (folio_maybe_mapped_shared(folio)) {1727 if (folio_maybe_mapped_shared(folio)) {
1717 if (++shared > max_ptes_shared) {1728 if (++shared > max_ptes_shared) {
1718 result = SCAN_EXCEED_SHARED_PTE;1729 result = SCAN_EXCEED_SHARED_PTE;
1719 count_vm_event(THP_SCAN_EXCEED_SHARED_PTE);1730 count_collapse_event(HPAGE_PMD_ORDER, THP_SCAN_EXCEED_SHARED_PTE,
1720 count_mthp_stat(HPAGE_PMD_ORDER,1731 MTHP_STAT_COLLAPSE_EXCEED_SHARED);
1721 MTHP_STAT_COLLAPSE_EXCEED_SHARED);
1722 goto out_unmap;1732 goto out_unmap;
1723 }1733 }
1724 }1734 }
@@ -1749,26 +1759,17 @@ static enum scan_result collapse_scan_pmd(struct mm_struct *mm, · 24 unmodified lines
1749 /*1759 /*
1750 * Check if the page has any GUP (or other external) pins.1760 * Check if the page has any GUP (or other external) pins.
1751 *1761 *
1752 * Here the check may be racy:1762 * Here the check is racy, but such cases are ephemeral and
1753 * it may see folio_mapcount() > folio_ref_count().1763 * we can always retry collapse later. Anyway the same
1754 * But such case is ephemeral we could always retry collapse1764 * check will be done again later, so the risk seems to be low.
1755 * later. However it may report false positive if the page
1756 * has excessive GUP pins (i.e. 512). Anyway the same check
1757 * will be done again later the risk seems low.
1758 */1765 */
1759 if (folio_expected_ref_count(folio) != folio_ref_count(folio)) {1766 if (folio_expected_ref_count(folio) != folio_ref_count(folio)) {
1760 result = SCAN_PAGE_COUNT;1767 result = SCAN_PAGE_COUNT;
1761 goto out_unmap;1768 goto out_unmap;
1762 }1769 }
1763 1770
1764 /*
1765 * If collapse was initiated by khugepaged, check that there is
1766 * enough young pte to justify collapsing the page
1767 */
1768 if (cc->is_khugepaged &&1771 if (cc->is_khugepaged &&
1769 (pte_young(pteval) || folio_test_young(folio) ||1772 folio_pte_referenced(folio, vma, addr, pteval))
1770 folio_test_referenced(folio) ||
1771 mmu_notifier_test_young(vma->vm_mm, addr)))
1772 referenced++;1773 referenced++;
1773 }1774 }
1774 if (cc->is_khugepaged &&1775 if (cc->is_khugepaged &&
@@ -1781,7 +1782,7 @@ static enum scan_result collapse_scan_pmd(struct mm_struct *mm, · 6 unmodified lines
1781out_unmap:1782out_unmap:
1782 pte_unmap_unlock(pte, ptl);1783 pte_unmap_unlock(pte, ptl);
1783 if (result == SCAN_SUCCEED) {1784 if (result == SCAN_SUCCEED) {
1784 /* collapse_huge_page expects the lock to be dropped before calling */1785 /* collapse_huge_page() expects the lock to be dropped before calling */
1785 mmap_read_unlock(mm);1786 mmap_read_unlock(mm);
1786 result = mthp_collapse(mm, start_addr, referenced,1787 result = mthp_collapse(mm, start_addr, referenced,
1787 unmapped, cc, enabled_orders);1788 unmapped, cc, enabled_orders);
@@ -2691,8 +2692,7 @@ static enum scan_result collapse_scan_file(struct mm_struct *mm, · 903 unmodified lines
2691 2692
2692 present = 0;2693 present = 0;
2693 swap = 0;2694 swap = 0;
2694 memset(cc->node_load, 0, sizeof(cc->node_load));2695 collapse_control_init_scan(cc);
2695 nodes_clear(cc->alloc_nmask);
2696 rcu_read_lock();2696 rcu_read_lock();
2697 xas_for_each(&xas, folio, start + HPAGE_PMD_NR - 1) {2697 xas_for_each(&xas, folio, start + HPAGE_PMD_NR - 1) {
2698 if (xas_retry(&xas, folio))2698 if (xas_retry(&xas, folio))
mm/kmemleak.c+92−13
@@ -151,6 +151,8 @@ struct kmemleak_object { · 150 unmodified lines
151 int min_count;151 int min_count;
152 /* the total number of pointers found pointing to this object */152 /* the total number of pointers found pointing to this object */
153 int count;153 int count;
154 /* consecutive scans the object has been seen unreferenced */
155 unsigned int unref_scans;
154 /* checksum for detecting modified objects */156 /* checksum for detecting modified objects */
155 u32 checksum;157 u32 checksum;
156 depot_stack_handle_t trace_handle;158 depot_stack_handle_t trace_handle;
@@ -175,6 +177,8 @@ struct kmemleak_object { · 18 unmodified lines
175#define OBJECT_PHYS (1 << 4)177#define OBJECT_PHYS (1 << 4)
176/* flag set for per-CPU pointers */178/* flag set for per-CPU pointers */
177#define OBJECT_PERCPU (1 << 5)179#define OBJECT_PERCPU (1 << 5)
180/* flag set on an object left unreferenced by the full scan, pending confirmation */
181#define OBJECT_SUSPECT (1 << 6)
178 182
179/* set when __remove_object() called */183/* set when __remove_object() called */
180#define DELSTATE_REMOVED (1 << 0)184#define DELSTATE_REMOVED (1 << 0)
@@ -232,9 +236,15 @@ static unsigned long max_percpu_addr; · 51 unmodified lines
232static struct task_struct *scan_thread;236static struct task_struct *scan_thread;
233/* used to avoid reporting of recently allocated objects */237/* used to avoid reporting of recently allocated objects */
234static unsigned long jiffies_min_age;238static unsigned long jiffies_min_age;
239/* consecutive scans an object must stay unreferenced before reporting */
240static unsigned int min_unref_scans =
241 IS_ENABLED(CONFIG_DEBUG_KMEMLEAK_VERBOSE) ? 2 : 1;
242module_param(min_unref_scans, uint, 0644);
235static unsigned long jiffies_last_scan;243static unsigned long jiffies_last_scan;
236/* delay between automatic memory scannings */244/* delay between automatic memory scannings */
237static unsigned long jiffies_scan_wait;245static unsigned long jiffies_scan_wait;
246/* number of objects flagged OBJECT_SUSPECT during the current scan */
247static int nr_suspects;
238/* enables or disables the task stacks scanning */248/* enables or disables the task stacks scanning */
239static int kmemleak_stack_scan = 1;249static int kmemleak_stack_scan = 1;
240/* protects the memory scanning, parameters and debug/kmemleak file access */250/* protects the memory scanning, parameters and debug/kmemleak file access */
@@ -688,6 +698,7 @@ static struct kmemleak_object *__alloc_object(gfp_t gfp) · 447 unmodified lines
688 object->excess_ref = 0;698 object->excess_ref = 0;
689 object->count = 0; /* white color initially */699 object->count = 0; /* white color initially */
690 object->checksum = ~0;700 object->checksum = ~0;
701 object->unref_scans = 0;
691 object->del_state = 0;702 object->del_state = 0;
692 703
693 /* task information */704 /* task information */
@@ -1440,6 +1451,11 @@ static void update_refs(struct kmemleak_object *object) · 746 unmodified lines
1440 */1451 */
1441 object->count++;1452 object->count++;
1442 if (color_gray(object)) {1453 if (color_gray(object)) {
1454 /* referenced after all, no longer a suspect */
1455 if (object->flags & OBJECT_SUSPECT) {
1456 object->flags &= ~OBJECT_SUSPECT;
1457 nr_suspects--;
1458 }
1443 /* put_object() called when removing from gray_list */1459 /* put_object() called when removing from gray_list */
1444 WARN_ON(!get_object(object));1460 WARN_ON(!get_object(object));
1445 list_add_tail(&object->gray_list, &gray_list);1461 list_add_tail(&object->gray_list, &gray_list);
@@ -1571,7 +1587,7 @@ static int scan_large_block(void *start, void *end) · 125 unmodified lines
1571 if (scan_block(start, next, NULL))1587 if (scan_block(start, next, NULL))
1572 return 1;1588 return 1;
1573 start = next;1589 start = next;
1574 cond_resched();1590 cond_resched_tasks_rcu_qs();
1575 }1591 }
1576 1592
1577 return 0;1593 return 0;
@@ -1608,7 +1624,7 @@ static void scan_object(struct kmemleak_object *object) · 30 unmodified lines
1608 scan_block(start, end, object);1624 scan_block(start, end, object);
1609 1625
1610 raw_spin_unlock_irqrestore(&object->lock, flags);1626 raw_spin_unlock_irqrestore(&object->lock, flags);
1611 cond_resched();1627 cond_resched_tasks_rcu_qs();
1612 raw_spin_lock_irqsave(&object->lock, flags);1628 raw_spin_lock_irqsave(&object->lock, flags);
1613 if (!(object->flags & OBJECT_ALLOCATED))1629 if (!(object->flags & OBJECT_ALLOCATED))
1614 break;1630 break;
@@ -1630,7 +1646,7 @@ static void scan_object(struct kmemleak_object *object) · 15 unmodified lines
1630 break;1646 break;
1631 1647
1632 raw_spin_unlock_irqrestore(&object->lock, flags);1648 raw_spin_unlock_irqrestore(&object->lock, flags);
1633 cond_resched();1649 cond_resched_tasks_rcu_qs();
1634 raw_spin_lock_irqsave(&object->lock, flags);1650 raw_spin_lock_irqsave(&object->lock, flags);
1635 } while (object->flags & OBJECT_ALLOCATED);1651 } while (object->flags & OBJECT_ALLOCATED);
1636 } else {1652 } else {
@@ -1658,7 +1674,7 @@ static void scan_gray_list(void) · 21 unmodified lines
1658 */1674 */
1659 object = list_entry(gray_list.next, typeof(*object), gray_list);1675 object = list_entry(gray_list.next, typeof(*object), gray_list);
1660 while (&object->gray_list != &gray_list) {1676 while (&object->gray_list != &gray_list) {
1661 cond_resched();1677 cond_resched_tasks_rcu_qs();
1662 1678
1663 /* may add new objects to the list */1679 /* may add new objects to the list */
1664 if (!scan_should_stop())1680 if (!scan_should_stop())
@@ -1693,7 +1709,7 @@ static void kmemleak_cond_resched(struct kmemleak_object *object) · 28 unmodified lines
1693 raw_spin_unlock_irq(&kmemleak_lock);1709 raw_spin_unlock_irq(&kmemleak_lock);
1694 1710
1695 rcu_read_unlock();1711 rcu_read_unlock();
1696 cond_resched();1712 cond_resched_tasks_rcu_qs();
1697 rcu_read_lock();1713 rcu_read_lock();
1698 1714
1699 raw_spin_lock_irq(&kmemleak_lock);1715 raw_spin_lock_irq(&kmemleak_lock);
@@ -1738,7 +1754,7 @@ static void kmemleak_scan_task_stacks(void) · 38 unmodified lines
1738 }1754 }
1739 put_task_struct(p);1755 put_task_struct(p);
1740 }1756 }
1741 cond_resched();1757 cond_resched_tasks_rcu_qs();
1742 } while (pid && !stop);1758 } while (pid && !stop);
1743}1759}
1744 1760
@@ -1844,16 +1860,16 @@ static void dedup_flush(struct xarray *dedup) · 99 unmodified lines
1844 * kernel's standard allocators. This function must be called with the1860 * kernel's standard allocators. This function must be called with the
1845 * scan_mutex held.1861 * scan_mutex held.
1846 */1862 */
1847static void kmemleak_scan(void)1863static int __kmemleak_scan(bool full)
1848{1864{
1849 struct kmemleak_object *object;1865 struct kmemleak_object *object;
1850 struct zone *zone;1866 struct zone *zone;
1851 int __maybe_unused i;1867 int __maybe_unused i;
1852 struct xarray dedup;
1853 int new_leaks = 0;
1854 int stop = 0;1868 int stop = 0;
1855 1869
1856 jiffies_last_scan = jiffies;1870 jiffies_last_scan = jiffies;
1871 if (full)
1872 nr_suspects = 0;
1857 1873
1858 /* prepare the kmemleak_object's */1874 /* prepare the kmemleak_object's */
1859 rcu_read_lock();1875 rcu_read_lock();
@@ -1881,8 +1897,13 @@ static void kmemleak_scan(void) · 21 unmodified lines
1881 __paint_it(object, KMEMLEAK_BLACK);1897 __paint_it(object, KMEMLEAK_BLACK);
1882 }1898 }
1883 1899
1900 /* referenced last scan: restart the unreferenced run */
1901 if (!color_white(object))
1902 object->unref_scans = 0;
1884 /* reset the reference count (whiten the object) */1903 /* reset the reference count (whiten the object) */
1885 object->count = 0;1904 object->count = 0;
1905 if (full)
1906 object->flags &= ~OBJECT_SUSPECT;
1886 if (color_gray(object) && get_object(object))1907 if (color_gray(object) && get_object(object))
1887 list_add_tail(&object->gray_list, &gray_list);1908 list_add_tail(&object->gray_list, &gray_list);
1888 1909
@@ -1915,7 +1936,7 @@ static void kmemleak_scan(void) · 26 unmodified lines
1915 struct page *page = pfn_to_online_page(pfn);1936 struct page *page = pfn_to_online_page(pfn);
1916 1937
1917 if (!(pfn & 63))1938 if (!(pfn & 63))
1918 cond_resched();1939 cond_resched_tasks_rcu_qs();
1919 1940
1920 if (!page)1941 if (!page)
1921 continue;1942 continue;
@@ -1950,6 +1971,10 @@ static void kmemleak_scan(void) · 28 unmodified lines
1950scan_gray:1971scan_gray:
1951 scan_gray_list();1972 scan_gray_list();
1952 1973
1974 /* a confirmation scan does not look for modified objects */
1975 if (!full)
1976 return nr_suspects;
1977
1953 /*1978 /*
1954 * Check for new or unreferenced objects modified since the previous1979 * Check for new or unreferenced objects modified since the previous
1955 * scan and color them gray until the next scan.1980 * scan and color them gray until the next scan.
@@ -1972,6 +1997,11 @@ scan_gray: · 16 unmodified lines
1972 /* color it gray temporarily */1997 /* color it gray temporarily */
1973 object->count = object->min_count;1998 object->count = object->min_count;
1974 list_add_tail(&object->gray_list, &gray_list);1999 list_add_tail(&object->gray_list, &gray_list);
2000 } else if (unreferenced_object(object) &&
2001 !(object->flags & OBJECT_REPORTED)) {
2002 /* flag the objects left unreferenced by this scan */
2003 object->flags |= OBJECT_SUSPECT;
2004 nr_suspects++;
1975 }2005 }
1976 raw_spin_unlock_irq(&object->lock);2006 raw_spin_unlock_irq(&object->lock);
1977 }2007 }
@@ -1982,12 +2012,62 @@ scan_gray: · 4 unmodified lines
1982 */2012 */
1983 scan_gray_list();2013 scan_gray_list();
1984 2014
2015 return nr_suspects;
2016}
2017
2018/*
2019 * Promote a suspected object to a reported leak once it has stayed
2020 * unreferenced for min_unref_scans consecutive scans. Called with
2021 * object->lock held; returns true when the object is newly reported.
2022 */
2023static bool confirm_leak(struct kmemleak_object *object)
2024{
2025 if (!unreferenced_object(object) ||
2026 !(object->flags & OBJECT_SUSPECT) ||
2027 (object->flags & OBJECT_REPORTED))
2028 return false;
2029
2030 object->unref_scans += 1;
2031 if (object->unref_scans < min_unref_scans)
2032 return false;
2033
2034 object->flags |= OBJECT_REPORTED;
2035 return true;
2036}
2037
2038/*
2039 * Scan the memory and report the unreferenced objects as leaks. Must be
2040 * called with the scan_mutex held.
2041 */
2042static void kmemleak_scan(void)
2043{
2044 struct kmemleak_object *object;
2045 struct xarray dedup;
2046 int new_leaks = 0;
2047
2048 /*
2049 * Full scan. Objects left unreferenced are flagged OBJECT_SUSPECT and
2050 * counted in the return value; nothing to confirm or report otherwise.
2051 */
2052 if (!__kmemleak_scan(true))
2053 return;
2054
1985 /*2055 /*
1986 * If scanning was stopped do not report any new unreferenced objects.2056 * If scanning was stopped do not report any new unreferenced objects.
1987 */2057 */
1988 if (scan_should_stop())2058 if (scan_should_stop())
1989 return;2059 return;
1990 2060
2061 /*
2062 * A live object whose only reference is moved by, for example, a
2063 * concurrent RCU update can be missed for one scan and reported as a
2064 * transient false positive. Scan again and only report the objects
2065 * left unreferenced (still flagged OBJECT_SUSPECT) by both scans.
2066 */
2067 __kmemleak_scan(false);
2068 if (scan_should_stop())
2069 return;
2070
1991 /*2071 /*
1992 * Scanning result reporting. When verbose printing is enabled, dedupe2072 * Scanning result reporting. When verbose printing is enabled, dedupe
1993 * by stackdepot trace_handle so each unique backtrace is logged once2073 * by stackdepot trace_handle so each unique backtrace is logged once
@@ -2014,9 +2094,8 @@ scan_gray: · 20 unmodified lines
2014 raw_spin_lock_irq(&object->lock);2094 raw_spin_lock_irq(&object->lock);
2015 trace_handle = 0;2095 trace_handle = 0;
2016 dedup_print = false;2096 dedup_print = false;
2017 if (unreferenced_object(object) &&2097
2018 !(object->flags & OBJECT_REPORTED)) {2098 if (confirm_leak(object)) {
2019 object->flags |= OBJECT_REPORTED;
2020 if (kmemleak_verbose) {2099 if (kmemleak_verbose) {
2021 trace_handle = object->trace_handle;2100 trace_handle = object->trace_handle;
2022 dedup_print = true;2101 dedup_print = true;
mm/ksm.c+7−9
@@ -959,10 +959,9 @@ enum ksm_get_folio_flags { · 958 unmodified lines
959 * seconds or even minutes: much too unresponsive. So instead we use a959 * seconds or even minutes: much too unresponsive. So instead we use a
960 * "keyhole reference": access to the ksm page from the stable node peeps960 * "keyhole reference": access to the ksm page from the stable node peeps
961 * out through its keyhole to see if that page still holds the right key,961 * out through its keyhole to see if that page still holds the right key,
962 * pointing back to this stable node. This relies on freeing a PageAnon962 * pointing back to this stable node. This relies on freeing an anon
963 * page to reset its page->mapping to NULL, and relies on no other use of963 * folio to reset its mapping to NULL, and relies on no other use of a
964 * a page to put something that might look like our key in page->mapping.964 * folio to put something that might look like our key in its mapping.
965 * is on its way to being freed; but it is an anomaly to bear in mind.
966 */965 */
967static struct folio *ksm_get_folio(struct ksm_stable_node *stable_node,966static struct folio *ksm_get_folio(struct ksm_stable_node *stable_node,
968 enum ksm_get_folio_flags flags)967 enum ksm_get_folio_flags flags)
@@ -1625,7 +1624,7 @@ static int try_to_merge_with_ksm_page(struct ksm_rmap_item *rmap_item, · 656 unmodified lines
1625 * stable_tree, break_cow() will clean it up.1624 * stable_tree, break_cow() will clean it up.
1626 */1625 */
1627 rmap_item->anon_vma = vma->anon_vma;1626 rmap_item->anon_vma = vma->anon_vma;
1628 rmap_item->linear_page_index = linear_page_index(vma, rmap_item->address);1627 rmap_item->linear_page_index = linear_anon_page_index(vma, rmap_item->address);
1629 get_anon_vma(vma->anon_vma);1628 get_anon_vma(vma->anon_vma);
1630out:1629out:
1631 mmap_read_unlock(mm);1630 mmap_read_unlock(mm);
@@ -3060,10 +3059,9 @@ int __ksm_enter(struct mm_struct *mm) · 1428 unmodified lines
3060 3059
3061 slot = &mm_slot->slot;3060 slot = &mm_slot->slot;
3062 3061
3062 spin_lock(&ksm_mmlist_lock);
3063 /* Check ksm_run too? Would need tighter locking */3063 /* Check ksm_run too? Would need tighter locking */
3064 needs_wakeup = list_empty(&ksm_mm_head.slot.mm_node);3064 needs_wakeup = list_empty(&ksm_mm_head.slot.mm_node);
3065
3066 spin_lock(&ksm_mmlist_lock);
3067 mm_slot_insert(mm_slots_hash, mm, slot);3065 mm_slot_insert(mm_slots_hash, mm, slot);
3068 /*3066 /*
3069 * When KSM_RUN_MERGE (or KSM_RUN_STOP),3067 * When KSM_RUN_MERGE (or KSM_RUN_STOP),
@@ -3152,7 +3150,7 @@ struct folio *ksm_might_need_to_copy(struct folio *folio, · 82 unmodified lines
3152 return folio; /* no need to copy it */3150 return folio; /* no need to copy it */
3153 } else if (!anon_vma) {3151 } else if (!anon_vma) {
3154 return folio; /* no need to copy it */3152 return folio; /* no need to copy it */
3155 } else if (folio->index == linear_page_index(vma, addr) &&3153 } else if (folio->index == linear_anon_page_index(vma, addr) &&
3156 anon_vma->root == vma->anon_vma->root) {3154 anon_vma->root == vma->anon_vma->root) {
3157 return folio; /* still no need to copy it */3155 return folio; /* still no need to copy it */
3158 }3156 }
@@ -3222,7 +3220,7 @@ again: · 63 unmodified lines
3222 /*3220 /*
3223 * Currently, KSM folios are always small folios, so it's3221 * Currently, KSM folios are always small folios, so it's
3224 * sufficient to search for a single page. We can simply use3222 * sufficient to search for a single page. We can simply use
3225 * the linear_page_index of the original de-duplicate3223 * the linear_anon_page_index of the original de-duplicate
3226 * anonymous page that we remembered in the rmap_item while3224 * anonymous page that we remembered in the rmap_item while
3227 * de-duplicating. Note that mremap() always de-duplicates KSM3225 * de-duplicating. Note that mremap() always de-duplicates KSM
3228 * folios: so if there was mremap() in our parent or our child,3226 * folios: so if there was mremap() in our parent or our child,
mm/madvise.c+9−8
@@ -32,6 +32,7 @@ · 31 unmodified lines
32#include <linux/leafops.h>32#include <linux/leafops.h>
33#include <linux/shmem_fs.h>33#include <linux/shmem_fs.h>
34#include <linux/mmu_notifier.h>34#include <linux/mmu_notifier.h>
35#include <linux/swap_ops.h>
35 36
36#include <asm/tlb.h>37#include <asm/tlb.h>
37 38
@@ -188,7 +189,7 @@ static int swapin_walk_pmd_entry(pmd_t *pmd, unsigned long start, · 150 unmodified lines
188 unsigned long end, struct mm_walk *walk)189 unsigned long end, struct mm_walk *walk)
189{190{
190 struct vm_area_struct *vma = walk->private;191 struct vm_area_struct *vma = walk->private;
191 struct swap_iocb *splug = NULL;192 struct swap_io_ctx ctx = {};
192 pte_t *ptep = NULL;193 pte_t *ptep = NULL;
193 spinlock_t *ptl;194 spinlock_t *ptl;
194 unsigned long addr;195 unsigned long addr;
@@ -212,15 +213,15 @@ static int swapin_walk_pmd_entry(pmd_t *pmd, unsigned long start, · 17 unmodified lines
212 pte_unmap_unlock(ptep, ptl);213 pte_unmap_unlock(ptep, ptl);
213 ptep = NULL;214 ptep = NULL;
214 215
215 folio = read_swap_cache_async(entry, GFP_HIGHUSER_MOVABLE,216 folio = read_swap_cache_async(&ctx, entry, GFP_HIGHUSER_MOVABLE,
216 vma, addr, &splug);217 vma, addr);
217 if (folio)218 if (folio)
218 folio_put(folio);219 folio_put(folio);
219 }220 }
220 221
221 if (ptep)222 if (ptep)
222 pte_unmap_unlock(ptep, ptl);223 pte_unmap_unlock(ptep, ptl);
223 swap_read_unplug(splug);224 swap_read_submit(&ctx);
224 cond_resched();225 cond_resched();
225 226
226 return 0;227 return 0;
@@ -238,7 +239,7 @@ static void shmem_swapin_range(struct vm_area_struct *vma, · 11 unmodified lines
238 XA_STATE(xas, &mapping->i_pages, linear_page_index(vma, start));239 XA_STATE(xas, &mapping->i_pages, linear_page_index(vma, start));
239 pgoff_t end_index = linear_page_index(vma, end) - 1;240 pgoff_t end_index = linear_page_index(vma, end) - 1;
240 struct folio *folio;241 struct folio *folio;
241 struct swap_iocb *splug = NULL;242 struct swap_io_ctx ctx = {};
242 243
243 rcu_read_lock();244 rcu_read_lock();
244 xas_for_each(&xas, folio, end_index) {245 xas_for_each(&xas, folio, end_index) {
@@ -257,15 +258,15 @@ static void shmem_swapin_range(struct vm_area_struct *vma, · 12 unmodified lines
257 xas_pause(&xas);258 xas_pause(&xas);
258 rcu_read_unlock();259 rcu_read_unlock();
259 260
260 folio = read_swap_cache_async(entry, mapping_gfp_mask(mapping),261 folio = read_swap_cache_async(&ctx, entry,
261 vma, addr, &splug);262 mapping_gfp_mask(mapping), vma, addr);
262 if (folio)263 if (folio)
263 folio_put(folio);264 folio_put(folio);
264 265
265 rcu_read_lock();266 rcu_read_lock();
266 }267 }
267 rcu_read_unlock();268 rcu_read_unlock();
268 swap_read_unplug(splug);269 swap_read_submit(&ctx);
269}270}
270#endif /* CONFIG_SWAP */271#endif /* CONFIG_SWAP */
271 272
mm/memcontrol-v1.c+2−2
@@ -2287,8 +2287,8 @@ void memcg1_stat_format(struct mem_cgroup *memcg, struct seq_buf *s) · 2286 unmodified lines
2287 for_each_online_pgdat(pgdat) {2287 for_each_online_pgdat(pgdat) {
2288 mz = memcg->nodeinfo[pgdat->node_id];2288 mz = memcg->nodeinfo[pgdat->node_id];
2289 2289
2290 anon_cost += mz->lruvec.anon_cost;2290 anon_cost += mz->lruvec.cost[WORKINGSET_ANON].count;
2291 file_cost += mz->lruvec.file_cost;2291 file_cost += mz->lruvec.cost[WORKINGSET_FILE].count;
2292 }2292 }
2293 seq_buf_printf(s, "anon_cost %lu\n", anon_cost);2293 seq_buf_printf(s, "anon_cost %lu\n", anon_cost);
2294 seq_buf_printf(s, "file_cost %lu\n", file_cost);2294 seq_buf_printf(s, "file_cost %lu\n", file_cost);
mm/memcontrol-v1.h+1−0
@@ -4,6 +4,7 @@ · 3 unmodified lines
4#define __MM_MEMCONTROL_V1_H4#define __MM_MEMCONTROL_V1_H
5 5
6#include <linux/cgroup-defs.h>6#include <linux/cgroup-defs.h>
7#include <linux/memcontrol.h>
7 8
8/* Cgroup v1 and v2 common declarations */9/* Cgroup v1 and v2 common declarations */
9 10
mm/memcontrol.c+66−3
@@ -63,6 +63,7 @@ · 62 unmodified lines
63#include <linux/sched/isolation.h>63#include <linux/sched/isolation.h>
64#include <linux/kmemleak.h>64#include <linux/kmemleak.h>
65#include "internal.h"65#include "internal.h"
66#include "swap.h"
66#include "swap_table.h"67#include "swap_table.h"
67#include <net/sock.h>68#include <net/sock.h>
68#include <net/ip.h>69#include <net/ip.h>
@@ -398,6 +399,7 @@ static const unsigned int memcg_node_stat_items[] = { · 329 unmodified lines
398 NR_SHMEM_THPS,399 NR_SHMEM_THPS,
399 NR_FILE_THPS,400 NR_FILE_THPS,
400 NR_ANON_THPS,401 NR_ANON_THPS,
402 NR_VMSCAN_WRITE,
401 NR_VMALLOC,403 NR_VMALLOC,
402 NR_KERNEL_STACK_KB,404 NR_KERNEL_STACK_KB,
403 NR_PAGETABLE,405 NR_PAGETABLE,
@@ -424,6 +426,8 @@ static const unsigned int memcg_node_stat_items[] = { · 20 unmodified lines
424 PGSCAN_PROACTIVE,426 PGSCAN_PROACTIVE,
425 PGSCAN_ANON,427 PGSCAN_ANON,
426 PGSCAN_FILE,428 PGSCAN_FILE,
429 PGROTATE_ANON,
430 PGROTATE_FILE,
427 PGREFILL,431 PGREFILL,
428#ifdef CONFIG_HUGETLB_PAGE432#ifdef CONFIG_HUGETLB_PAGE
429 NR_HUGETLB,433 NR_HUGETLB,
@@ -507,6 +511,42 @@ unsigned long lruvec_page_state(struct lruvec *lruvec, enum node_stat_item idx) · 77 unmodified lines
507 return x;511 return x;
508}512}
509 513
514/**
515 * lruvec_page_state_monotonic - non-clamping lruvec stat read for delta sampling
516 * @lruvec: the LRU vector to read from
517 * @idx: the node_stat_item to read
518 *
519 * Returns the raw state[idx] value cast to unsigned long, skipping the
520 * clamp-negative-to-zero step in lruvec_page_state(). Intended for callers
521 * that snapshot a monotonically-incremented counter and subtract two
522 * samples: unsigned modular arithmetic then yields the correct delta across
523 * a signed-long wraparound (a real hazard on 32-bit) that the clamp would
524 * otherwise turn into a huge spurious delta.
525 *
526 * Do NOT use for non-monotonic page-count reads where a transient negative
527 * reading from per-CPU delta skew must present as zero.
528 *
529 * XXX: This helper (and its node/global peers) exists because some
530 * monotonically-incremented event counters are stored in
531 * enum node_stat_item.
532 */
533unsigned long lruvec_page_state_monotonic(struct lruvec *lruvec,
534 enum node_stat_item idx)
535{
536 struct mem_cgroup_per_node *pn;
537 int i;
538
539 if (mem_cgroup_disabled())
540 return node_page_state_monotonic(lruvec_pgdat(lruvec), idx);
541
542 i = memcg_stats_index(idx);
543 if (WARN_ONCE(BAD_STAT_IDX(i), "%s: missing stat item %d\n", __func__, idx))
544 return 0;
545
546 pn = container_of(lruvec, struct mem_cgroup_per_node, lruvec);
547 return (unsigned long)READ_ONCE(pn->lruvec_stats->state[i]);
548}
549
510unsigned long lruvec_page_state_local(struct lruvec *lruvec,550unsigned long lruvec_page_state_local(struct lruvec *lruvec,
511 enum node_stat_item idx)551 enum node_stat_item idx)
512{552{
@@ -2100,7 +2140,12 @@ static bool consume_stock(struct mem_cgroup *memcg, unsigned int nr_pages) · 1587 unmodified lines
2100 2140
2101 stock_pages = READ_ONCE(stock->nr_pages[i]);2141 stock_pages = READ_ONCE(stock->nr_pages[i]);
2102 if (stock_pages >= nr_pages) {2142 if (stock_pages >= nr_pages) {
2103 WRITE_ONCE(stock->nr_pages[i], stock_pages - nr_pages);2143 stock_pages -= nr_pages;
2144 WRITE_ONCE(stock->nr_pages[i], stock_pages);
2145 if (!stock_pages) {
2146 css_put(&memcg->css);
2147 WRITE_ONCE(stock->cached[i], NULL);
2148 }
2104 ret = true;2149 ret = true;
2105 }2150 }
2106 break;2151 break;
@@ -2653,6 +2698,19 @@ retry: · 546 unmodified lines
2653 if (!gfpflags_allow_blocking(gfp_mask))2698 if (!gfpflags_allow_blocking(gfp_mask))
2654 goto nomem;2699 goto nomem;
2655 2700
2701 /*
2702 * OOM victim still needs to charge memory to exit. OOM reaper should
2703 * help but it might fail on mmap_lock contention. If the victim is a
2704 * large thread group then all exiting threads might compete on oom_lock
2705 * just to learn that there is nothing really killable anymore. Bail
2706 * out early and fail the charge to expedite their exit. They are
2707 * considered fully reclaimed by the oom reaper and they shouldn't
2708 * contribute further charges.
2709 */
2710 if (tsk_is_oom_victim(current) &&
2711 mm_flags_test(MMF_OOM_SKIP, current->signal->oom_mm))
2712 goto nomem;
2713
2656 __memcg_memory_event(mem_over_limit, MEMCG_MAX, allow_spinning);2714 __memcg_memory_event(mem_over_limit, MEMCG_MAX, allow_spinning);
2657 raised_max_event = true;2715 raised_max_event = true;
2658 2716
@@ -4177,11 +4235,10 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) · 1518 unmodified lines
4177#endif4235#endif
4178 page_counter_set_high(&memcg->swap, PAGE_COUNTER_MAX);4236 page_counter_set_high(&memcg->swap, PAGE_COUNTER_MAX);
4179 if (parent) {4237 if (parent) {
4180 WRITE_ONCE(memcg->swappiness, mem_cgroup_swappiness(parent));
4181
4182 page_counter_init(&memcg->memory, &parent->memory, memcg_on_dfl);4238 page_counter_init(&memcg->memory, &parent->memory, memcg_on_dfl);
4183 page_counter_init(&memcg->swap, &parent->swap, false);4239 page_counter_init(&memcg->swap, &parent->swap, false);
4184#ifdef CONFIG_MEMCG_V14240#ifdef CONFIG_MEMCG_V1
4241 WRITE_ONCE(memcg->swappiness, mem_cgroup_swappiness(parent));
4185 memcg->memory.track_failcnt = !memcg_on_dfl;4242 memcg->memory.track_failcnt = !memcg_on_dfl;
4186 memcg->memsw.track_failcnt = !memcg_on_dfl;4243 memcg->memsw.track_failcnt = !memcg_on_dfl;
4187 WRITE_ONCE(memcg->oom_kill_disable, READ_ONCE(parent->oom_kill_disable));4244 WRITE_ONCE(memcg->oom_kill_disable, READ_ONCE(parent->oom_kill_disable));
@@ -4801,6 +4858,9 @@ static ssize_t memory_high_write(struct kernfs_open_file *of, · 613 unmodified lines
4801 unsigned long nr_pages = page_counter_read(&memcg->memory);4858 unsigned long nr_pages = page_counter_read(&memcg->memory);
4802 unsigned long reclaimed;4859 unsigned long reclaimed;
4803 4860
4861 if (high != READ_ONCE(memcg->memory.high))
4862 break;
4863
4804 if (nr_pages <= high)4864 if (nr_pages <= high)
4805 break;4865 break;
4806 4866
@@ -4856,6 +4916,9 @@ static ssize_t memory_max_write(struct kernfs_open_file *of, · 49 unmodified lines
4856 for (;;) {4916 for (;;) {
4857 unsigned long nr_pages = page_counter_read(&memcg->memory);4917 unsigned long nr_pages = page_counter_read(&memcg->memory);
4858 4918
4919 if (max != READ_ONCE(memcg->memory.max))
4920 break;
4921
4859 if (nr_pages <= max)4922 if (nr_pages <= max)
4860 break;4923 break;
4861 4924
mm/memory-failure.c+2−2
@@ -620,7 +620,7 @@ static void add_to_kill_fsdax(struct task_struct *tsk, const struct page *p, · 619 unmodified lines
620 struct vm_area_struct *vma,620 struct vm_area_struct *vma,
621 struct list_head *to_kill, pgoff_t pgoff)621 struct list_head *to_kill, pgoff_t pgoff)
622{622{
623 unsigned long addr = vma_address(vma, pgoff, 1);623 unsigned long addr = vma_filebacked_address(vma, pgoff, 1);
624 __add_to_kill(tsk, p, vma, to_kill, addr);624 __add_to_kill(tsk, p, vma, to_kill, addr);
625}625}
626 626
@@ -2265,7 +2265,7 @@ static void add_to_kill_pgoff(struct task_struct *tsk, · 1638 unmodified lines
2265 }2265 }
2266 2266
2267 /* Check for pgoff not backed by struct page */2267 /* Check for pgoff not backed by struct page */
2268 tk->addr = vma_address(vma, pgoff, 1);2268 tk->addr = vma_filebacked_address(vma, pgoff, 1);
2269 tk->size_shift = PAGE_SHIFT;2269 tk->size_shift = PAGE_SHIFT;
2270 2270
2271 if (tk->addr == -EFAULT)2271 if (tk->addr == -EFAULT)
mm/memory.c+101−39
@@ -519,9 +519,52 @@ static bool is_bad_page_map_ratelimited(void) · 518 unmodified lines
519 return false;519 return false;
520}520}
521 521
522static void ptval_bytes_to_hex_str(char *buf, size_t buf_size, const void *entry, size_t entry_size)
523{
524 if (WARN_ON_ONCE(buf_size < entry_size * 2 + 1)) {
525 snprintf(buf, buf_size, "overflow");
526 return;
527 }
528
529 switch (entry_size) {
530 case sizeof(u32):
531 snprintf(buf, buf_size, "%08x", *(const u32 *)entry);
532 break;
533 case sizeof(u64):
534 snprintf(buf, buf_size, "%016llx", *(const u64 *)entry);
535 break;
536#if defined(__SIZEOF_INT128__)
537 case sizeof(u128):
538 snprintf(buf, buf_size, "%016llx%016llx",
539 (unsigned long long)(*(const u128 *)entry >> 64),
540 (unsigned long long)*(const u128 *)entry);
541 break;
542#endif
543 default:
544 snprintf(buf, buf_size, "unsupported");
545 break;
546 }
547}
548
549#define ptval_to_str(buf, val) \
550 do { \
551 auto __val = (val); \
552 \
553 ptval_bytes_to_hex_str((buf), sizeof(buf), &__val, sizeof(__val)); \
554 } while (0)
555
556#if defined(__SIZEOF_INT128__)
557#define PTVAL_STR_MAX (32 + 1) /* Max 128-bit value in hex + NUL */
558#else
559#define PTVAL_STR_MAX (16 + 1) /* Max 64-bit value in hex + NUL */
560#endif
561
522static void __print_bad_page_map_pgtable(struct mm_struct *mm, unsigned long addr)562static void __print_bad_page_map_pgtable(struct mm_struct *mm, unsigned long addr)
523{563{
524 unsigned long long pgdv, p4dv, pudv, pmdv;564 char pgd_str[PTVAL_STR_MAX];
565 char p4d_str[PTVAL_STR_MAX];
566 char pud_str[PTVAL_STR_MAX];
567 char pmd_str[PTVAL_STR_MAX];
525 p4d_t p4d, *p4dp;568 p4d_t p4d, *p4dp;
526 pud_t pud, *pudp;569 pud_t pud, *pudp;
527 pmd_t pmd, *pmdp;570 pmd_t pmd, *pmdp;
@@ -532,34 +575,34 @@ static void __print_bad_page_map_pgtable(struct mm_struct *mm, unsigned long add · 4 unmodified lines
532 * see locking requirements for print_bad_page_map().575 * see locking requirements for print_bad_page_map().
533 */576 */
534 pgdp = pgd_offset(mm, addr);577 pgdp = pgd_offset(mm, addr);
535 pgdv = pgd_val(*pgdp);578 ptval_to_str(pgd_str, pgd_val(*pgdp));
536 579
537 if (!pgd_present(*pgdp) || pgd_leaf(*pgdp)) {580 if (!pgd_present(*pgdp) || pgd_leaf(*pgdp)) {
538 pr_alert("pgd:%08llx\n", pgdv);581 pr_alert("pgd:%s\n", pgd_str);
539 return;582 return;
540 }583 }
541 584
542 p4dp = p4d_offset(pgdp, addr);585 p4dp = p4d_offset(pgdp, addr);
543 p4d = p4dp_get(p4dp);586 p4d = p4dp_get(p4dp);
544 p4dv = p4d_val(p4d);587 ptval_to_str(p4d_str, p4d_val(p4d));
545 588
546 if (!p4d_present(p4d) || p4d_leaf(p4d)) {589 if (!p4d_present(p4d) || p4d_leaf(p4d)) {
547 pr_alert("pgd:%08llx p4d:%08llx\n", pgdv, p4dv);590 pr_alert("pgd:%s p4d:%s\n", pgd_str, p4d_str);
548 return;591 return;
549 }592 }
550 593
551 pudp = pud_offset(p4dp, addr);594 pudp = pud_offset(p4dp, addr);
552 pud = pudp_get(pudp);595 pud = pudp_get(pudp);
553 pudv = pud_val(pud);596 ptval_to_str(pud_str, pud_val(pud));
554 597
555 if (!pud_present(pud) || pud_leaf(pud)) {598 if (!pud_present(pud) || pud_leaf(pud)) {
556 pr_alert("pgd:%08llx p4d:%08llx pud:%08llx\n", pgdv, p4dv, pudv);599 pr_alert("pgd:%s p4d:%s pud:%s\n", pgd_str, p4d_str, pud_str);
557 return;600 return;
558 }601 }
559 602
560 pmdp = pmd_offset(pudp, addr);603 pmdp = pmd_offset(pudp, addr);
561 pmd = pmdp_get(pmdp);604 pmd = pmdp_get(pmdp);
562 pmdv = pmd_val(pmd);605 ptval_to_str(pmd_str, pmd_val(pmd));
563 606
564 /*607 /*
565 * Dumping the PTE would be nice, but it's tricky with CONFIG_HIGHPTE,608 * Dumping the PTE would be nice, but it's tricky with CONFIG_HIGHPTE,
@@ -567,8 +610,7 @@ static void __print_bad_page_map_pgtable(struct mm_struct *mm, unsigned long add · 1 unmodified line
567 * doing another map would be bad. print_bad_page_map() should610 * doing another map would be bad. print_bad_page_map() should
568 * already take care of printing the PTE.611 * already take care of printing the PTE.
569 */612 */
570 pr_alert("pgd:%08llx p4d:%08llx pud:%08llx pmd:%08llx\n", pgdv,613 pr_alert("pgd:%s p4d:%s pud:%s pmd:%s\n", pgd_str, p4d_str, pud_str, pmd_str);
571 p4dv, pudv, pmdv);
572}614}
573 615
574/*616/*
@@ -584,25 +626,34 @@ static void __print_bad_page_map_pgtable(struct mm_struct *mm, unsigned long add · 9 unmodified lines
584 * page table lock.626 * page table lock.
585 */627 */
586static void print_bad_page_map(struct vm_area_struct *vma,628static void print_bad_page_map(struct vm_area_struct *vma,
587 unsigned long addr, unsigned long long entry, struct page *page,629 unsigned long addr, const void *entry, size_t entry_size,
588 enum pgtable_level level)630 struct page *page, enum pgtable_level level)
589{631{
590 struct address_space *mapping;632 struct address_space *mapping;
591 pgoff_t index;633 char entry_str[PTVAL_STR_MAX];
634 pgoff_t index, anon_index;
592 635
593 if (is_bad_page_map_ratelimited())636 if (is_bad_page_map_ratelimited())
594 return;637 return;
595 638
596 mapping = vma->vm_file ? vma->vm_file->f_mapping : NULL;639 mapping = vma->vm_file ? vma->vm_file->f_mapping : NULL;
597 index = linear_page_index(vma, addr);640 index = linear_page_index(vma, addr);
641 anon_index = __linear_anon_page_index(vma, addr);
598 642
599 pr_alert("BUG: Bad page map in process %s %s:%08llx", current->comm,643 ptval_bytes_to_hex_str(entry_str, sizeof(entry_str), entry, entry_size);
600 pgtable_level_to_str(level), entry);644 pr_alert("BUG: Bad page map in process %s %s:%s", current->comm,
645 pgtable_level_to_str(level), entry_str);
601 __print_bad_page_map_pgtable(vma->vm_mm, addr);646 __print_bad_page_map_pgtable(vma->vm_mm, addr);
602 if (page)647 if (page)
603 dump_page(page, "bad page map");648 dump_page(page, "bad page map");
604 pr_alert("addr:%px vm_flags:%08lx anon_vma:%px mapping:%px index:%lx\n",649 pr_alert("addr:%px vm_flags:%08lx anon_vma:%px mapping:%px",
605 (void *)addr, vma->vm_flags, vma->anon_vma, mapping, index);650 (void *)addr, vma->vm_flags, vma->anon_vma, mapping);
651 if (!vma_is_cow_mapping(vma) || index == anon_index) {
652 pr_cont(" index:%lx\n", index);
653 } else {
654 pr_cont(" index:%lx (file) %lx (anon)\n", index, anon_index);
655 }
656
606 pr_alert("file:%pD fault:%ps mmap:%ps mmap_prepare: %ps read_folio:%ps\n",657 pr_alert("file:%pD fault:%ps mmap:%ps mmap_prepare: %ps read_folio:%ps\n",
607 vma->vm_file,658 vma->vm_file,
608 vma->vm_ops ? vma->vm_ops->fault : NULL,659 vma->vm_ops ? vma->vm_ops->fault : NULL,
@@ -627,8 +678,13 @@ static inline bool pgtable_level_has_pxx_special(enum pgtable_level level) · 18 unmodified lines
627 }678 }
628}679}
629 680
630#define print_bad_pte(vma, addr, pte, page) \681static void print_bad_pte(struct vm_area_struct *vma, unsigned long addr,
631 print_bad_page_map(vma, addr, pte_val(pte), page, PGTABLE_LEVEL_PTE)682 pte_t pte, struct page *page)
683{
684 auto entry = pte_val(pte);
685
686 print_bad_page_map(vma, addr, &entry, sizeof(entry), page, PGTABLE_LEVEL_PTE);
687}
632 688
633/**689/**
634 * __vm_normal_page() - Get the "struct page" associated with a page table entry.690 * __vm_normal_page() - Get the "struct page" associated with a page table entry.
@@ -636,8 +692,9 @@ static inline bool pgtable_level_has_pxx_special(enum pgtable_level level) · 1 unmodified line
636 * @addr: The address where the page table entry is mapped.692 * @addr: The address where the page table entry is mapped.
637 * @pfn: The PFN stored in the page table entry.693 * @pfn: The PFN stored in the page table entry.
638 * @special: Whether the page table entry is marked "special".694 * @special: Whether the page table entry is marked "special".
639 * @level: The page table level for error reporting purposes only.
640 * @entry: The page table entry value for error reporting purposes only.695 * @entry: The page table entry value for error reporting purposes only.
696 * @entry_size: The size of @entry.
697 * @level: The page table level for error reporting purposes only.
641 *698 *
642 * "Special" mappings do not wish to be associated with a "struct page" (either699 * "Special" mappings do not wish to be associated with a "struct page" (either
643 * it doesn't exist, or it exists but they don't want to touch it). In this700 * it doesn't exist, or it exists but they don't want to touch it). In this
@@ -697,7 +754,7 @@ static inline bool pgtable_level_has_pxx_special(enum pgtable_level level) · 53 unmodified lines
697 */754 */
698static inline struct page *__vm_normal_page(struct vm_area_struct *vma,755static inline struct page *__vm_normal_page(struct vm_area_struct *vma,
699 unsigned long addr, unsigned long pfn, bool special,756 unsigned long addr, unsigned long pfn, bool special,
700 unsigned long long entry, enum pgtable_level level)757 const void *entry, size_t entry_size, enum pgtable_level level)
701{758{
702 if (pgtable_level_has_pxx_special(level)) {759 if (pgtable_level_has_pxx_special(level)) {
703 if (unlikely(special)) {760 if (unlikely(special)) {
@@ -710,7 +767,7 @@ static inline struct page *__vm_normal_page(struct vm_area_struct *vma, · 6 unmodified lines
710 if (is_zero_pfn(pfn) || is_huge_zero_pfn(pfn))767 if (is_zero_pfn(pfn) || is_huge_zero_pfn(pfn))
711 return NULL;768 return NULL;
712 769
713 print_bad_page_map(vma, addr, entry, NULL, level);770 print_bad_page_map(vma, addr, entry, entry_size, NULL, level);
714 return NULL;771 return NULL;
715 }772 }
716 /*773 /*
@@ -730,7 +787,7 @@ static inline struct page *__vm_normal_page(struct vm_area_struct *vma, · 13 unmodified lines
730 /* Only CoW'ed anon folios are "normal". */787 /* Only CoW'ed anon folios are "normal". */
731 if (pfn == index)788 if (pfn == index)
732 return NULL;789 return NULL;
733 if (!is_cow_mapping(vma->vm_flags))790 if (!vma_is_cow_mapping(vma))
734 return NULL;791 return NULL;
735 }792 }
736 }793 }
@@ -741,7 +798,7 @@ static inline struct page *__vm_normal_page(struct vm_area_struct *vma, · 4 unmodified lines
741 798
742 if (unlikely(pfn > highest_memmap_pfn)) {799 if (unlikely(pfn > highest_memmap_pfn)) {
743 /* Corrupted page table entry. */800 /* Corrupted page table entry. */
744 print_bad_page_map(vma, addr, entry, NULL, level);801 print_bad_page_map(vma, addr, entry, entry_size, NULL, level);
745 return NULL;802 return NULL;
746 }803 }
747 /*804 /*
@@ -767,8 +824,10 @@ static inline struct page *__vm_normal_page(struct vm_area_struct *vma, · 19 unmodified lines
767struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr,824struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
768 pte_t pte)825 pte_t pte)
769{826{
827 auto entry = pte_val(pte);
828
770 return __vm_normal_page(vma, addr, pte_pfn(pte), pte_special(pte),829 return __vm_normal_page(vma, addr, pte_pfn(pte), pte_special(pte),
771 pte_val(pte), PGTABLE_LEVEL_PTE);830 &entry, sizeof(entry), PGTABLE_LEVEL_PTE);
772}831}
773 832
774/**833/**
@@ -809,8 +868,10 @@ struct folio *vm_normal_folio(struct vm_area_struct *vma, unsigned long addr, · 34 unmodified lines
809struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr,868struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr,
810 pmd_t pmd)869 pmd_t pmd)
811{870{
871 auto entry = pmd_val(pmd);
872
812 return __vm_normal_page(vma, addr, pmd_pfn(pmd), pmd_special(pmd),873 return __vm_normal_page(vma, addr, pmd_pfn(pmd), pmd_special(pmd),
813 pmd_val(pmd), PGTABLE_LEVEL_PMD);874 &entry, sizeof(entry), PGTABLE_LEVEL_PMD);
814}875}
815 876
816/**877/**
@@ -850,8 +911,10 @@ struct folio *vm_normal_folio_pmd(struct vm_area_struct *vma, · 33 unmodified lines
850struct page *vm_normal_page_pud(struct vm_area_struct *vma,911struct page *vm_normal_page_pud(struct vm_area_struct *vma,
851 unsigned long addr, pud_t pud)912 unsigned long addr, pud_t pud)
852{913{
914 auto entry = pud_val(pud);
915
853 return __vm_normal_page(vma, addr, pud_pfn(pud), pud_special(pud),916 return __vm_normal_page(vma, addr, pud_pfn(pud), pud_special(pud),
854 pud_val(pud), PGTABLE_LEVEL_PUD);917 &entry, sizeof(entry), PGTABLE_LEVEL_PUD);
855}918}
856#endif919#endif
857 920
@@ -946,7 +1009,6 @@ copy_nonpresent_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, · 88 unmodified lines
946 pte_t *dst_pte, pte_t *src_pte, struct vm_area_struct *dst_vma,1009 pte_t *dst_pte, pte_t *src_pte, struct vm_area_struct *dst_vma,
947 struct vm_area_struct *src_vma, unsigned long addr, int *rss)1010 struct vm_area_struct *src_vma, unsigned long addr, int *rss)
948{1011{
949 vm_flags_t vm_flags = dst_vma->vm_flags;
950 pte_t orig_pte = ptep_get(src_pte);1012 pte_t orig_pte = ptep_get(src_pte);
951 softleaf_t entry = softleaf_from_pte(orig_pte);1013 softleaf_t entry = softleaf_from_pte(orig_pte);
952 pte_t pte = orig_pte;1014 pte_t pte = orig_pte;
@@ -970,7 +1032,7 @@ copy_nonpresent_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, · 17 unmodified lines
970 rss[mm_counter(folio)]++;1032 rss[mm_counter(folio)]++;
971 1033
972 if (!softleaf_is_migration_read(entry) &&1034 if (!softleaf_is_migration_read(entry) &&
973 is_cow_mapping(vm_flags)) {1035 vma_is_cow_mapping(dst_vma)) {
974 /*1036 /*
975 * COW mappings require pages in both parent and child1037 * COW mappings require pages in both parent and child
976 * to be set to read. A previously exclusive entry is1038 * to be set to read. A previously exclusive entry is
@@ -1011,7 +1073,7 @@ copy_nonpresent_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, · 34 unmodified lines
1011 * save and restore device driver state).1073 * save and restore device driver state).
1012 */1074 */
1013 if (softleaf_is_device_private_write(entry) &&1075 if (softleaf_is_device_private_write(entry) &&
1014 is_cow_mapping(vm_flags)) {1076 vma_is_cow_mapping(dst_vma)) {
1015 entry = make_readable_device_private_entry(1077 entry = make_readable_device_private_entry(
1016 swp_offset(entry));1078 swp_offset(entry));
1017 pte = swp_entry_to_pte(entry);1079 pte = swp_entry_to_pte(entry);
@@ -1026,7 +1088,7 @@ copy_nonpresent_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, · 8 unmodified lines
1026 * exclusive entries currently only support private writable1088 * exclusive entries currently only support private writable
1027 * (ie. COW) mappings.1089 * (ie. COW) mappings.
1028 */1090 */
1029 VM_BUG_ON(!is_cow_mapping(src_vma->vm_flags));1091 VM_BUG_ON(!vma_is_cow_mapping(src_vma));
1030 if (try_restore_exclusive_pte(src_vma, addr, src_pte, orig_pte))1092 if (try_restore_exclusive_pte(src_vma, addr, src_pte, orig_pte))
1031 return -EBUSY;1093 return -EBUSY;
1032 return -ENOENT;1094 return -ENOENT;
@@ -1125,7 +1187,7 @@ static __always_inline void __copy_present_ptes(struct vm_area_struct *dst_vma, · 92 unmodified lines
1125 }1187 }
1126 1188
1127 /* If it's a COW mapping, write protect it both processes. */1189 /* If it's a COW mapping, write protect it both processes. */
1128 if (is_cow_mapping(src_vma->vm_flags) && writable) {1190 if (vma_is_cow_mapping(src_vma) && writable) {
1129 wrprotect_ptes(src_mm, addr, src_pte, nr);1191 wrprotect_ptes(src_mm, addr, src_pte, nr);
1130 pte = pte_wrprotect(pte);1192 pte = pte_wrprotect(pte);
1131 }1193 }
@@ -1546,9 +1608,9 @@ copy_page_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma) · 414 unmodified lines
1546 * We need to invalidate the secondary MMU mappings only when1608 * We need to invalidate the secondary MMU mappings only when
1547 * there could be a permission downgrade on the ptes of the1609 * there could be a permission downgrade on the ptes of the
1548 * parent mm. And a permission downgrade will only happen if1610 * parent mm. And a permission downgrade will only happen if
1549 * is_cow_mapping() returns true.1611 * vma_is_cow_mapping() returns true.
1550 */1612 */
1551 is_cow = is_cow_mapping(src_vma->vm_flags);1613 is_cow = vma_is_cow_mapping(src_vma);
1552 1614
1553 if (is_cow) {1615 if (is_cow) {
1554 mmu_notifier_range_init(&range, MMU_NOTIFY_PROTECTION_PAGE,1616 mmu_notifier_range_init(&range, MMU_NOTIFY_PROTECTION_PAGE,
@@ -2381,7 +2443,7 @@ static bool vm_mixed_zeropage_allowed(struct vm_area_struct *vma) · 826 unmodified lines
2381 if (mm_forbids_zeropage(vma->vm_mm))2443 if (mm_forbids_zeropage(vma->vm_mm))
2382 return false;2444 return false;
2383 /* zeropages in COW mappings are common and unproblematic. */2445 /* zeropages in COW mappings are common and unproblematic. */
2384 if (is_cow_mapping(vma->vm_flags))2446 if (vma_is_cow_mapping(vma))
2385 return true;2447 return true;
2386 /* Mappings that do not allow for writable PTEs are unproblematic. */2448 /* Mappings that do not allow for writable PTEs are unproblematic. */
2387 if (!(vma->vm_flags & (VM_WRITE | VM_MAYWRITE)))2449 if (!(vma->vm_flags & (VM_WRITE | VM_MAYWRITE)))
@@ -2832,7 +2894,7 @@ vm_fault_t vmf_insert_pfn_prot(struct vm_area_struct *vma, unsigned long addr, · 444 unmodified lines
2832 BUG_ON(!(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)));2894 BUG_ON(!(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)));
2833 BUG_ON((vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) ==2895 BUG_ON((vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP)) ==
2834 (VM_PFNMAP|VM_MIXEDMAP));2896 (VM_PFNMAP|VM_MIXEDMAP));
2835 BUG_ON((vma->vm_flags & VM_PFNMAP) && is_cow_mapping(vma->vm_flags));2897 BUG_ON((vma->vm_flags & VM_PFNMAP) && vma_is_cow_mapping(vma));
2836 BUG_ON((vma->vm_flags & VM_MIXEDMAP) && pfn_valid(pfn));2898 BUG_ON((vma->vm_flags & VM_MIXEDMAP) && pfn_valid(pfn));
2837 2899
2838 if (addr < vma->vm_start || addr >= vma->vm_end)2900 if (addr < vma->vm_start || addr >= vma->vm_end)
@@ -3244,7 +3306,7 @@ static int remap_pfn_range_prepare_vma(struct vm_area_struct *vma, · 405 unmodified lines
3244 unsigned long size)3306 unsigned long size)
3245{3307{
3246 const unsigned long end = addr + PAGE_ALIGN(size);3308 const unsigned long end = addr + PAGE_ALIGN(size);
3247 const bool is_cow = is_cow_mapping(vma->vm_flags);3309 const bool is_cow = vma_is_cow_mapping(vma);
3248 int err;3310 int err;
3249 3311
3250 err = get_remap_pgoff(is_cow, addr, end, vma->vm_start, vma->vm_end,3312 err = get_remap_pgoff(is_cow, addr, end, vma->vm_start, vma->vm_end,
@@ -6744,7 +6806,7 @@ static vm_fault_t sanitize_fault_flags(struct vm_area_struct *vma, · 3493 unmodified lines
6744 * FAULT_FLAG_UNSHARE only applies to COW mappings. Let's6806 * FAULT_FLAG_UNSHARE only applies to COW mappings. Let's
6745 * just treat it like an ordinary read-fault otherwise.6807 * just treat it like an ordinary read-fault otherwise.
6746 */6808 */
6747 if (!is_cow_mapping(vma->vm_flags))6809 if (!vma_is_cow_mapping(vma))
6748 *flags &= ~FAULT_FLAG_UNSHARE;6810 *flags &= ~FAULT_FLAG_UNSHARE;
6749 } else if (*flags & FAULT_FLAG_WRITE) {6811 } else if (*flags & FAULT_FLAG_WRITE) {
6750 /* Write faults on read-only mappings are impossible ... */6812 /* Write faults on read-only mappings are impossible ... */
@@ -6752,7 +6814,7 @@ static vm_fault_t sanitize_fault_flags(struct vm_area_struct *vma, · 1 unmodified line
6752 return VM_FAULT_SIGSEGV;6814 return VM_FAULT_SIGSEGV;
6753 /* ... and FOLL_FORCE only applies to COW mappings. */6815 /* ... and FOLL_FORCE only applies to COW mappings. */
6754 if (WARN_ON_ONCE(!(vma->vm_flags & VM_WRITE) &&6816 if (WARN_ON_ONCE(!(vma->vm_flags & VM_WRITE) &&
6755 !is_cow_mapping(vma->vm_flags)))6817 !vma_is_cow_mapping(vma)))
6756 return VM_FAULT_SIGSEGV;6818 return VM_FAULT_SIGSEGV;
6757 }6819 }
6758#ifdef CONFIG_PER_VMA_LOCK6820#ifdef CONFIG_PER_VMA_LOCK
mm/mempolicy.c+7−16
@@ -844,7 +844,7 @@ bool folio_can_map_prot_numa(struct folio *folio, struct vm_area_struct *vma, · 843 unmodified lines
844 return false;844 return false;
845 845
846 /* Also skip shared copy-on-write folios */846 /* Also skip shared copy-on-write folios */
847 if (is_cow_mapping(vma->vm_flags) && folio_maybe_mapped_shared(folio))847 if (vma_is_cow_mapping(vma) && folio_maybe_mapped_shared(folio))
848 return false;848 return false;
849 849
850 /* Folios are pinned and can't be migrated */850 /* Folios are pinned and can't be migrated */
@@ -2060,24 +2060,15 @@ struct mempolicy *get_vma_policy(struct vm_area_struct *vma, · 1209 unmodified lines
2060bool vma_policy_mof(struct vm_area_struct *vma)2060bool vma_policy_mof(struct vm_area_struct *vma)
2061{2061{
2062 struct mempolicy *pol;2062 struct mempolicy *pol;
2063 pgoff_t ilx;
2064 bool mof;
2063 2065
2064 if (vma->vm_ops && vma->vm_ops->get_policy) {2066 pol = __get_vma_policy(vma, vma->vm_start, &ilx);
2065 bool ret = false;
2066 pgoff_t ilx; /* ignored here */
2067
2068 pol = vma->vm_ops->get_policy(vma, vma->vm_start, &ilx);
2069 if (pol && (pol->flags & MPOL_F_MOF))
2070 ret = true;
2071 mpol_cond_put(pol);
2072
2073 return ret;
2074 }
2075
2076 pol = vma->vm_policy;
2077 if (!pol)2067 if (!pol)
2078 pol = get_task_policy(current);2068 pol = get_task_policy(current);
2079 2069 mof = pol->flags & MPOL_F_MOF;
2080 return pol->flags & MPOL_F_MOF;2070 mpol_cond_put(pol);
2071 return mof;
2081}2072}
2082 2073
2083bool apply_policy_zone(struct mempolicy *policy, enum zone_type zone)2074bool apply_policy_zone(struct mempolicy *policy, enum zone_type zone)
mm/migrate.c+10−11
@@ -356,23 +356,18 @@ static bool remove_migration_pte(struct folio *folio, · 355 unmodified lines
356 356
357 while (page_vma_mapped_walk(&pvmw)) {357 while (page_vma_mapped_walk(&pvmw)) {
358 rmap_t rmap_flags = RMAP_NONE;358 rmap_t rmap_flags = RMAP_NONE;
359 pte_t old_pte;359 unsigned long idx = 0;
360 pte_t pte;
361 softleaf_t entry;360 softleaf_t entry;
362 struct page *new;361 struct page *new;
363 unsigned long idx = 0;362 pte_t old_pte;
364 363 pte_t pte;
365 /* pgoff is invalid for ksm pages, but they are never large */
366 if (folio_test_large(folio) && !folio_test_hugetlb(folio))
367 idx = linear_page_index(vma, pvmw.address) - pvmw.pgoff;
368 new = folio_page(folio, idx);
369 364
370#ifdef CONFIG_ARCH_HAS_PMD_SOFTLEAVES365#ifdef CONFIG_ARCH_HAS_PMD_SOFTLEAVES
371 /* PMD-mapped THP migration entry */366 /* PMD-mapped THP migration entry */
372 if (!pvmw.pte) {367 if (!pvmw.pte) {
373 VM_BUG_ON_FOLIO(folio_test_hugetlb(folio) ||368 VM_BUG_ON_FOLIO(folio_test_hugetlb(folio) ||
374 !folio_test_pmd_mappable(folio), folio);369 !folio_test_pmd_mappable(folio), folio);
375 remove_migration_pmd(&pvmw, new);370 remove_migration_pmd(&pvmw, folio);
376 continue;371 continue;
377 }372 }
378#endif373#endif
@@ -381,14 +376,18 @@ static bool remove_migration_pte(struct folio *folio, · 2 unmodified lines
381 pvmw.pte);376 pvmw.pte);
382 else377 else
383 old_pte = ptep_get(pvmw.pte);378 old_pte = ptep_get(pvmw.pte);
379
380 entry = softleaf_from_pte(old_pte);
381 if (folio_test_large(folio) && !folio_test_hugetlb(folio))
382 idx = softleaf_to_pfn(entry) - pvmw.pfn;
383
384 if (rmap_walk_arg->map_unused_to_zeropage &&384 if (rmap_walk_arg->map_unused_to_zeropage &&
385 try_to_map_unused_to_zeropage(&pvmw, folio, old_pte, idx))385 try_to_map_unused_to_zeropage(&pvmw, folio, old_pte, idx))
386 continue;386 continue;
387 387
388 folio_get(folio);388 folio_get(folio);
389 new = folio_page(folio, idx);
389 pte = mk_pte(new, READ_ONCE(vma->vm_page_prot));390 pte = mk_pte(new, READ_ONCE(vma->vm_page_prot));
390
391 entry = softleaf_from_pte(old_pte);
392 if (!softleaf_is_migration_young(entry))391 if (!softleaf_is_migration_young(entry))
393 pte = pte_mkold(pte);392 pte = pte_mkold(pte);
394 if (folio_test_dirty(folio) && softleaf_is_migration_dirty(entry))393 if (folio_test_dirty(folio) && softleaf_is_migration_dirty(entry))
mm/migrate_device.c+14−1
@@ -882,7 +882,7 @@ static int migrate_vma_insert_huge_pmd_page(struct migrate_vma *migrate, · 881 unmodified lines
882 882
883 if (flush) {883 if (flush) {
884 pte_free(vma->vm_mm, pgtable);884 pte_free(vma->vm_mm, pgtable);
885 flush_cache_page(vma, addr, addr + HPAGE_PMD_SIZE);885 flush_cache_range(vma, addr, addr + HPAGE_PMD_SIZE);
886 pmdp_invalidate(vma, addr, pmdp);886 pmdp_invalidate(vma, addr, pmdp);
887 } else {887 } else {
888 pgtable_trans_huge_deposit(vma->vm_mm, pmdp, pgtable);888 pgtable_trans_huge_deposit(vma->vm_mm, pmdp, pgtable);
@@ -1193,6 +1193,13 @@ static void __migrate_device_pages(unsigned long *src_pfns, · 304 unmodified lines
1193 MIGRATE_PFN_COMPOUND);1193 MIGRATE_PFN_COMPOUND);
1194 goto next;1194 goto next;
1195 }1195 }
1196
1197 /*
1198 * reset nr so that only first after-split folio
1199 * is processed below
1200 */
1201 VM_WARN_ON_ONCE(folio_test_large(folio));
1202 nr = 1;
1196 } else if ((src_pfns[i] & MIGRATE_PFN_MIGRATE) &&1203 } else if ((src_pfns[i] & MIGRATE_PFN_MIGRATE) &&
1197 (dst_pfns[i] & MIGRATE_PFN_COMPOUND) &&1204 (dst_pfns[i] & MIGRATE_PFN_COMPOUND) &&
1198 !(src_pfns[i] & MIGRATE_PFN_COMPOUND)) {1205 !(src_pfns[i] & MIGRATE_PFN_COMPOUND)) {
@@ -1232,6 +1239,12 @@ static void __migrate_device_pages(unsigned long *src_pfns, · 33 unmodified lines
1232 folio = page_folio(migrate_pfn_to_page(src_pfns[i+j]));1239 folio = page_folio(migrate_pfn_to_page(src_pfns[i+j]));
1233 newfolio = page_folio(migrate_pfn_to_page(dst_pfns[i+j]));1240 newfolio = page_folio(migrate_pfn_to_page(dst_pfns[i+j]));
1234 1241
1242 /*
1243 * folio_free_swap() removed the folio from the swap
1244 * cache. Refresh the saved mapping before migration.
1245 */
1246 mapping = folio_mapping(folio);
1247
1235 r = folio_migrate_mapping(mapping, newfolio, folio, extra_cnt);1248 r = folio_migrate_mapping(mapping, newfolio, folio, extra_cnt);
1236 if (r)1249 if (r)
1237 src_pfns[i+j] &= ~MIGRATE_PFN_MIGRATE;1250 src_pfns[i+j] &= ~MIGRATE_PFN_MIGRATE;
mm/mm_init.c+0−1
@@ -1339,7 +1339,6 @@ static void __meminit pgdat_init_internals(struct pglist_data *pgdat) · 1338 unmodified lines
1339 for (i = 0; i < NR_VMSCAN_THROTTLE; i++)1339 for (i = 0; i < NR_VMSCAN_THROTTLE; i++)
1340 init_waitqueue_head(&pgdat->reclaim_wait[i]);1340 init_waitqueue_head(&pgdat->reclaim_wait[i]);
1341 1341
1342 pgdat_page_ext_init(pgdat);
1343 lruvec_init(&pgdat->__lruvec);1342 lruvec_init(&pgdat->__lruvec);
1344}1343}
1345 1344
mm/mmzone.c+1−0
@@ -79,6 +79,7 @@ void lruvec_init(struct lruvec *lruvec) · 78 unmodified lines
79 79
80 memset(lruvec, 0, sizeof(struct lruvec));80 memset(lruvec, 0, sizeof(struct lruvec));
81 spin_lock_init(&lruvec->lru_lock);81 spin_lock_init(&lruvec->lru_lock);
82 spin_lock_init(&lruvec->cost_lock);
82 zswap_lruvec_state_init(lruvec);83 zswap_lruvec_state_init(lruvec);
83 84
84 for_each_lru(lru)85 for_each_lru(lru)
mm/mremap.c+5−3
@@ -264,7 +264,7 @@ static int move_ptes(struct pagetable_move_control *pmc, · 263 unmodified lines
264 264
265 for (; old_addr < old_end; old_ptep += nr_ptes, old_addr += nr_ptes * PAGE_SIZE,265 for (; old_addr < old_end; old_ptep += nr_ptes, old_addr += nr_ptes * PAGE_SIZE,
266 new_ptep += nr_ptes, new_addr += nr_ptes * PAGE_SIZE) {266 new_ptep += nr_ptes, new_addr += nr_ptes * PAGE_SIZE) {
267 VM_WARN_ON_ONCE(!pte_none(*new_ptep));267 VM_WARN_ON_ONCE(!pte_none(ptep_get(new_ptep)));
268 268
269 nr_ptes = 1;269 nr_ptes = 1;
270 max_nr_ptes = (old_end - old_addr) >> PAGE_SHIFT;270 max_nr_ptes = (old_end - old_addr) >> PAGE_SHIFT;
@@ -1265,7 +1265,9 @@ static void unmap_source_vma(struct vma_remap_struct *vrm) · 994 unmodified lines
1265static int copy_vma_and_data(struct vma_remap_struct *vrm,1265static int copy_vma_and_data(struct vma_remap_struct *vrm,
1266 struct vm_area_struct **new_vma_ptr)1266 struct vm_area_struct **new_vma_ptr)
1267{1267{
1268 const unsigned long new_pgoff = linear_page_index(vrm->vma, vrm->addr);1268 const pgoff_t new_pgoff = linear_page_index(vrm->vma, vrm->addr);
1269 const pgoff_t new_anon_pgoff =
1270 __linear_anon_page_index(vrm->vma, vrm->addr);
1269 struct vm_area_struct *vma = vrm->vma;1271 struct vm_area_struct *vma = vrm->vma;
1270 struct vm_area_struct *new_vma;1272 struct vm_area_struct *new_vma;
1271 unsigned long moved_len;1273 unsigned long moved_len;
@@ -1273,7 +1275,7 @@ static int copy_vma_and_data(struct vma_remap_struct *vrm, · 1 unmodified line
1273 PAGETABLE_MOVE(pmc, NULL, NULL, vrm->addr, vrm->new_addr, vrm->old_len);1275 PAGETABLE_MOVE(pmc, NULL, NULL, vrm->addr, vrm->new_addr, vrm->old_len);
1274 1276
1275 new_vma = copy_vma(&vma, vrm->new_addr, vrm->new_len, new_pgoff,1277 new_vma = copy_vma(&vma, vrm->new_addr, vrm->new_len, new_pgoff,
1276 &pmc.need_rmap_locks);1278 new_anon_pgoff, &pmc.need_rmap_locks);
1277 if (!new_vma) {1279 if (!new_vma) {
1278 vrm_uncharge(vrm);1280 vrm_uncharge(vrm);
1279 *new_vma_ptr = NULL;1281 *new_vma_ptr = NULL;
mm/nommu.c+4−0
@@ -1393,6 +1393,10 @@ static int split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma, · 1392 unmodified lines
1393 setup_vma_to_mm(vma, mm);1393 setup_vma_to_mm(vma, mm);
1394 setup_vma_to_mm(new, mm);1394 setup_vma_to_mm(new, mm);
1395 vma_iter_store_new(vmi, new);1395 vma_iter_store_new(vmi, new);
1396
1397 /* vmi should point lower address */
1398 if (new_below)
1399 vma_next(vmi);
1396 mm->map_count++;1400 mm->map_count++;
1397 return 0;1401 return 0;
1398 1402
mm/page-writeback.c+5−0
@@ -2762,6 +2762,11 @@ EXPORT_SYMBOL(folio_redirty_for_writepage); · 2761 unmodified lines
2762 * in this folio. Truncation will block on the page table lock as it2762 * in this folio. Truncation will block on the page table lock as it
2763 * unmaps pages before removing the folio from its mapping.2763 * unmaps pages before removing the folio from its mapping.
2764 *2764 *
2765 * .. DANGER::
2766 * Do not use this on a folio obtained from a function like
2767 * get_user_pages_fast() without holding appropriate locks; you might want to
2768 * use set_page_dirty_lock() or folio_mark_dirty_lock() instead.
2769 *
2765 * Return: True if the folio was newly dirtied, false if it was already dirty.2770 * Return: True if the folio was newly dirtied, false if it was already dirty.
2766 */2771 */
2767bool folio_mark_dirty(struct folio *folio)2772bool folio_mark_dirty(struct folio *folio)
mm/page_alloc.c+20−8
@@ -6853,8 +6853,8 @@ static int sysctl_min_slab_ratio_sysctl_handler(const struct ctl_table *table, i · 6852 unmodified lines
6853 6853
6854/*6854/*
6855 * lowmem_reserve_ratio_sysctl_handler - just a wrapper around6855 * lowmem_reserve_ratio_sysctl_handler - just a wrapper around
6856 * proc_dointvec() so that we can call setup_per_zone_lowmem_reserve()6856 * proc_dointvec_minmax() so that we can call
6857 * whenever sysctl_lowmem_reserve_ratio changes.6857 * setup_per_zone_lowmem_reserve() when the sysctl is written.
6858 *6858 *
6859 * The reserve ratio obviously has absolutely no relation with the6859 * The reserve ratio obviously has absolutely no relation with the
6860 * minimum watermarks. The lowmem reserve ratio can only make sense6860 * minimum watermarks. The lowmem reserve ratio can only make sense
@@ -6863,16 +6863,27 @@ static int sysctl_min_slab_ratio_sysctl_handler(const struct ctl_table *table, i · 2 unmodified lines
6863static int lowmem_reserve_ratio_sysctl_handler(const struct ctl_table *table,6863static int lowmem_reserve_ratio_sysctl_handler(const struct ctl_table *table,
6864 int write, void *buffer, size_t *length, loff_t *ppos)6864 int write, void *buffer, size_t *length, loff_t *ppos)
6865{6865{
6866 int i;6866 struct ctl_table tmp = *table;
6867 int ratio[ARRAY_SIZE(sysctl_lowmem_reserve_ratio)];
6868 int rc;
6867 6869
6868 proc_dointvec_minmax(table, write, buffer, length, ppos);6870 if (!write)
6871 return proc_dointvec_minmax(table, write, buffer, length, ppos);
6869 6872
6870 for (i = 0; i < MAX_NR_ZONES; i++) {6873 /*
6871 if (sysctl_lowmem_reserve_ratio[i] < 1)6874 * proc_dointvec_max() works incrementally. Use a buffer and only set
6872 sysctl_lowmem_reserve_ratio[i] = 0;6875 * the values if all of them parse cleanly.
6873 }6876 */
6877 memcpy(ratio, sysctl_lowmem_reserve_ratio, sizeof(ratio));
6878 tmp.data = ratio;
6879
6880 rc = proc_dointvec_minmax(&tmp, write, buffer, length, ppos);
6881 if (rc)
6882 return rc;
6874 6883
6884 memcpy(sysctl_lowmem_reserve_ratio, ratio, sizeof(ratio));
6875 setup_per_zone_lowmem_reserve();6885 setup_per_zone_lowmem_reserve();
6886
6876 return 0;6887 return 0;
6877}6888}
6878 6889
@@ -6971,6 +6982,7 @@ static const struct ctl_table page_alloc_sysctl_table[] = { · 92 unmodified lines
6971 .maxlen = sizeof(sysctl_lowmem_reserve_ratio),6982 .maxlen = sizeof(sysctl_lowmem_reserve_ratio),
6972 .mode = 0644,6983 .mode = 0644,
6973 .proc_handler = lowmem_reserve_ratio_sysctl_handler,6984 .proc_handler = lowmem_reserve_ratio_sysctl_handler,
6985 .extra1 = SYSCTL_ZERO,
6974 },6986 },
6975#ifdef CONFIG_NUMA6987#ifdef CONFIG_NUMA
6976 {6988 {
mm/page_ext.c+0−9
@@ -164,11 +164,6 @@ void __init page_ext_init_flatmem_late(void) · 163 unmodified lines
164 invoke_init_callbacks();164 invoke_init_callbacks();
165}165}
166 166
167void __meminit pgdat_page_ext_init(struct pglist_data *pgdat)
168{
169 pgdat->node_page_ext = NULL;
170}
171
172static struct page_ext *lookup_page_ext(const struct page *page)167static struct page_ext *lookup_page_ext(const struct page *page)
173{168{
174 unsigned long pfn = page_to_pfn(page);169 unsigned long pfn = page_to_pfn(page);
@@ -494,10 +489,6 @@ oom: · 319 unmodified lines
494 panic("Out of memory");489 panic("Out of memory");
495}490}
496 491
497void __meminit pgdat_page_ext_init(struct pglist_data *pgdat)
498{
499}
500
501#endif492#endif
502 493
503/**494/**
mm/page_io.c+281−300
@@ -25,57 +25,10 @@ · 24 unmodified lines
25#include <linux/sched/task.h>25#include <linux/sched/task.h>
26#include <linux/delayacct.h>26#include <linux/delayacct.h>
27#include <linux/zswap.h>27#include <linux/zswap.h>
28#include <linux/swap_ops.h>
28#include "swap.h"29#include "swap.h"
29#include "swap_table.h"30#include "swap_table.h"
30 31
31static void __end_swap_bio_write(struct bio *bio)
32{
33 struct folio *folio = bio_first_folio_all(bio);
34
35 if (bio->bi_status) {
36 /*
37 * We failed to write the page out to swap-space.
38 * Re-dirty the page in order to avoid it being reclaimed.
39 * Also print a dire warning that things will go BAD (tm)
40 * very quickly.
41 *
42 * Also clear PG_reclaim to avoid folio_rotate_reclaimable()
43 */
44 folio_mark_dirty(folio);
45 pr_alert_ratelimited("Write-error on swap-device (%u:%u:%llu)\n",
46 MAJOR(bio_dev(bio)), MINOR(bio_dev(bio)),
47 (unsigned long long)bio->bi_iter.bi_sector);
48 folio_clear_reclaim(folio);
49 }
50 folio_end_writeback(folio);
51}
52
53static void end_swap_bio_write(struct bio *bio)
54{
55 __end_swap_bio_write(bio);
56 bio_put(bio);
57}
58
59static void __end_swap_bio_read(struct bio *bio)
60{
61 struct folio *folio = bio_first_folio_all(bio);
62
63 if (bio->bi_status) {
64 pr_alert_ratelimited("Read-error on swap-device (%u:%u:%llu)\n",
65 MAJOR(bio_dev(bio)), MINOR(bio_dev(bio)),
66 (unsigned long long)bio->bi_iter.bi_sector);
67 } else {
68 folio_mark_uptodate(folio);
69 }
70 folio_unlock(folio);
71}
72
73static void end_swap_bio_read(struct bio *bio)
74{
75 __end_swap_bio_read(bio);
76 bio_put(bio);
77}
78
79int generic_swapfile_activate(struct swap_info_struct *sis,32int generic_swapfile_activate(struct swap_info_struct *sis,
80 struct file *swap_file,33 struct file *swap_file,
81 sector_t *span)34 sector_t *span)
@@ -248,7 +201,7 @@ static void swap_zeromap_folio_clear(struct folio *folio) · 166 unmodified lines
248 * We may have stale swap cache pages in memory: notice201 * We may have stale swap cache pages in memory: notice
249 * them here and get rid of the unnecessary final write.202 * them here and get rid of the unnecessary final write.
250 */203 */
251int swap_writeout(struct folio *folio, struct swap_iocb **swap_plug)204int swap_writeout(struct swap_io_ctx *ctx, struct folio *folio)
252{205{
253 int ret = 0;206 int ret = 0;
254 207
@@ -295,39 +248,44 @@ int swap_writeout(struct folio *folio, struct swap_iocb **swap_plug) · 40 unmodified lines
295 }248 }
296 rcu_read_unlock();249 rcu_read_unlock();
297 250
298 __swap_writepage(folio, swap_plug);251 __swap_writepage(ctx, folio);
299 return 0;252 return 0;
300out_unlock:253out_unlock:
301 folio_unlock(folio);254 folio_unlock(folio);
302 return ret;255 return ret;
303}256}
304 257
305static inline void count_swpout_vm_event(struct folio *folio)258#if defined(CONFIG_MEMCG) && defined(CONFIG_BLK_CGROUP)
259static struct cgroup_subsys_state *folio_memcg_blkg_css(struct folio *folio)
306{260{
307#ifdef CONFIG_TRANSPARENT_HUGEPAGE261 return cgroup_e_css(folio_memcg(folio)->css.cgroup, &io_cgrp_subsys);
308 if (unlikely(folio_test_pmd_mappable(folio))) {262}
309 count_memcg_folio_events(folio, THP_SWPOUT, 1);263
310 count_vm_event(THP_SWPOUT);264static bool folio_blkg_can_merge(struct folio *folio, struct folio *prev_folio)
265{
266 bool can_merge = true;
267
268 if (folio_memcg_charged(folio) != folio_memcg_charged(prev_folio))
269 return false;
270 if (folio_memcg_charged(folio)) {
271 rcu_read_lock();
272 if (folio_memcg_blkg_css(folio) !=
273 folio_memcg_blkg_css(prev_folio))
274 can_merge = false;
275 rcu_read_unlock();
311 }276 }
312#endif277 return can_merge;
313 count_mthp_stat(folio_order(folio), MTHP_STAT_SWPOUT);
314 count_memcg_folio_events(folio, PSWPOUT, folio_nr_pages(folio));
315 count_vm_events(PSWPOUT, folio_nr_pages(folio));
316}278}
317 279
318#if defined(CONFIG_MEMCG) && defined(CONFIG_BLK_CGROUP)
319static void bio_associate_blkg_from_page(struct bio *bio, struct folio *folio)280static void bio_associate_blkg_from_page(struct bio *bio, struct folio *folio)
320{281{
321 struct cgroup_subsys_state *css;282 struct cgroup_subsys_state *css;
322 struct mem_cgroup *memcg;
323 283
324 if (!folio_memcg_charged(folio))284 if (!folio_memcg_charged(folio))
325 return;285 return;
326
327 rcu_read_lock();286 rcu_read_lock();
328 memcg = folio_memcg(folio);287 css = folio_memcg_blkg_css(folio);
329 css = cgroup_e_css(memcg->css.cgroup, &io_cgrp_subsys);288 if (css && !css_tryget(css))
330 if (!css || !css_tryget(css))
331 css = NULL;289 css = NULL;
332 rcu_read_unlock();290 rcu_read_unlock();
333 291
@@ -336,15 +294,13 @@ static void bio_associate_blkg_from_page(struct bio *bio, struct folio *folio) · 2 unmodified lines
336 css_put(css);294 css_put(css);
337}295}
338#else296#else
297static bool folio_blkg_can_merge(struct folio *folio, struct folio *prev_folio)
298{
299 return true;
300}
339#define bio_associate_blkg_from_page(bio, folio) do { } while (0)301#define bio_associate_blkg_from_page(bio, folio) do { } while (0)
340#endif /* CONFIG_MEMCG && CONFIG_BLK_CGROUP */302#endif /* CONFIG_MEMCG && CONFIG_BLK_CGROUP */
341 303
342struct swap_iocb {
343 struct kiocb iocb;
344 struct bio_vec bvecs[SWAP_CLUSTER_MAX];
345 int nr_bvecs;
346 int len;
347};
348static mempool_t *sio_pool;304static mempool_t *sio_pool;
349 305
350int sio_pool_init(void)306int sio_pool_init(void)
@@ -360,168 +316,74 @@ int sio_pool_init(void) · 9 unmodified lines
360 return 0;316 return 0;
361}317}
362 318
363static void sio_write_complete(struct kiocb *iocb, long ret)319static bool swap_can_merge(struct swap_io_ctx *ctx, struct folio *folio,
320 int rw)
364{321{
365 struct swap_iocb *sio = container_of(iocb, struct swap_iocb, iocb);322 struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);
366 struct page *page = sio->bvecs[0].bv_page;323 struct bio_vec *last_bv = &ctx->sio->bvecs[ctx->sio->nr_bvecs - 1];
367 int p;324 struct folio *prev_folio = bvec_folio(last_bv);
368 325 size_t prev_folio_size = folio_size(prev_folio);
369 if (ret != sio->len) {
370 /*
371 * In the case of swap-over-nfs, this can be a
372 * temporary failure if the system has limited
373 * memory for allocating transmit buffers.
374 * Mark the page dirty and avoid
375 * folio_rotate_reclaimable but rate-limit the
376 * messages.
377 */
378 pr_err_ratelimited("Write error %ld on dio swapfile (%llu)\n",
379 ret, swap_dev_pos(page_swap_entry(page)));
380 for (p = 0; p < sio->nr_bvecs; p++) {
381 page = sio->bvecs[p].bv_page;
382 set_page_dirty(page);
383 ClearPageReclaim(page);
384 }
385 }
386
387 for (p = 0; p < sio->nr_bvecs; p++)
388 end_page_writeback(sio->bvecs[p].bv_page);
389 326
390 mempool_free(sio, sio_pool);327 if (ctx->sis != sis)
328 return false;
329 return sis->ops->can_merge(folio, prev_folio, prev_folio_size, rw);
391}330}
392 331
393static void swap_writepage_fs(struct folio *folio, struct swap_iocb **swap_plug)332static void swap_add_folio(struct swap_io_ctx *ctx, struct folio *folio, int rw)
394{333{
395 struct swap_iocb *sio = swap_plug ? *swap_plug : NULL;
396 struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);334 struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);
397 struct file *swap_file = sis->swap_file;335 struct swap_iocb *sio = ctx->sio;
398 loff_t pos = swap_dev_pos(folio->swap);336
399 337 if (sio && !swap_can_merge(ctx, folio, rw)) {
400 count_swpout_vm_event(folio);338 if (rw == WRITE)
401 folio_start_writeback(folio);339 swap_write_submit(ctx);
402 folio_unlock(folio);340 else
403 if (sio) {341 swap_read_submit(ctx);
404 if (sio->iocb.ki_filp != swap_file ||342 sio = ctx->sio;
405 sio->iocb.ki_pos + sio->len != pos) {
406 swap_write_unplug(sio);
407 sio = NULL;
408 }
409 }343 }
344
410 if (!sio) {345 if (!sio) {
411 sio = mempool_alloc(sio_pool, GFP_NOIO);346 ctx->sis = sis;
412 init_sync_kiocb(&sio->iocb, swap_file);347 ctx->sio = sio = mempool_alloc(sio_pool, GFP_NOIO);
413 sio->iocb.ki_complete = sio_write_complete;
414 sio->iocb.ki_pos = pos;
415 sio->nr_bvecs = 0;348 sio->nr_bvecs = 0;
416 sio->len = 0;349 sio->len = 0;
417 }350 }
418 bvec_set_folio(&sio->bvecs[sio->nr_bvecs], folio, folio_size(folio), 0);351 bvec_set_folio(&sio->bvecs[sio->nr_bvecs], folio, folio_size(folio), 0);
419 sio->len += folio_size(folio);352 sio->len += folio_size(folio);
420 sio->nr_bvecs += 1;
421 if (sio->nr_bvecs == ARRAY_SIZE(sio->bvecs) || !swap_plug) {
422 swap_write_unplug(sio);
423 sio = NULL;
424 }
425 if (swap_plug)
426 *swap_plug = sio;
427}
428
429static void swap_writepage_bdev_sync(struct folio *folio,
430 struct swap_info_struct *sis)
431{
432 struct bio_vec bv;
433 struct bio bio;
434
435 bio_init(&bio, sis->bdev, &bv, 1, REQ_OP_WRITE | REQ_SWAP);
436 bio.bi_iter.bi_sector = swap_folio_sector(folio);
437 bio_add_folio_nofail(&bio, folio, folio_size(folio), 0);
438
439 bio_associate_blkg_from_page(&bio, folio);
440 count_swpout_vm_event(folio);
441
442 folio_start_writeback(folio);
443 folio_unlock(folio);
444 353
445 submit_bio_wait(&bio);
446 __end_swap_bio_write(&bio);
447}
448
449static void swap_writepage_bdev_async(struct folio *folio,
450 struct swap_info_struct *sis)
451{
452 struct bio *bio;
453
454 bio = bio_alloc(sis->bdev, 1, REQ_OP_WRITE | REQ_SWAP, GFP_NOIO);
455 bio->bi_iter.bi_sector = swap_folio_sector(folio);
456 bio->bi_end_io = end_swap_bio_write;
457 bio_add_folio_nofail(bio, folio, folio_size(folio), 0);
458
459 bio_associate_blkg_from_page(bio, folio);
460 count_swpout_vm_event(folio);
461 folio_start_writeback(folio);
462 folio_unlock(folio);
463 submit_bio(bio);
464}
465
466void __swap_writepage(struct folio *folio, struct swap_iocb **swap_plug)
467{
468 struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);
469
470 VM_BUG_ON_FOLIO(!folio_test_swapcache(folio), folio);
471 /*
472 * ->flags can be updated non-atomically,
473 * but that will never affect SWP_FS_OPS, so the data_race
474 * is safe.
475 */
476 if (data_race(sis->flags & SWP_FS_OPS))
477 swap_writepage_fs(folio, swap_plug);
478 /*354 /*
479 * ->flags can be updated non-atomically,355 * Write out the iocb if we filled it, or if the device is synchronous.
480 * but that will never affect SWP_SYNCHRONOUS_IO, so the data_race356 *
481 * is safe.357 * The latter is to work around expectations in the classic LRU code
358 * which make synchronous clearing of the folio writeback flag in the
359 * reclaim path beneficial.
482 */360 */
483 else if (data_race(sis->flags & SWP_SYNCHRONOUS_IO))361 if (++sio->nr_bvecs == ARRAY_SIZE(sio->bvecs) ||
484 swap_writepage_bdev_sync(folio, sis);362 (rw == WRITE && (sis->flags & SWP_SYNCHRONOUS_IO))) {
485 else363 if (rw == WRITE)
486 swap_writepage_bdev_async(folio, sis);364 swap_write_submit(ctx);
487}365 else
488 366 swap_read_submit(ctx);
489void swap_write_unplug(struct swap_iocb *sio)367 }
490{
491 struct iov_iter from;
492 struct address_space *mapping = sio->iocb.ki_filp->f_mapping;
493 int ret;
494
495 iov_iter_bvec(&from, ITER_SOURCE, sio->bvecs, sio->nr_bvecs, sio->len);
496 ret = mapping->a_ops->swap_rw(&sio->iocb, &from);
497 if (ret != -EIOCBQUEUED)
498 sio_write_complete(&sio->iocb, ret);
499}368}
500 369
501static void sio_read_complete(struct kiocb *iocb, long ret)370void __swap_writepage(struct swap_io_ctx *ctx, struct folio *folio)
502{371{
503 struct swap_iocb *sio = container_of(iocb, struct swap_iocb, iocb);372 VM_BUG_ON_FOLIO(!folio_test_swapcache(folio), folio);
504 int p;
505
506 if (ret == sio->len) {
507 for (p = 0; p < sio->nr_bvecs; p++) {
508 struct folio *folio = bvec_folio(&sio->bvecs[p]);
509
510 count_mthp_stat(folio_order(folio), MTHP_STAT_SWPIN);
511 count_memcg_folio_events(folio, PSWPIN, folio_nr_pages(folio));
512 folio_mark_uptodate(folio);
513 folio_unlock(folio);
514 }
515 count_vm_events(PSWPIN, sio->len >> PAGE_SHIFT);
516 } else {
517 for (p = 0; p < sio->nr_bvecs; p++) {
518 struct folio *folio = bvec_folio(&sio->bvecs[p]);
519 373
520 folio_unlock(folio);374#ifdef CONFIG_TRANSPARENT_HUGEPAGE
521 }375 if (unlikely(folio_test_pmd_mappable(folio))) {
522 pr_alert_ratelimited("Read-error on swap-device\n");376 count_memcg_folio_events(folio, THP_SWPOUT, 1);
377 count_vm_event(THP_SWPOUT);
523 }378 }
524 mempool_free(sio, sio_pool);379#endif
380 count_mthp_stat(folio_order(folio), MTHP_STAT_SWPOUT);
381 count_memcg_folio_events(folio, PSWPOUT, folio_nr_pages(folio));
382 count_vm_events(PSWPOUT, folio_nr_pages(folio));
383
384 folio_start_writeback(folio);
385 folio_unlock(folio);
386 swap_add_folio(ctx, folio, WRITE);
525}387}
526 388
527/*389/*
@@ -587,78 +449,7 @@ static bool swap_read_folio_zeromap(struct folio *folio) · 59 unmodified lines
587 return true;449 return true;
588}450}
589 451
590static void swap_read_folio_fs(struct folio *folio, struct swap_iocb **plug)452void swap_read_folio(struct swap_io_ctx *ctx, struct folio *folio)
591{
592 struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);
593 struct swap_iocb *sio = NULL;
594 loff_t pos = swap_dev_pos(folio->swap);
595
596 if (plug)
597 sio = *plug;
598 if (sio) {
599 if (sio->iocb.ki_filp != sis->swap_file ||
600 sio->iocb.ki_pos + sio->len != pos) {
601 swap_read_unplug(sio);
602 sio = NULL;
603 }
604 }
605 if (!sio) {
606 sio = mempool_alloc(sio_pool, GFP_KERNEL);
607 init_sync_kiocb(&sio->iocb, sis->swap_file);
608 sio->iocb.ki_pos = pos;
609 sio->iocb.ki_complete = sio_read_complete;
610 sio->nr_bvecs = 0;
611 sio->len = 0;
612 }
613 bvec_set_folio(&sio->bvecs[sio->nr_bvecs], folio, folio_size(folio), 0);
614 sio->len += folio_size(folio);
615 sio->nr_bvecs += 1;
616 if (sio->nr_bvecs == ARRAY_SIZE(sio->bvecs) || !plug) {
617 swap_read_unplug(sio);
618 sio = NULL;
619 }
620 if (plug)
621 *plug = sio;
622}
623
624static void swap_read_folio_bdev_sync(struct folio *folio,
625 struct swap_info_struct *sis)
626{
627 struct bio_vec bv;
628 struct bio bio;
629
630 bio_init(&bio, sis->bdev, &bv, 1, REQ_OP_READ);
631 bio.bi_iter.bi_sector = swap_folio_sector(folio);
632 bio_add_folio_nofail(&bio, folio, folio_size(folio), 0);
633 /*
634 * Keep this task valid during swap readpage because the oom killer may
635 * attempt to access it in the page fault retry time check.
636 */
637 get_task_struct(current);
638 count_mthp_stat(folio_order(folio), MTHP_STAT_SWPIN);
639 count_memcg_folio_events(folio, PSWPIN, folio_nr_pages(folio));
640 count_vm_events(PSWPIN, folio_nr_pages(folio));
641 submit_bio_wait(&bio);
642 __end_swap_bio_read(&bio);
643 put_task_struct(current);
644}
645
646static void swap_read_folio_bdev_async(struct folio *folio,
647 struct swap_info_struct *sis)
648{
649 struct bio *bio;
650
651 bio = bio_alloc(sis->bdev, 1, REQ_OP_READ, GFP_KERNEL);
652 bio->bi_iter.bi_sector = swap_folio_sector(folio);
653 bio->bi_end_io = end_swap_bio_read;
654 bio_add_folio_nofail(bio, folio, folio_size(folio), 0);
655 count_mthp_stat(folio_order(folio), MTHP_STAT_SWPIN);
656 count_memcg_folio_events(folio, PSWPIN, folio_nr_pages(folio));
657 count_vm_events(PSWPIN, folio_nr_pages(folio));
658 submit_bio(bio);
659}
660
661void swap_read_folio(struct folio *folio, struct swap_iocb **plug)
662{453{
663 struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);454 struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);
664 bool synchronous = sis->flags & SWP_SYNCHRONOUS_IO;455 bool synchronous = sis->flags & SWP_SYNCHRONOUS_IO;
@@ -691,14 +482,7 @@ void swap_read_folio(struct folio *folio, struct swap_iocb **plug) · 26 unmodified lines
691 482
692 /* We have to read from slower devices. Increase zswap protection. */483 /* We have to read from slower devices. Increase zswap protection. */
693 zswap_folio_swapin(folio);484 zswap_folio_swapin(folio);
694 485 swap_add_folio(ctx, folio, READ);
695 if (data_race(sis->flags & SWP_FS_OPS)) {
696 swap_read_folio_fs(folio, plug);
697 } else if (synchronous) {
698 swap_read_folio_bdev_sync(folio, sis);
699 } else {
700 swap_read_folio_bdev_async(folio, sis);
701 }
702 486
703finish:487finish:
704 if (workingset) {488 if (workingset) {
@@ -708,14 +492,211 @@ finish: · 3 unmodified lines
708 delayacct_swapin_end();492 delayacct_swapin_end();
709}493}
710 494
711void __swap_read_unplug(struct swap_iocb *sio)495static void swap_write_end(struct swap_iocb *sio, bool failed)
712{496{
713 struct iov_iter from;497 int p;
714 struct address_space *mapping = sio->iocb.ki_filp->f_mapping;498
715 int ret;499 for (p = 0; p < sio->nr_bvecs; p++) {
500 struct page *page = sio->bvecs[p].bv_page;
501
502 if (failed) {
503 set_page_dirty(page);
504 ClearPageReclaim(page);
505 }
506 end_page_writeback(page);
507 }
508 mempool_free(sio, sio_pool);
509}
510
511static void swap_fs_write_complete(struct kiocb *iocb, long ret)
512{
513 struct swap_iocb *sio = container_of(iocb, struct swap_iocb, iocb);
514 bool failed = ret != sio->len;
515
516 if (failed) {
517 struct page *page = sio->bvecs[0].bv_page;
518
519 /*
520 * In the case of swap-over-nfs, this can be a temporary failure
521 * if the system has limited memory for allocating transmit
522 * buffers. Mark the page dirty and avoid
523 * folio_rotate_reclaimable but rate-limit the messages.
524 */
525 pr_err_ratelimited("Write error %ld on dio swapfile (%llu)\n",
526 ret, swap_dev_pos(page_swap_entry(page)));
527 }
528
529 swap_write_end(sio, failed);
530}
716 531
717 iov_iter_bvec(&from, ITER_DEST, sio->bvecs, sio->nr_bvecs, sio->len);532static void end_swap_bio_write(struct bio *bio)
718 ret = mapping->a_ops->swap_rw(&sio->iocb, &from);533{
719 if (ret != -EIOCBQUEUED)534 struct swap_iocb *sio = container_of(bio, struct swap_iocb, bio);
720 sio_read_complete(&sio->iocb, ret);535 bool failed = !!bio->bi_status;
536
537 if (failed)
538 pr_alert_ratelimited("Write-error on swap-device (%u:%u:%llu)\n",
539 MAJOR(bio_dev(bio)), MINOR(bio_dev(bio)),
540 (unsigned long long)bio->bi_iter.bi_sector);
541 bio_uninit(bio);
542 swap_write_end(sio, failed);
543}
544
545static void swap_read_end(struct swap_iocb *sio, bool failed)
546{
547 int p;
548
549 for (p = 0; p < sio->nr_bvecs; p++) {
550 struct folio *folio = bvec_folio(&sio->bvecs[p]);
551
552 if (!failed) {
553 count_mthp_stat(folio_order(folio), MTHP_STAT_SWPIN);
554 count_memcg_folio_events(folio, PSWPIN,
555 folio_nr_pages(folio));
556 folio_mark_uptodate(folio);
557 }
558 folio_unlock(folio);
559 }
560
561 if (!failed)
562 count_vm_events(PSWPIN, sio->len >> PAGE_SHIFT);
563
564 mempool_free(sio, sio_pool);
565}
566
567static void swap_fs_read_complete(struct kiocb *iocb, long ret)
568{
569 struct swap_iocb *sio = container_of(iocb, struct swap_iocb, iocb);
570 bool failed = ret != sio->len;
571
572 if (failed)
573 pr_alert_ratelimited("Read-error on swap-device\n");
574 swap_read_end(sio, failed);
575}
576
577static void swap_bio_read_end_io(struct bio *bio)
578{
579 struct swap_iocb *sio = container_of(bio, struct swap_iocb, bio);
580 bool failed = !!bio->bi_status;
581
582 if (failed)
583 pr_alert_ratelimited("Read-error on swap-device (%u:%u:%llu)\n",
584 MAJOR(bio_dev(bio)), MINOR(bio_dev(bio)),
585 (unsigned long long)bio->bi_iter.bi_sector);
586 bio_uninit(bio);
587 swap_read_end(sio, failed);
588}
589
590static void swap_bdev_submit_write(struct swap_io_ctx *ctx)
591{
592 struct swap_iocb *sio = ctx->sio;
593 struct bio *bio = &sio->bio;
594
595 bio_init(bio, ctx->sis->bdev, sio->bvecs, ARRAY_SIZE(sio->bvecs),
596 REQ_OP_WRITE | REQ_SWAP);
597 bio->bi_iter.bi_size = sio->len;
598 bio->bi_iter.bi_sector = swap_folio_sector(bio_first_folio_all(bio));
599 bio_associate_blkg_from_page(bio, bio_first_folio_all(bio));
600
601 if (ctx->sis->flags & SWP_SYNCHRONOUS_IO) {
602 submit_bio_wait(bio);
603 end_swap_bio_write(bio);
604 } else {
605 bio->bi_end_io = end_swap_bio_write;
606 submit_bio(bio);
607 }
608}
609
610static void swap_bdev_submit_read(struct swap_io_ctx *ctx)
611{
612 struct swap_iocb *sio = ctx->sio;
613 struct bio *bio = &sio->bio;
614
615 bio_init(bio, ctx->sis->bdev, sio->bvecs, ARRAY_SIZE(sio->bvecs),
616 REQ_OP_READ);
617 bio->bi_iter.bi_size = sio->len;
618 bio->bi_iter.bi_sector = swap_folio_sector(bio_first_folio_all(bio));
619
620 if (ctx->sis->flags & SWP_SYNCHRONOUS_IO) {
621 /*
622 * Keep this task valid during swap readpage because the oom
623 * killer may attempt to access it in the page fault retry
624 * time check.
625 */
626 get_task_struct(current);
627 submit_bio_wait(bio);
628 swap_bio_read_end_io(bio);
629 put_task_struct(current);
630 } else {
631 bio->bi_end_io = swap_bio_read_end_io;
632 submit_bio(bio);
633 }
634}
635
636static bool swap_bdev_can_merge(struct folio *folio, struct folio *prev_folio,
637 size_t prev_folio_size, int rw)
638{
639 if (swap_folio_sector(folio) !=
640 swap_folio_sector(prev_folio) + (prev_folio_size >> SECTOR_SHIFT))
641 return false;
642 if (rw == WRITE && !folio_blkg_can_merge(folio, prev_folio))
643 return false;
644 return true;
645}
646
647const struct swap_ops swap_bdev_ops = {
648 .submit_write = swap_bdev_submit_write,
649 .submit_read = swap_bdev_submit_read,
650 .can_merge = swap_bdev_can_merge,
651};
652
653void swap_fs_prepare_rw(struct swap_io_ctx *ctx, int rw, struct iov_iter *iter)
654{
655 struct swap_iocb *sio = ctx->sio;
656
657 init_sync_kiocb(&sio->iocb, ctx->sis->swap_file);
658 sio->iocb.ki_pos = swap_dev_pos(bvec_folio(&sio->bvecs[0])->swap);
659 if (rw == WRITE)
660 sio->iocb.ki_complete = swap_fs_write_complete;
661 else
662 sio->iocb.ki_complete = swap_fs_read_complete;
663
664 iov_iter_bvec(iter, rw == WRITE ? ITER_SOURCE : ITER_DEST,
665 sio->bvecs, sio->nr_bvecs, sio->len);
666}
667EXPORT_SYMBOL_GPL(swap_fs_prepare_rw);
668
669bool swap_fs_can_merge(struct folio *folio, struct folio *prev_folio,
670 size_t prev_folio_size, int rw)
671{
672 return swap_dev_pos(folio->swap) ==
673 swap_dev_pos(prev_folio->swap) + prev_folio_size;
674}
675EXPORT_SYMBOL_GPL(swap_fs_can_merge);
676
677int swap_fs_activate(struct swap_info_struct *sis, const struct swap_ops *ops)
678{
679 sis->ops = ops;
680 return add_swap_extent(sis, 0, sis->max, 0);
681}
682EXPORT_SYMBOL_GPL(swap_fs_activate);
683
684void swap_write_submit(struct swap_io_ctx *ctx)
685{
686 if (!ctx->sio)
687 return;
688 count_vm_events(NRSWPOUT, 1);
689 ctx->sis->ops->submit_write(ctx);
690 ctx->sio = NULL;
691 ctx->sis = NULL;
692}
693
694void swap_read_submit(struct swap_io_ctx *ctx)
695{
696 if (!ctx->sio)
697 return;
698 count_vm_events(NRSWPIN, 1);
699 ctx->sis->ops->submit_read(ctx);
700 ctx->sio = NULL;
701 ctx->sis = NULL;
721}702}
mm/page_reporting.c+18−10
@@ -48,7 +48,11 @@ MODULE_PARM_DESC(page_reporting_order, "Set page reporting order"); · 47 unmodified lines
48 */48 */
49EXPORT_SYMBOL_GPL(page_reporting_order);49EXPORT_SYMBOL_GPL(page_reporting_order);
50 50
51#define PAGE_REPORTING_DELAY (2 * HZ)51static unsigned int page_reporting_delay_ms = 2 * MSEC_PER_SEC;
52module_param(page_reporting_delay_ms, uint, 0644);
53MODULE_PARM_DESC(page_reporting_delay_ms,
54 "Set page reporting delay in milliseconds");
55
52static struct page_reporting_dev_info __rcu *pr_dev_info __read_mostly;56static struct page_reporting_dev_info __rcu *pr_dev_info __read_mostly;
53 57
54enum {58enum {
@@ -57,6 +61,13 @@ enum { · 2 unmodified lines
57 PAGE_REPORTING_ACTIVE61 PAGE_REPORTING_ACTIVE
58};62};
59 63
64/* schedule work for page reporting */
65static void page_reporting_schedule_work(struct page_reporting_dev_info *prdev)
66{
67 queue_delayed_work(system_freezable_wq, &prdev->work,
68 msecs_to_jiffies(page_reporting_delay_ms));
69}
70
60/* request page reporting */71/* request page reporting */
61static void72static void
62__page_reporting_request(struct page_reporting_dev_info *prdev)73__page_reporting_request(struct page_reporting_dev_info *prdev)
@@ -77,12 +88,10 @@ __page_reporting_request(struct page_reporting_dev_info *prdev) · 14 unmodified lines
77 return;88 return;
78 89
79 /*90 /*
80 * Delay the start of work to allow a sizable queue to build. For91 * Delay the start of work to allow a sizable queue to build.
81 * now we are limiting this to running no more than once every92 * We limit this based on page_reporting_delay_ms.
82 * couple of seconds.
83 */93 */
84 queue_delayed_work(system_freezable_wq, &prdev->work,94 page_reporting_schedule_work(prdev);
85 PAGE_REPORTING_DELAY);
86}95}
87 96
88/* notify prdev of free page reporting request */97/* notify prdev of free page reporting request */
@@ -337,13 +346,12 @@ static void page_reporting_process(struct work_struct *work) · 248 unmodified lines
337err_out:346err_out:
338 /*347 /*
339 * If the state has reverted back to requested then there may be348 * If the state has reverted back to requested then there may be
340 * additional pages to be processed. We will defer for 2s to allow349 * additional pages to be processed. We will defer by
341 * more pages to accumulate.350 * page_reporting_delay_ms to allow more pages to accumulate.
342 */351 */
343 state = atomic_cmpxchg(&prdev->state, state, PAGE_REPORTING_IDLE);352 state = atomic_cmpxchg(&prdev->state, state, PAGE_REPORTING_IDLE);
344 if (state == PAGE_REPORTING_REQUESTED)353 if (state == PAGE_REPORTING_REQUESTED)
345 queue_delayed_work(system_freezable_wq, &prdev->work,354 page_reporting_schedule_work(prdev);
346 PAGE_REPORTING_DELAY);
347}355}
348 356
349static DEFINE_MUTEX(page_reporting_mutex);357static DEFINE_MUTEX(page_reporting_mutex);
mm/page_vma_mapped.c+5−1
@@ -356,6 +356,7 @@ unsigned long page_mapped_in_vma(const struct page *page, · 355 unmodified lines
356 struct vm_area_struct *vma)356 struct vm_area_struct *vma)
357{357{
358 const struct folio *folio = page_folio(page);358 const struct folio *folio = page_folio(page);
359 const pgoff_t pgoff = page_pgoff(folio, page);
359 struct page_vma_mapped_walk pvmw = {360 struct page_vma_mapped_walk pvmw = {
360 .pfn = page_to_pfn(page),361 .pfn = page_to_pfn(page),
361 .nr_pages = 1,362 .nr_pages = 1,
@@ -363,7 +364,10 @@ unsigned long page_mapped_in_vma(const struct page *page, · 1 unmodified line
363 .flags = PVMW_SYNC,364 .flags = PVMW_SYNC,
364 };365 };
365 366
366 pvmw.address = vma_address(vma, page_pgoff(folio, page), 1);367 if (folio_test_anon(folio))
368 pvmw.address = vma_anon_address(vma, pgoff, 1);
369 else
370 pvmw.address = vma_filebacked_address(vma, pgoff, 1);
367 if (pvmw.address == -EFAULT)371 if (pvmw.address == -EFAULT)
368 goto out;372 goto out;
369 if (!page_vma_mapped_walk(&pvmw))373 if (!page_vma_mapped_walk(&pvmw))
mm/pgalloc-track.h+3−0
@@ -2,6 +2,9 @@ · 1 unmodified line
2#ifndef _LINUX_PGALLOC_TRACK_H2#ifndef _LINUX_PGALLOC_TRACK_H
3#define _LINUX_PGALLOC_TRACK_H3#define _LINUX_PGALLOC_TRACK_H
4 4
5#include <linux/mm.h>
6#include <linux/pgtable.h>
7
5#if defined(CONFIG_MMU)8#if defined(CONFIG_MMU)
6static inline p4d_t *p4d_alloc_track(struct mm_struct *mm, pgd_t *pgd,9static inline p4d_t *p4d_alloc_track(struct mm_struct *mm, pgd_t *pgd,
7 unsigned long address,10 unsigned long address,
mm/rmap.c+25−18
@@ -350,7 +350,7 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src, · 349 unmodified lines
350 * Now link the anon_vma's back to the newly inserted AVCs.350 * Now link the anon_vma's back to the newly inserted AVCs.
351 * Note that all anon_vma's share the same root.351 * Note that all anon_vma's share the same root.
352 */352 */
353 anon_vma_lock_write(src->anon_vma);353 anon_vma_lock_write(active_anon_vma);
354 list_for_each_entry_reverse(avc, &dst->anon_vma_chain, same_vma) {354 list_for_each_entry_reverse(avc, &dst->anon_vma_chain, same_vma) {
355 struct anon_vma *anon_vma = avc->anon_vma;355 struct anon_vma *anon_vma = avc->anon_vma;
356 356
@@ -865,14 +865,15 @@ unsigned long page_address_in_vma(const struct folio *folio, · 508 unmodified lines
865 if (!vma->anon_vma || !anon_vma ||865 if (!vma->anon_vma || !anon_vma ||
866 vma->anon_vma->root != anon_vma->root)866 vma->anon_vma->root != anon_vma->root)
867 return -EFAULT;867 return -EFAULT;
868 /* KSM folios don't reach here because of the !anon_vma check */
869 return vma_anon_address(vma, page_pgoff(folio, page), 1);
868 } else if (!vma->vm_file) {870 } else if (!vma->vm_file) {
869 return -EFAULT;871 return -EFAULT;
870 } else if (vma->vm_file->f_mapping != folio->mapping) {872 } else if (vma->vm_file->f_mapping != folio->mapping) {
871 return -EFAULT;873 return -EFAULT;
872 }874 }
873 875
874 /* KSM folios don't reach here because of the !anon_vma check */876 return vma_filebacked_address(vma, page_pgoff(folio, page), 1);
875 return vma_address(vma, page_pgoff(folio, page), 1);
876}877}
877 878
878/*879/*
@@ -907,7 +908,7 @@ out: · 28 unmodified lines
907struct folio_referenced_arg {908struct folio_referenced_arg {
908 int mapcount;909 int mapcount;
909 int referenced;910 int referenced;
910 vm_flags_t vm_flags;911 vma_flags_t vma_flags;
911 struct mem_cgroup *memcg;912 struct mem_cgroup *memcg;
912};913};
913 914
@@ -926,7 +927,7 @@ static bool folio_referenced_one(struct folio *folio, · 12 unmodified lines
926 address = pvmw.address;927 address = pvmw.address;
927 nr = 1;928 nr = 1;
928 929
929 if (vma->vm_flags & VM_LOCKED) {930 if (vma_test(vma, VMA_LOCKED_BIT)) {
930 ptes++;931 ptes++;
931 pra->mapcount--;932 pra->mapcount--;
932 933
@@ -947,7 +948,7 @@ static bool folio_referenced_one(struct folio *folio, · 14 unmodified lines
947 /* Restore the mlock which got missed */948 /* Restore the mlock which got missed */
948 mlock_vma_folio(folio, vma);949 mlock_vma_folio(folio, vma);
949 page_vma_mapped_walk_done(&pvmw);950 page_vma_mapped_walk_done(&pvmw);
950 pra->vm_flags |= VM_LOCKED;951 vma_flags_set(&pra->vma_flags, VMA_LOCKED_BIT);
951 return false; /* To break the loop */952 return false; /* To break the loop */
952 }953 }
953 954
@@ -1015,8 +1016,11 @@ static bool folio_referenced_one(struct folio *folio, · 61 unmodified lines
1015 referenced++;1016 referenced++;
1016 1017
1017 if (referenced) {1018 if (referenced) {
1019 vma_flags_t vma_flags = vma->flags;
1020
1018 pra->referenced++;1021 pra->referenced++;
1019 pra->vm_flags |= vma->vm_flags & ~VM_LOCKED;1022 vma_flags_clear(&vma_flags, VMA_LOCKED_BIT);
1023 vma_flags_set_mask(&pra->vma_flags, vma_flags);
1020 }1024 }
1021 1025
1022 if (!pra->mapcount)1026 if (!pra->mapcount)
@@ -1054,7 +1058,7 @@ static bool invalid_folio_referenced_vma(struct vm_area_struct *vma, void *arg) · 31 unmodified lines
1054 * @folio: The folio to test.1058 * @folio: The folio to test.
1055 * @is_locked: Caller holds lock on the folio.1059 * @is_locked: Caller holds lock on the folio.
1056 * @memcg: target memory cgroup1060 * @memcg: target memory cgroup
1057 * @vm_flags: A combination of all the vma->vm_flags which referenced the folio.1061 * @vma_flags: A combination of all the vma->flags which referenced the folio.
1058 *1062 *
1059 * Quick test_and_clear_referenced for all mappings of a folio,1063 * Quick test_and_clear_referenced for all mappings of a folio,
1060 *1064 *
@@ -1062,7 +1066,7 @@ static bool invalid_folio_referenced_vma(struct vm_area_struct *vma, void *arg) · 1 unmodified line
1062 * the function bailed out due to rmap lock contention.1066 * the function bailed out due to rmap lock contention.
1063 */1067 */
1064int folio_referenced(struct folio *folio, int is_locked,1068int folio_referenced(struct folio *folio, int is_locked,
1065 struct mem_cgroup *memcg, vm_flags_t *vm_flags)1069 struct mem_cgroup *memcg, vma_flags_t *vma_flags)
1066{1070{
1067 bool we_locked = false;1071 bool we_locked = false;
1068 struct folio_referenced_arg pra = {1072 struct folio_referenced_arg pra = {
@@ -1078,7 +1082,7 @@ int folio_referenced(struct folio *folio, int is_locked, · 9 unmodified lines
1078 };1082 };
1079 1083
1080 VM_WARN_ON_ONCE_FOLIO(folio_is_zone_device(folio), folio);1084 VM_WARN_ON_ONCE_FOLIO(folio_is_zone_device(folio), folio);
1081 *vm_flags = 0;1085 vma_flags_clear_all(vma_flags);
1082 if (!pra.mapcount)1086 if (!pra.mapcount)
1083 return 0;1087 return 0;
1084 1088
@@ -1092,7 +1096,7 @@ int folio_referenced(struct folio *folio, int is_locked, · 7 unmodified lines
1092 }1096 }
1093 1097
1094 rmap_walk(folio, &rwc);1098 rmap_walk(folio, &rwc);
1095 *vm_flags = pra.vm_flags;1099 vma_flags_set_mask(vma_flags, pra.vma_flags);
1096 1100
1097 if (we_locked)1101 if (we_locked)
1098 folio_unlock(folio);1102 folio_unlock(folio);
@@ -1239,6 +1243,7 @@ static bool mapping_wrprotect_range_one(struct folio *folio, · 140 unmodified lines
1239 .vma = vma,1243 .vma = vma,
1240 .address = address,1244 .address = address,
1241 .flags = PVMW_SYNC,1245 .flags = PVMW_SYNC,
1246 .pgoff_is_anon = false,
1242 };1247 };
1243 1248
1244 state->cleaned += page_vma_mkclean_one(&pvmw);1249 state->cleaned += page_vma_mkclean_one(&pvmw);
@@ -1316,12 +1321,13 @@ int pfn_mkclean_range(unsigned long pfn, unsigned long nr_pages, pgoff_t pgoff, · 71 unmodified lines
1316 .pgoff = pgoff,1321 .pgoff = pgoff,
1317 .vma = vma,1322 .vma = vma,
1318 .flags = PVMW_SYNC,1323 .flags = PVMW_SYNC,
1324 .pgoff_is_anon = false,
1319 };1325 };
1320 1326
1321 if (invalid_mkclean_vma(vma, NULL))1327 if (invalid_mkclean_vma(vma, NULL))
1322 return 0;1328 return 0;
1323 1329
1324 pvmw.address = vma_address(vma, pgoff, nr_pages);1330 pvmw.address = vma_filebacked_address(vma, pgoff, nr_pages);
1325 VM_BUG_ON_VMA(pvmw.address == -EFAULT, vma);1331 VM_BUG_ON_VMA(pvmw.address == -EFAULT, vma);
1326 1332
1327 return page_vma_mkclean_one(&pvmw);1333 return page_vma_mkclean_one(&pvmw);
@@ -1482,7 +1488,7 @@ static void __folio_set_anon(struct folio *folio, struct vm_area_struct *vma, · 154 unmodified lines
1482 */1488 */
1483 anon_vma = (void *) anon_vma + FOLIO_MAPPING_ANON;1489 anon_vma = (void *) anon_vma + FOLIO_MAPPING_ANON;
1484 WRITE_ONCE(folio->mapping, (struct address_space *) anon_vma);1490 WRITE_ONCE(folio->mapping, (struct address_space *) anon_vma);
1485 folio->index = linear_page_index(vma, address);1491 folio->index = linear_anon_page_index(vma, address);
1486}1492}
1487 1493
1488/**1494/**
@@ -1509,8 +1515,8 @@ static void __page_check_anon_rmap(const struct folio *folio, · 20 unmodified lines
1509 */1515 */
1510 VM_BUG_ON_FOLIO(folio_anon_vma(folio)->root != vma->anon_vma->root,1516 VM_BUG_ON_FOLIO(folio_anon_vma(folio)->root != vma->anon_vma->root,
1511 folio);1517 folio);
1512 VM_BUG_ON_PAGE(page_pgoff(folio, page) != linear_page_index(vma, address),1518 VM_BUG_ON_PAGE(page_pgoff(folio, page) !=
1513 page);1519 linear_anon_page_index(vma, address), page);
1514}1520}
1515 1521
1516static __always_inline void __folio_add_anon_rmap(struct folio *folio,1522static __always_inline void __folio_add_anon_rmap(struct folio *folio,
@@ -3035,10 +3041,10 @@ static void rmap_walk_anon(struct folio *folio, · 1518 unmodified lines
3035 pgoff_end = pgoff_start + folio_nr_pages(folio) - 1;3041 pgoff_end = pgoff_start + folio_nr_pages(folio) - 1;
3036 anon_rmap_tree_foreach(avc, anon_vma, pgoff_start, pgoff_end) {3042 anon_rmap_tree_foreach(avc, anon_vma, pgoff_start, pgoff_end) {
3037 struct vm_area_struct *vma = avc->vma;3043 struct vm_area_struct *vma = avc->vma;
3038 unsigned long address = vma_address(vma, pgoff_start,3044 const unsigned long address = vma_anon_address(vma, pgoff_start,
3039 folio_nr_pages(folio));3045 folio_nr_pages(folio));
3040 3046
3041 VM_BUG_ON_VMA(address == -EFAULT, vma);3047 VM_WARN_ON_ONCE_VMA(address == -EFAULT, vma);
3042 cond_resched();3048 cond_resched();
3043 3049
3044 if (rwc->invalid_vma && rwc->invalid_vma(vma, rwc->arg))3050 if (rwc->invalid_vma && rwc->invalid_vma(vma, rwc->arg))
@@ -3098,7 +3104,8 @@ static void __rmap_walk_file(struct folio *folio, struct address_space *mapping, · 53 unmodified lines
3098 }3104 }
3099lookup:3105lookup:
3100 mapping_rmap_tree_foreach(vma, mapping, pgoff_start, pgoff_end) {3106 mapping_rmap_tree_foreach(vma, mapping, pgoff_start, pgoff_end) {
3101 unsigned long address = vma_address(vma, pgoff_start, nr_pages);3107 unsigned long address = vma_filebacked_address(vma, pgoff_start,
3108 nr_pages);
3102 3109
3103 VM_BUG_ON_VMA(address == -EFAULT, vma);3110 VM_BUG_ON_VMA(address == -EFAULT, vma);
3104 cond_resched();3111 cond_resched();
mm/shmem.c+24−5
@@ -41,6 +41,7 @@ · 40 unmodified lines
41#include <linux/swapfile.h>41#include <linux/swapfile.h>
42#include <linux/iversion.h>42#include <linux/iversion.h>
43#include <linux/unicode.h>43#include <linux/unicode.h>
44#include <linux/swap_ops.h>
44#include "swap.h"45#include "swap.h"
45 46
46static struct vfsmount *shm_mnt __ro_after_init;47static struct vfsmount *shm_mnt __ro_after_init;
@@ -1597,13 +1598,13 @@ start_over: · 1550 unmodified lines
1597 1598
1598/**1599/**
1599 * shmem_writeout - Write the folio to swap1600 * shmem_writeout - Write the folio to swap
1601 * @ctx: swap I/O context
1600 * @folio: The folio to write1602 * @folio: The folio to write
1601 * @plug: swap plug
1602 * @folio_list: list to put back folios on split1603 * @folio_list: list to put back folios on split
1603 *1604 *
1604 * Move the folio from the page cache to the swap cache.1605 * Move the folio from the page cache to the swap cache.
1605 */1606 */
1606int shmem_writeout(struct folio *folio, struct swap_iocb **plug,1607int shmem_writeout(struct swap_io_ctx *ctx, struct folio *folio,
1607 struct list_head *folio_list)1608 struct list_head *folio_list)
1608{1609{
1609 struct address_space *mapping = folio->mapping;1610 struct address_space *mapping = folio->mapping;
@@ -1715,7 +1716,7 @@ try_split: · 105 unmodified lines
1715 shmem_delete_from_page_cache(folio, swp_to_radix_entry(folio->swap));1716 shmem_delete_from_page_cache(folio, swp_to_radix_entry(folio->swap));
1716 1717
1717 BUG_ON(folio_mapped(folio));1718 BUG_ON(folio_mapped(folio));
1718 error = swap_writeout(folio, plug);1719 error = swap_writeout(ctx, folio);
1719 if (error != AOP_WRITEPAGE_ACTIVATE) {1720 if (error != AOP_WRITEPAGE_ACTIVATE) {
1720 /* folio has been unlocked */1721 /* folio has been unlocked */
1721 return error;1722 return error;
@@ -1751,7 +1752,17 @@ redirty: · 29 unmodified lines
1751 folio_mark_dirty(folio);1752 folio_mark_dirty(folio);
1752 return AOP_WRITEPAGE_ACTIVATE; /* Return with folio locked */1753 return AOP_WRITEPAGE_ACTIVATE; /* Return with folio locked */
1753}1754}
1754EXPORT_SYMBOL_GPL(shmem_writeout);1755
1756int shmem_write_folio(struct folio *folio)
1757{
1758 struct swap_io_ctx ctx = {};
1759 int err;
1760
1761 err = shmem_writeout(&ctx, folio, NULL);
1762 swap_write_submit(&ctx);
1763 return err;
1764}
1765EXPORT_SYMBOL_GPL(shmem_write_folio);
1755 1766
1756#if defined(CONFIG_NUMA) && defined(CONFIG_TMPFS)1767#if defined(CONFIG_NUMA) && defined(CONFIG_TMPFS)
1757static void shmem_show_mpol(struct seq_file *seq, struct mempolicy *mpol)1768static void shmem_show_mpol(struct seq_file *seq, struct mempolicy *mpol)
@@ -3617,6 +3628,7 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset, · 1859 unmodified lines
3617 struct shmem_inode_info *info = SHMEM_I(inode);3628 struct shmem_inode_info *info = SHMEM_I(inode);
3618 struct shmem_falloc shmem_falloc;3629 struct shmem_falloc shmem_falloc;
3619 pgoff_t start, index, end, undo_fallocend;3630 pgoff_t start, index, end, undo_fallocend;
3631 loff_t aligned_end;
3620 int error;3632 int error;
3621 3633
3622 if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))3634 if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
@@ -3673,8 +3685,15 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset, · 50 unmodified lines
3673 goto out;3685 goto out;
3674 }3686 }
3675 3687
3688 /* Check for wraparound */
3689 if (check_add_overflow(offset + len, (loff_t)PAGE_SIZE - 1,
3690 &aligned_end)) {
3691 error = -EFBIG;
3692 goto out;
3693 }
3694
3676 start = offset >> PAGE_SHIFT;3695 start = offset >> PAGE_SHIFT;
3677 end = (offset + len + PAGE_SIZE - 1) >> PAGE_SHIFT;3696 end = aligned_end >> PAGE_SHIFT;
3678 /* Try to avoid a swapstorm if len is impossible to satisfy */3697 /* Try to avoid a swapstorm if len is impossible to satisfy */
3679 if (sbinfo->max_blocks && end - start > sbinfo->max_blocks) {3698 if (sbinfo->max_blocks && end - start > sbinfo->max_blocks) {
3680 error = -ENOSPC;3699 error = -ENOSPC;
mm/show_mem.c+6−6
@@ -309,8 +309,8 @@ static void show_free_areas(unsigned int filter, const nodemask_t *nodemask, · 308 unmodified lines
309 " min:%lukB"309 " min:%lukB"
310 " low:%lukB"310 " low:%lukB"
311 " high:%lukB"311 " high:%lukB"
312 " reserved_highatomic:%luKB"312 " reserved_highatomic:%lukB"
313 " free_highatomic:%luKB"313 " free_highatomic:%lukB"
314 " active_anon:%lukB"314 " active_anon:%lukB"
315 " inactive_anon:%lukB"315 " inactive_anon:%lukB"
316 " active_file:%lukB"316 " active_file:%lukB"
@@ -323,7 +323,7 @@ static void show_free_areas(unsigned int filter, const nodemask_t *nodemask, · 6 unmodified lines
323 " mlocked:%lukB"323 " mlocked:%lukB"
324 " bounce:%lukB"324 " bounce:%lukB"
325 " free_pcp:%lukB"325 " free_pcp:%lukB"
326 " local_pcp:%ukB"326 " local_pcp:%lukB"
327 " free_cma:%lukB"327 " free_cma:%lukB"
328 "\n",328 "\n",
329 zone->name,329 zone->name,
@@ -350,7 +350,7 @@ static void show_free_areas(unsigned int filter, const nodemask_t *nodemask, · 20 unmodified lines
350 K(zone_page_state(zone, NR_MLOCK)),350 K(zone_page_state(zone, NR_MLOCK)),
351 0UL,351 0UL,
352 K(free_pcp),352 K(free_pcp),
353 K(this_cpu_read(zone->per_cpu_pageset->count)),353 K((unsigned long)this_cpu_read(zone->per_cpu_pageset->count)),
354 K(zone_page_state(zone, NR_FREE_CMA_PAGES)));354 K(zone_page_state(zone, NR_FREE_CMA_PAGES)));
355 printk("lowmem_reserve[]:");355 printk("lowmem_reserve[]:");
356 for (i = 0; i < MAX_NR_ZONES; i++)356 for (i = 0; i < MAX_NR_ZONES; i++)
@@ -400,7 +400,7 @@ static void show_free_areas(unsigned int filter, const nodemask_t *nodemask, · 43 unmodified lines
400 hugetlb_show_meminfo_node(nid);400 hugetlb_show_meminfo_node(nid);
401 }401 }
402 402
403 printk("%ld total pagecache pages\n", global_node_page_state(NR_FILE_PAGES));403 printk("%lu total pagecache pages\n", global_node_page_state(NR_FILE_PAGES));
404 404
405 show_swap_cache_info();405 show_swap_cache_info();
406}406}
@@ -430,7 +430,7 @@ void __show_mem(unsigned int filter, const nodemask_t *nodemask, · 23 unmodified lines
430 printk("%lu pages cma reserved\n", totalcma_pages);430 printk("%lu pages cma reserved\n", totalcma_pages);
431#endif431#endif
432#ifdef CONFIG_MEMORY_FAILURE432#ifdef CONFIG_MEMORY_FAILURE
433 printk("%lu pages hwpoisoned\n", atomic_long_read(&num_poisoned_pages));433 printk("%ld pages hwpoisoned\n", atomic_long_read(&num_poisoned_pages));
434#endif434#endif
435#ifdef CONFIG_MEM_ALLOC_PROFILING435#ifdef CONFIG_MEM_ALLOC_PROFILING
436 static DEFINE_SPINLOCK(mem_alloc_profiling_spinlock);436 static DEFINE_SPINLOCK(mem_alloc_profiling_spinlock);
mm/shuffle.h+2−0
@@ -2,7 +2,9 @@ · 1 unmodified line
2// Copyright(c) 2018 Intel Corporation. All rights reserved.2// Copyright(c) 2018 Intel Corporation. All rights reserved.
3#ifndef _MM_SHUFFLE_H3#ifndef _MM_SHUFFLE_H
4#define _MM_SHUFFLE_H4#define _MM_SHUFFLE_H
5
5#include <linux/jump_label.h>6#include <linux/jump_label.h>
7#include <linux/mmzone.h>
6 8
7#define SHUFFLE_ORDER MAX_PAGE_ORDER9#define SHUFFLE_ORDER MAX_PAGE_ORDER
8 10
mm/sparse.c+4−14
@@ -104,7 +104,7 @@ int __meminit sparse_index_init(unsigned long section_nr, int nid) · 103 unmodified lines
104 return 0;104 return 0;
105}105}
106#else /* !SPARSEMEM_EXTREME */106#else /* !SPARSEMEM_EXTREME */
107int sparse_index_init(unsigned long section_nr, int nid)107int __meminit sparse_index_init(unsigned long section_nr, int nid)
108{108{
109 return 0;109 return 0;
110}110}
@@ -127,7 +127,7 @@ static inline int sparse_early_nid(struct mem_section *section) · 16 unmodified lines
127}127}
128 128
129/* Validate the physical addressing limitations of the model */129/* Validate the physical addressing limitations of the model */
130static void __meminit mminit_validate_memmodel_limits(unsigned long *start_pfn,130static void __init mminit_validate_memmodel_limits(unsigned long *start_pfn,
131 unsigned long *end_pfn)131 unsigned long *end_pfn)
132{132{
133 unsigned long max_sparsemem_pfn = (DIRECT_MAP_PHYSMEM_END + 1) >> PAGE_SHIFT;133 unsigned long max_sparsemem_pfn = (DIRECT_MAP_PHYSMEM_END + 1) >> PAGE_SHIFT;
@@ -213,16 +213,6 @@ static void __init memblocks_present(void) · 79 unmodified lines
213 memory_present(nid, start, end);213 memory_present(nid, start, end);
214}214}
215 215
216static unsigned long usemap_size(void)
217{
218 return BITS_TO_LONGS(SECTION_BLOCKFLAGS_BITS) * sizeof(unsigned long);
219}
220
221size_t mem_section_usage_size(void)
222{
223 return sizeof(struct mem_section_usage) + usemap_size();
224}
225
226#ifdef CONFIG_SPARSEMEM_VMEMMAP216#ifdef CONFIG_SPARSEMEM_VMEMMAP
227unsigned long __init section_map_size(void)217unsigned long __init section_map_size(void)
228{218{
@@ -249,8 +239,8 @@ void __weak __meminit vmemmap_populate_print_last(void) · 20 unmodified lines
249{239{
250}240}
251 241
252static void *sparse_usagebuf __meminitdata;242static void *sparse_usagebuf __initdata;
253static void *sparse_usagebuf_end __meminitdata;243static void *sparse_usagebuf_end __initdata;
254 244
255/*245/*
256 * Helper function that is used for generic section initialization, and246 * Helper function that is used for generic section initialization, and
mm/sparse.h+6−0
@@ -47,6 +47,12 @@ static inline void __section_mark_present(struct mem_section *ms, · 46 unmodified lines
47 47
48 ms->section_mem_map |= SECTION_MARKED_PRESENT;48 ms->section_mem_map |= SECTION_MARKED_PRESENT;
49}49}
50
51static inline size_t mem_section_usage_size(void)
52{
53 return struct_size_t(struct mem_section_usage, pageblock_flags,
54 BITS_TO_LONGS(SECTION_BLOCKFLAGS_BITS));
55}
50#else56#else
51static inline void sparse_init(void) {}57static inline void sparse_init(void) {}
52#endif /* CONFIG_SPARSEMEM */58#endif /* CONFIG_SPARSEMEM */
mm/swap.h+31−34
@@ -4,9 +4,13 @@ · 3 unmodified lines
4 4
5#include <linux/atomic.h> /* for atomic_long_t */5#include <linux/atomic.h> /* for atomic_long_t */
6#include <linux/mm.h> /* for PAGE_SHIFT */6#include <linux/mm.h> /* for PAGE_SHIFT */
7#include <linux/memcontrol.h> /* for mem_cgroup_swappiness() */
8#include <linux/swap.h> /* for MAX_SWAPFILES_SHIFT, struct swap_info_struct */
9
7struct mempolicy;10struct mempolicy;
8struct swap_iocb;11struct swap_iocb;
9struct swap_memcg_table;12struct swap_memcg_table;
13struct swap_io_ctx;
10 14
11#if defined(MAX_POSSIBLE_PHYSMEM_BITS)15#if defined(MAX_POSSIBLE_PHYSMEM_BITS)
12#define SWAP_CACHE_PFN_BITS (MAX_POSSIBLE_PHYSMEM_BITS - PAGE_SHIFT)16#define SWAP_CACHE_PFN_BITS (MAX_POSSIBLE_PHYSMEM_BITS - PAGE_SHIFT)
@@ -76,6 +80,18 @@ enum swap_cluster_flags { · 63 unmodified lines
76 CLUSTER_FLAG_MAX,80 CLUSTER_FLAG_MAX,
77};81};
78 82
83extern int vm_swappiness;
84
85static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
86{
87#ifdef CONFIG_MEMCG_V1
88 if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) &&
89 !mem_cgroup_disabled() && !mem_cgroup_is_root(memcg))
90 return READ_ONCE(memcg->swappiness);
91#endif
92 return READ_ONCE(vm_swappiness);
93}
94
79#ifdef CONFIG_SWAP95#ifdef CONFIG_SWAP
80#include <linux/swapops.h> /* for swp_offset */96#include <linux/swapops.h> /* for swp_offset */
81#include <linux/blk_types.h> /* for bio_end_io_t */97#include <linux/blk_types.h> /* for bio_end_io_t */
@@ -238,17 +254,11 @@ extern void __swap_cluster_free_entries(struct swap_info_struct *si, · 156 unmodified lines
238 254
239/* linux/mm/page_io.c */255/* linux/mm/page_io.c */
240int sio_pool_init(void);256int sio_pool_init(void);
241struct swap_iocb;257void swap_read_folio(struct swap_io_ctx *ctx, struct folio *folio);
242void swap_read_folio(struct folio *folio, struct swap_iocb **plug);258void swap_read_submit(struct swap_io_ctx *ctx);
243void __swap_read_unplug(struct swap_iocb *plug);259void swap_write_submit(struct swap_io_ctx *ctx);
244static inline void swap_read_unplug(struct swap_iocb *plug)260int swap_writeout(struct swap_io_ctx *ctx, struct folio *folio);
245{261void __swap_writepage(struct swap_io_ctx *ctx, struct folio *folio);
246 if (unlikely(plug))
247 __swap_read_unplug(plug);
248}
249void swap_write_unplug(struct swap_iocb *sio);
250int swap_writeout(struct folio *folio, struct swap_iocb **swap_plug);
251void __swap_writepage(struct folio *folio, struct swap_iocb **swap_plug);
252 262
253/* linux/mm/swap_state.c */263/* linux/mm/swap_state.c */
254extern struct address_space swap_space __read_mostly;264extern struct address_space swap_space __read_mostly;
@@ -315,9 +325,8 @@ void __swap_cache_replace_folio(struct swap_cluster_info *ci, · 60 unmodified lines
315 325
316void show_swap_cache_info(void);326void show_swap_cache_info(void);
317void swapcache_clear(struct swap_info_struct *si, swp_entry_t entry, int nr);327void swapcache_clear(struct swap_info_struct *si, swp_entry_t entry, int nr);
318struct folio *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,328struct folio *read_swap_cache_async(struct swap_io_ctx *ctx, swp_entry_t entry,
319 struct vm_area_struct *vma, unsigned long addr,329 gfp_t gfp_mask, struct vm_area_struct *vma, unsigned long addr);
320 struct swap_iocb **plug);
321struct folio *swap_cluster_readahead(swp_entry_t entry, gfp_t flag,330struct folio *swap_cluster_readahead(swp_entry_t entry, gfp_t flag,
322 struct mempolicy *mpol, pgoff_t ilx);331 struct mempolicy *mpol, pgoff_t ilx);
323struct folio *swapin_readahead(swp_entry_t entry, gfp_t flag,332struct folio *swapin_readahead(swp_entry_t entry, gfp_t flag,
@@ -327,18 +336,7 @@ struct folio *swapin_sync(swp_entry_t entry, gfp_t flag, unsigned long orders, · 3 unmodified lines
327void swap_update_readahead(struct folio *folio, struct vm_area_struct *vma,336void swap_update_readahead(struct folio *folio, struct vm_area_struct *vma,
328 unsigned long addr);337 unsigned long addr);
329 338
330static inline unsigned int folio_swap_flags(struct folio *folio)
331{
332 return __swap_entry_to_info(folio->swap)->flags;
333}
334
335#else /* CONFIG_SWAP */339#else /* CONFIG_SWAP */
336struct swap_iocb;
337static inline struct swap_cluster_info *swap_cluster_lock(
338 struct swap_info_struct *si, pgoff_t offset, bool irq)
339{
340 return NULL;
341}
342 340
343static inline struct swap_cluster_info *swap_cluster_get_and_lock(341static inline struct swap_cluster_info *swap_cluster_get_and_lock(
344 struct folio *folio)342 struct folio *folio)
@@ -379,11 +377,11 @@ static inline void folio_put_swap(struct folio *folio, struct page *page) · 34 unmodified lines
379{377{
380}378}
381 379
382static inline void swap_read_folio(struct folio *folio, struct swap_iocb **plug)380static inline void swap_read_folio(struct swap_io_ctx *ctx, struct folio *folio)
383{381{
384}382}
385 383
386static inline void swap_write_unplug(struct swap_iocb *sio)384static inline void swap_write_submit(struct swap_io_ctx *ctx)
387{385{
388}386}
389 387
@@ -425,8 +423,7 @@ static inline void swap_update_readahead(struct folio *folio, · 35 unmodified lines
425{423{
426}424}
427 425
428static inline int swap_writeout(struct folio *folio,426static inline int swap_writeout(struct swap_io_ctx *ctx, struct folio *folio)
429 struct swap_iocb **swap_plug)
430{427{
431 return 0;428 return 0;
432}429}
@@ -464,11 +461,11 @@ static inline void __swap_cache_replace_folio(struct swap_cluster_info *ci, · 31 unmodified lines
464 struct folio *old, struct folio *new)461 struct folio *old, struct folio *new)
465{462{
466}463}
464#endif /* CONFIG_SWAP */
467 465
468static inline unsigned int folio_swap_flags(struct folio *folio)466extern const struct swap_ops swap_bdev_ops;
469{467
470 return 0;468int shmem_writeout(struct swap_io_ctx *ctx, struct folio *folio,
471}469 struct list_head *folio_list);
472 470
473#endif /* CONFIG_SWAP */
474#endif /* _MM_SWAP_H */471#endif /* _MM_SWAP_H */
mm/swap_state.c+32−22
@@ -23,6 +23,7 @@ · 22 unmodified lines
23#include <linux/huge_mm.h>23#include <linux/huge_mm.h>
24#include <linux/shmem_fs.h>24#include <linux/shmem_fs.h>
25#include <linux/sysctl.h>25#include <linux/sysctl.h>
26#include <linux/swap_ops.h>
26#include "internal.h"27#include "internal.h"
27#include "swap_table.h"28#include "swap_table.h"
28#include "swap.h"29#include "swap.h"
@@ -638,9 +639,9 @@ void swap_update_readahead(struct folio *folio, struct vm_area_struct *vma, · 609 unmodified lines
638 }639 }
639}640}
640 641
641static struct folio *swap_cache_read_folio(swp_entry_t entry, gfp_t gfp,642static struct folio *swap_cache_read_folio(struct swap_io_ctx *ctx,
642 struct mempolicy *mpol, pgoff_t ilx,643 swp_entry_t entry, gfp_t gfp, struct mempolicy *mpol,
643 struct swap_iocb **plug, bool readahead)644 pgoff_t ilx, bool readahead)
644{645{
645 struct folio *folio;646 struct folio *folio;
646 647
@@ -654,7 +655,7 @@ static struct folio *swap_cache_read_folio(swp_entry_t entry, gfp_t gfp, · 7 unmodified lines
654 if (IS_ERR_OR_NULL(folio))655 if (IS_ERR_OR_NULL(folio))
655 return NULL;656 return NULL;
656 657
657 swap_read_folio(folio, plug);658 swap_read_folio(ctx, folio);
658 if (readahead) {659 if (readahead) {
659 folio_set_readahead(folio);660 folio_set_readahead(folio);
660 count_vm_event(SWAP_RA);661 count_vm_event(SWAP_RA);
@@ -682,6 +683,7 @@ static struct folio *swap_cache_read_folio(swp_entry_t entry, gfp_t gfp, · 21 unmodified lines
682struct folio *swapin_sync(swp_entry_t entry, gfp_t gfp, unsigned long orders,683struct folio *swapin_sync(swp_entry_t entry, gfp_t gfp, unsigned long orders,
683 struct vm_fault *vmf, struct mempolicy *mpol, pgoff_t ilx)684 struct vm_fault *vmf, struct mempolicy *mpol, pgoff_t ilx)
684{685{
686 struct swap_io_ctx ctx = {};
685 struct folio *folio;687 struct folio *folio;
686 688
687 do {689 do {
@@ -694,7 +696,8 @@ struct folio *swapin_sync(swp_entry_t entry, gfp_t gfp, unsigned long orders, · 6 unmodified lines
694 if (IS_ERR(folio))696 if (IS_ERR(folio))
695 return folio;697 return folio;
696 698
697 swap_read_folio(folio, NULL);699 swap_read_folio(&ctx, folio);
700 swap_read_submit(&ctx);
698 return folio;701 return folio;
699}702}
700 703
@@ -704,9 +707,8 @@ struct folio *swapin_sync(swp_entry_t entry, gfp_t gfp, unsigned long orders, · 3 unmodified lines
704 * A failure return means that either the page allocation failed or that707 * A failure return means that either the page allocation failed or that
705 * the swap entry is no longer in use.708 * the swap entry is no longer in use.
706 */709 */
707struct folio *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,710struct folio *read_swap_cache_async(struct swap_io_ctx *ctx, swp_entry_t entry,
708 struct vm_area_struct *vma, unsigned long addr,711 gfp_t gfp_mask, struct vm_area_struct *vma, unsigned long addr)
709 struct swap_iocb **plug)
710{712{
711 struct swap_info_struct *si;713 struct swap_info_struct *si;
712 struct mempolicy *mpol;714 struct mempolicy *mpol;
@@ -718,13 +720,24 @@ struct folio *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask, · 5 unmodified lines
718 return NULL;720 return NULL;
719 721
720 mpol = get_vma_policy(vma, addr, 0, &ilx);722 mpol = get_vma_policy(vma, addr, 0, &ilx);
721 folio = swap_cache_read_folio(entry, gfp_mask, mpol, ilx, plug, false);723 folio = swap_cache_read_folio(ctx, entry, gfp_mask, mpol, ilx, false);
722 mpol_cond_put(mpol);724 mpol_cond_put(mpol);
723 725
724 put_swap_device(si);726 put_swap_device(si);
725 return folio;727 return folio;
726}728}
727 729
730static struct folio *swap_cache_read_folio_sync(swp_entry_t entry, gfp_t gfp,
731 struct mempolicy *mpol, pgoff_t ilx)
732{
733 struct swap_io_ctx ctx = {};
734 struct folio *folio;
735
736 folio = swap_cache_read_folio(&ctx, entry, gfp, mpol, ilx, false);
737 swap_read_submit(&ctx);
738 return folio;
739}
740
728static unsigned int __swapin_nr_pages(unsigned long prev_offset,741static unsigned int __swapin_nr_pages(unsigned long prev_offset,
729 unsigned long offset,742 unsigned long offset,
730 int hits,743 int hits,
@@ -813,8 +826,8 @@ struct folio *swap_cluster_readahead(swp_entry_t entry, gfp_t gfp_mask, · 82 unmodified lines
813 unsigned long start_offset, end_offset;826 unsigned long start_offset, end_offset;
814 unsigned long mask;827 unsigned long mask;
815 struct swap_info_struct *si = __swap_entry_to_info(entry);828 struct swap_info_struct *si = __swap_entry_to_info(entry);
829 struct swap_io_ctx ctx = {};
816 struct blk_plug plug;830 struct blk_plug plug;
817 struct swap_iocb *splug = NULL;
818 swp_entry_t ra_entry;831 swp_entry_t ra_entry;
819 832
820 mask = swapin_nr_pages(offset) - 1;833 mask = swapin_nr_pages(offset) - 1;
@@ -833,17 +846,16 @@ struct folio *swap_cluster_readahead(swp_entry_t entry, gfp_t gfp_mask, · 12 unmodified lines
833 for (offset = start_offset; offset <= end_offset ; offset++) {846 for (offset = start_offset; offset <= end_offset ; offset++) {
834 /* Ok, do the async read-ahead now */847 /* Ok, do the async read-ahead now */
835 ra_entry = swp_entry(swp_type(entry), offset);848 ra_entry = swp_entry(swp_type(entry), offset);
836 folio = swap_cache_read_folio(ra_entry, gfp_mask, mpol, ilx,849 folio = swap_cache_read_folio(&ctx, ra_entry, gfp_mask, mpol,
837 &splug, offset != entry_offset);850 ilx, offset != entry_offset);
838 if (!folio)851 if (!folio)
839 continue;852 continue;
840 folio_put(folio);853 folio_put(folio);
841 }854 }
842 blk_finish_plug(&plug);855 blk_finish_plug(&plug);
843 swap_read_unplug(splug);856 swap_read_submit(&ctx);
844skip:857skip:
845 /* The page was likely read above, so no need for plugging here */858 return swap_cache_read_folio_sync(entry, gfp_mask, mpol, ilx);
846 return swap_cache_read_folio(entry, gfp_mask, mpol, ilx, NULL, false);
847}859}
848 860
849static int swap_vma_ra_win(struct vm_fault *vmf, unsigned long *start,861static int swap_vma_ra_win(struct vm_fault *vmf, unsigned long *start,
@@ -903,8 +915,8 @@ static int swap_vma_ra_win(struct vm_fault *vmf, unsigned long *start, · 53 unmodified lines
903static struct folio *swap_vma_readahead(swp_entry_t targ_entry, gfp_t gfp_mask,915static struct folio *swap_vma_readahead(swp_entry_t targ_entry, gfp_t gfp_mask,
904 struct mempolicy *mpol, pgoff_t targ_ilx, struct vm_fault *vmf)916 struct mempolicy *mpol, pgoff_t targ_ilx, struct vm_fault *vmf)
905{917{
918 struct swap_io_ctx ctx = {};
906 struct blk_plug plug;919 struct blk_plug plug;
907 struct swap_iocb *splug = NULL;
908 struct folio *folio;920 struct folio *folio;
909 pte_t *pte = NULL, pentry;921 pte_t *pte = NULL, pentry;
910 int win;922 int win;
@@ -943,8 +955,8 @@ static struct folio *swap_vma_readahead(swp_entry_t targ_entry, gfp_t gfp_mask, · 32 unmodified lines
943 if (!si)955 if (!si)
944 continue;956 continue;
945 }957 }
946 folio = swap_cache_read_folio(entry, gfp_mask, mpol, ilx,958 folio = swap_cache_read_folio(&ctx, entry, gfp_mask, mpol, ilx,
947 &splug, addr != vmf->address);959 addr != vmf->address);
948 if (si)960 if (si)
949 put_swap_device(si);961 put_swap_device(si);
950 if (!folio)962 if (!folio)
@@ -954,12 +966,10 @@ static struct folio *swap_vma_readahead(swp_entry_t targ_entry, gfp_t gfp_mask, · 3 unmodified lines
954 if (pte)966 if (pte)
955 pte_unmap(pte);967 pte_unmap(pte);
956 blk_finish_plug(&plug);968 blk_finish_plug(&plug);
957 swap_read_unplug(splug);969 swap_read_submit(&ctx);
958skip:970skip:
959 /* The folio was likely read above, so no need for plugging here */971 /* The folio was likely read above, so no need for plugging here */
960 folio = swap_cache_read_folio(targ_entry, gfp_mask, mpol, targ_ilx,972 return swap_cache_read_folio_sync(targ_entry, gfp_mask, mpol, targ_ilx);
961 NULL, false);
962 return folio;
963}973}
964 974
965/**975/**
mm/swapfile.c+16−8
@@ -1899,11 +1899,11 @@ struct swap_info_struct *get_swap_device(swp_entry_t entry) · 1898 unmodified lines
1899 1899
1900 return si;1900 return si;
1901bad_nofile:1901bad_nofile:
1902 pr_err("%s: %s%08lx\n", __func__, Bad_file, entry.val);1902 pr_err_ratelimited("%s: %s%08lx\n", __func__, Bad_file, entry.val);
1903out:1903out:
1904 return NULL;1904 return NULL;
1905put_out:1905put_out:
1906 pr_err("%s: %s%08lx\n", __func__, Bad_offset, entry.val);1906 pr_err_ratelimited("%s: %s%08lx\n", __func__, Bad_offset, entry.val);
1907 percpu_ref_put(&si->users);1907 percpu_ref_put(&si->users);
1908 return NULL;1908 return NULL;
1909}1909}
@@ -2959,6 +2959,12 @@ static int setup_swap_extents(struct swap_info_struct *sis, · 1049 unmodified lines
2959 struct inode *inode = mapping->host;2959 struct inode *inode = mapping->host;
2960 int ret;2960 int ret;
2961 2961
2962 ret = sio_pool_init();
2963 if (ret)
2964 return ret;
2965
2966 sis->ops = &swap_bdev_ops;
2967
2962 if (S_ISBLK(inode->i_mode)) {2968 if (S_ISBLK(inode->i_mode)) {
2963 ret = add_swap_extent(sis, 0, sis->max, 0);2969 ret = add_swap_extent(sis, 0, sis->max, 0);
2964 *span = sis->pages;2970 *span = sis->pages;
@@ -2970,11 +2976,6 @@ static int setup_swap_extents(struct swap_info_struct *sis, · 5 unmodified lines
2970 if (ret < 0)2976 if (ret < 0)
2971 return ret;2977 return ret;
2972 sis->flags |= SWP_ACTIVATED;2978 sis->flags |= SWP_ACTIVATED;
2973 if ((sis->flags & SWP_FS_OPS) &&
2974 sio_pool_init() != 0) {
2975 destroy_swap_extents(sis, swap_file);
2976 return -ENOMEM;
2977 }
2978 return ret;2979 return ret;
2979 }2980 }
2980 2981
@@ -3668,6 +3669,13 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) · 687 unmodified lines
3668 error = -EBUSY;3669 error = -EBUSY;
3669 goto bad_swap_unlock_inode;3670 goto bad_swap_unlock_inode;
3670 }3671 }
3672 if (IS_ENCRYPTED(inode)) {
3673 pr_warn_once(
3674 "Filesystem-level encrypted swapfile '%s' is unsupported. Create a loop device over it, or use dm-crypt\n",
3675 name->name);
3676 error = -EINVAL;
3677 goto bad_swap_unlock_inode;
3678 }
3671 3679
3672 /*3680 /*
3673 * The swap subsystem needs a major overhaul to support this.3681 * The swap subsystem needs a major overhaul to support this.
@@ -3875,7 +3883,7 @@ int swap_dup_entry_direct(swp_entry_t entry) · 201 unmodified lines
3875 3883
3876 si = swap_entry_to_info(entry);3884 si = swap_entry_to_info(entry);
3877 if (WARN_ON_ONCE(!si)) {3885 if (WARN_ON_ONCE(!si)) {
3878 pr_err("%s%08lx\n", Bad_file, entry.val);3886 pr_err_ratelimited("%s%08lx\n", Bad_file, entry.val);
3879 return -EINVAL;3887 return -EINVAL;
3880 }3888 }
3881 3889
mm/userfaultfd.c+2−2
@@ -1352,7 +1352,7 @@ static long move_present_ptes(struct mm_struct *mm, · 1351 unmodified lines
1352 }1352 }
1353 1353
1354 folio_move_anon_rmap(src_folio, dst_vma);1354 folio_move_anon_rmap(src_folio, dst_vma);
1355 src_folio->index = linear_page_index(dst_vma, dst_addr);1355 src_folio->index = linear_anon_page_index(dst_vma, dst_addr);
1356 1356
1357 orig_dst_pte = folio_mk_pte(src_folio, dst_vma->vm_page_prot);1357 orig_dst_pte = folio_mk_pte(src_folio, dst_vma->vm_page_prot);
1358 /* Set soft dirty bit so userspace can notice the pte was moved */1358 /* Set soft dirty bit so userspace can notice the pte was moved */
@@ -1428,7 +1428,7 @@ static int move_swap_pte(struct mm_struct *mm, struct vm_area_struct *dst_vma, · 69 unmodified lines
1428 */1428 */
1429 if (src_folio) {1429 if (src_folio) {
1430 folio_move_anon_rmap(src_folio, dst_vma);1430 folio_move_anon_rmap(src_folio, dst_vma);
1431 src_folio->index = linear_page_index(dst_vma, dst_addr);1431 src_folio->index = linear_anon_page_index(dst_vma, dst_addr);
1432 } else {1432 } else {
1433 /*1433 /*
1434 * Check if the swap entry is cached after acquiring the src_pte1434 * Check if the swap entry is cached after acquiring the src_pte
mm/vma.c+79−34
@@ -18,6 +18,7 @@ struct mmap_state { · 17 unmodified lines
18 unsigned long addr;18 unsigned long addr;
19 unsigned long end;19 unsigned long end;
20 pgoff_t pgoff;20 pgoff_t pgoff;
21 pgoff_t anon_pgoff;
21 unsigned long pglen;22 unsigned long pglen;
22 union {23 union {
23 vm_flags_t vm_flags;24 vm_flags_t vm_flags;
@@ -46,13 +47,14 @@ struct mmap_state { · 22 unmodified lines
46 bool file_doesnt_need_get :1;47 bool file_doesnt_need_get :1;
47};48};
48 49
49#define MMAP_STATE(name, mm_, vmi_, addr_, len_, pgoff_, vma_flags_, file_) \50#define MMAP_STATE(name, mm_, vmi_, addr_, len_, pgoff_, anon_pgoff_, vma_flags_, file_) \
50 struct mmap_state name = { \51 struct mmap_state name = { \
51 .mm = mm_, \52 .mm = mm_, \
52 .vmi = vmi_, \53 .vmi = vmi_, \
53 .addr = addr_, \54 .addr = addr_, \
54 .end = (addr_) + (len_), \55 .end = (addr_) + (len_), \
55 .pgoff = pgoff_, \56 .pgoff = pgoff_, \
57 .anon_pgoff = anon_pgoff_, \
56 .pglen = PHYS_PFN(len_), \58 .pglen = PHYS_PFN(len_), \
57 .vma_flags = vma_flags_, \59 .vma_flags = vma_flags_, \
58 .file = file_, \60 .file = file_, \
@@ -67,6 +69,7 @@ struct mmap_state { · 8 unmodified lines
67 .end = (map_)->end, \69 .end = (map_)->end, \
68 .vma_flags = (map_)->vma_flags, \70 .vma_flags = (map_)->vma_flags, \
69 .pgoff = (map_)->pgoff, \71 .pgoff = (map_)->pgoff, \
72 .anon_pgoff = (map_)->anon_pgoff, \
70 .file = (map_)->file, \73 .file = (map_)->file, \
71 .prev = (map_)->prev, \74 .prev = (map_)->prev, \
72 .middle = vma_, \75 .middle = vma_, \
@@ -82,10 +85,11 @@ static void __vma_set_range(struct vm_area_struct *vma, unsigned long start, · 9 unmodified lines
82}85}
83 86
84static void vma_set_range(struct vm_area_struct *vma, unsigned long start,87static void vma_set_range(struct vm_area_struct *vma, unsigned long start,
85 unsigned long end, pgoff_t pgoff)88 unsigned long end, pgoff_t pgoff, pgoff_t anon_pgoff)
86{89{
87 __vma_set_range(vma, start, end);90 __vma_set_range(vma, start, end);
88 vma_set_pgoff(vma, pgoff);91 vma_set_pgoff(vma, pgoff);
92 vma_set_anon_pgoff(vma, anon_pgoff);
89}93}
90 94
91/* Was this VMA ever forked from a parent, i.e. maybe contains CoW mappings? */95/* Was this VMA ever forked from a parent, i.e. maybe contains CoW mappings? */
@@ -200,6 +204,25 @@ static void init_multi_vma_prep(struct vma_prepare *vp, · 108 unmodified lines
200 vp->skip_vma_uprobe = true;204 vp->skip_vma_uprobe = true;
201}205}
202 206
207/*
208 * Does this merge require that adjacent VMAs must have adjacent anonymous page
209 * offsets in addition to having adjacent vma->vm_pgoff?
210 *
211 * This is only required for MAP_PRIVATE-file backed mappings as the page offset
212 * for pure anonymous VMAs is equal to the anonymous page offset.
213 *
214 * Read-only shared mappings (with VMA_SHARED_BIT cleared) are always unfaulted
215 * so automatically have correct anonymous page offset (as it is always updated
216 * on remap).
217 *
218 * 'Special' mappings in the sense of VDSO, VVAR etc. have !file but would in
219 * any case not be candidates for merge nor be mergeable.
220 */
221static bool needs_adjacent_anon_pgoff(const struct vma_merge_struct *vmg)
222{
223 return vmg->file && vma_flags_is_cow_mapping(&vmg->vma_flags);
224}
225
203/*226/*
204 * Return true if we can merge this (vma_flags,anon_vma,file,vm_pgoff)227 * Return true if we can merge this (vma_flags,anon_vma,file,vm_pgoff)
205 * in front of (at a lower virtual address and file offset than) the vma.228 * in front of (at a lower virtual address and file offset than) the vma.
@@ -221,6 +244,9 @@ static bool can_vma_merge_before(struct vma_merge_struct *vmg) · 15 unmodified lines
221 return false;244 return false;
222 if (vmg_end_pgoff(vmg) != vma_start_pgoff(vmg->next))245 if (vmg_end_pgoff(vmg) != vma_start_pgoff(vmg->next))
223 return false;246 return false;
247 if (needs_adjacent_anon_pgoff(vmg) &&
248 vmg_end_anon_pgoff(vmg) != vma_start_anon_pgoff(vmg->next))
249 return false;
224 return true;250 return true;
225}251}
226 252
@@ -241,6 +267,9 @@ static bool can_vma_merge_after(struct vma_merge_struct *vmg) · 14 unmodified lines
241 return false;267 return false;
242 if (vma_end_pgoff(vmg->prev) != vmg_start_pgoff(vmg))268 if (vma_end_pgoff(vmg->prev) != vmg_start_pgoff(vmg))
243 return false;269 return false;
270 if (needs_adjacent_anon_pgoff(vmg) &&
271 vma_end_anon_pgoff(vmg->prev) != vmg_start_anon_pgoff(vmg))
272 return false;
244 return true;273 return true;
245}274}
246 275
@@ -812,7 +841,8 @@ static int commit_merge(struct vma_merge_struct *vmg) · 565 unmodified lines
812 */841 */
813 vma_adjust_trans_huge(vma, vmg->start, vmg->end,842 vma_adjust_trans_huge(vma, vmg->start, vmg->end,
814 vmg->__adjust_middle_start ? vmg->middle : NULL);843 vmg->__adjust_middle_start ? vmg->middle : NULL);
815 vma_set_range(vma, vmg->start, vmg->end, vmg_start_pgoff(vmg));844 vma_set_range(vma, vmg->start, vmg->end, vmg_start_pgoff(vmg),
845 vmg_start_anon_pgoff(vmg));
816 vmg_adjust_set_range(vmg);846 vmg_adjust_set_range(vmg);
817 vma_iter_store_overwrite(vmg->vmi, vmg->target);847 vma_iter_store_overwrite(vmg->vmi, vmg->target);
818 848
@@ -982,6 +1012,7 @@ static __must_check struct vm_area_struct *vma_merge_existing_range( · 163 unmodified lines
982 vmg->start = prev->vm_start;1012 vmg->start = prev->vm_start;
983 vmg->end = next->vm_end;1013 vmg->end = next->vm_end;
984 vmg->pgoff = vma_start_pgoff(prev);1014 vmg->pgoff = vma_start_pgoff(prev);
1015 vmg->anon_pgoff = vma_start_anon_pgoff(prev);
985 1016
986 /*1017 /*
987 * We already ensured anon_vma compatibility above, so now it's1018 * We already ensured anon_vma compatibility above, so now it's
@@ -1000,6 +1031,7 @@ static __must_check struct vm_area_struct *vma_merge_existing_range( · 12 unmodified lines
1000 */1031 */
1001 vmg->start = prev->vm_start;1032 vmg->start = prev->vm_start;
1002 vmg->pgoff = vma_start_pgoff(prev);1033 vmg->pgoff = vma_start_pgoff(prev);
1034 vmg->anon_pgoff = vma_start_anon_pgoff(prev);
1003 1035
1004 if (!vmg->__remove_middle)1036 if (!vmg->__remove_middle)
1005 vmg->__adjust_middle_start = true;1037 vmg->__adjust_middle_start = true;
@@ -1022,12 +1054,14 @@ static __must_check struct vm_area_struct *vma_merge_existing_range( · 16 unmodified lines
1022 if (vmg->__remove_middle) {1054 if (vmg->__remove_middle) {
1023 vmg->end = next->vm_end;1055 vmg->end = next->vm_end;
1024 vmg->pgoff = vma_start_pgoff(next) - pglen;1056 vmg->pgoff = vma_start_pgoff(next) - pglen;
1057 vmg->anon_pgoff = vma_start_anon_pgoff(next) - pglen;
1025 } else {1058 } else {
1026 /* We shrink middle and expand next. */1059 /* We shrink middle and expand next. */
1027 vmg->__adjust_next_start = true;1060 vmg->__adjust_next_start = true;
1028 vmg->start = middle->vm_start;1061 vmg->start = middle->vm_start;
1029 vmg->end = start;1062 vmg->end = start;
1030 vmg->pgoff = vma_start_pgoff(middle);1063 vmg->pgoff = vma_start_pgoff(middle);
1064 vmg->anon_pgoff = vma_start_anon_pgoff(middle);
1031 }1065 }
1032 1066
1033 err = dup_anon_vma(next, middle, &anon_dup);1067 err = dup_anon_vma(next, middle, &anon_dup);
@@ -1137,6 +1171,7 @@ struct vm_area_struct *vma_merge_new_range(struct vma_merge_struct *vmg) · 103 unmodified lines
1137 vmg->start = prev->vm_start;1171 vmg->start = prev->vm_start;
1138 vmg->target = prev;1172 vmg->target = prev;
1139 vmg->pgoff = vma_start_pgoff(prev);1173 vmg->pgoff = vma_start_pgoff(prev);
1174 vmg->anon_pgoff = vma_start_anon_pgoff(prev);
1140 1175
1141 /*1176 /*
1142 * If this merge would result in removal of the next VMA but we1177 * If this merge would result in removal of the next VMA but we
@@ -1908,23 +1943,27 @@ static int vma_link(struct mm_struct *mm, struct vm_area_struct *vma) · 765 unmodified lines
1908 */1943 */
1909struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,1944struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
1910 unsigned long addr, unsigned long len, pgoff_t pgoff,1945 unsigned long addr, unsigned long len, pgoff_t pgoff,
1911 bool *need_rmap_locks)1946 pgoff_t anon_pgoff, bool *need_rmap_locks)
1912{1947{
1913 struct vm_area_struct *vma = *vmap;1948 struct vm_area_struct *vma = *vmap;
1914 unsigned long vma_start = vma->vm_start;1949 unsigned long old_vma_start = vma->vm_start;
1915 struct mm_struct *mm = vma->vm_mm;1950 struct mm_struct *mm = vma->vm_mm;
1916 struct vm_area_struct *new_vma;1951 struct vm_area_struct *new_vma;
1917 bool faulted_in_anon_vma = true;1952 bool can_self_merge = false;
1918 VMA_ITERATOR(vmi, mm, addr);1953 VMA_ITERATOR(vmi, mm, addr);
1919 VMG_VMA_STATE(vmg, &vmi, NULL, vma, addr, addr + len);1954 VMG_VMA_STATE(vmg, &vmi, NULL, vma, addr, addr + len);
1920 1955
1921 /*1956 /*
1922 * If anonymous vma has not yet been faulted, update new pgoff1957 * If a vma has not yet been faulted, update its anonymous pgoff to
1923 * to match new location, to increase its chance of merging.1958 * match the new location to increase its chance of merging.
1924 */1959 */
1925 if (unlikely(vma_is_anonymous(vma) && !vma->anon_vma)) {1960 if (!vma->anon_vma) {
1926 pgoff = addr >> PAGE_SHIFT;1961 anon_pgoff = addr >> PAGE_SHIFT;
1927 faulted_in_anon_vma = false;1962
1963 if (vma_is_anonymous(vma)) {
1964 pgoff = anon_pgoff;
1965 can_self_merge = true;
1966 }
1928 }1967 }
1929 1968
1930 /*1969 /*
@@ -1940,28 +1979,26 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, · 9 unmodified lines
1940 return NULL; /* should never get here */1979 return NULL; /* should never get here */
1941 1980
1942 vmg.pgoff = pgoff;1981 vmg.pgoff = pgoff;
1982 vmg.anon_pgoff = anon_pgoff;
1943 vmg.next = vma_iter_next_rewind(&vmi, NULL);1983 vmg.next = vma_iter_next_rewind(&vmi, NULL);
1944 new_vma = vma_merge_copied_range(&vmg);1984 new_vma = vma_merge_copied_range(&vmg);
1945 1985
1946 if (new_vma) {1986 if (new_vma) {
1947 /*1987 /* Self-merged and VMA replaced. */
1948 * Source vma may have been merged into new_vma1988 if (unlikely(new_vma->vm_start < old_vma_start &&
1949 */1989 new_vma->vm_end > old_vma_start)) {
1950 if (unlikely(vma_start >= new_vma->vm_start &&
1951 vma_start < new_vma->vm_end)) {
1952 /*1990 /*
1953 * The only way we can get a vma_merge with1991 * The only way a VMA can both self-merge and be
1954 * self during an mremap is if the vma hasn't1992 * replaced is if the remap places the new VMA
1955 * been faulted in yet and we were allowed to1993 * immediately prior to its old self ('next') and
1956 * reset the dst vma->vm_pgoff to the1994 * immediately after another VMA ('prev') causing the
1957 * destination address of the mremap to allow1995 * next to be removed and prev to be expanded to cover
1958 * the merge to happen. mremap must change the1996 * the entire range.
1959 * vm_pgoff linearity between src and dst vmas1997 *
1960 * (in turn preventing a vma_merge) to be1998 * This should only be possible if the anonymous page
1961 * safe. It is only safe to keep the vm_pgoff1999 * offset was updated, i.e. the VMA is unfaulted.
1962 * linear if there are no pages mapped yet.
1963 */2000 */
1964 VM_BUG_ON_VMA(faulted_in_anon_vma, new_vma);2001 VM_WARN_ON_ONCE_VMA(!can_self_merge, new_vma);
1965 *vmap = vma = new_vma;2002 *vmap = vma = new_vma;
1966 }2003 }
1967 *need_rmap_locks =2004 *need_rmap_locks =
@@ -1970,7 +2007,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, · 2 unmodified lines
1970 new_vma = vm_area_dup(vma);2007 new_vma = vm_area_dup(vma);
1971 if (!new_vma)2008 if (!new_vma)
1972 goto out;2009 goto out;
1973 vma_set_range(new_vma, addr, addr + len, pgoff);2010 vma_set_range(new_vma, addr, addr + len, pgoff, anon_pgoff);
1974 if (vma_dup_policy(vma, new_vma))2011 if (vma_dup_policy(vma, new_vma))
1975 goto out_free_vma;2012 goto out_free_vma;
1976 if (anon_vma_clone(new_vma, vma, VMA_OP_REMAP))2013 if (anon_vma_clone(new_vma, vma, VMA_OP_REMAP))
@@ -2036,7 +2073,12 @@ static int anon_vma_compatible(struct vm_area_struct *a, struct vm_area_struct * · 59 unmodified lines
2036 if (!vma_flags_empty(&diff))2073 if (!vma_flags_empty(&diff))
2037 return false;2074 return false;
2038 /* Page offset must align. */2075 /* Page offset must align. */
2039 return vma_end_pgoff(a) == vma_start_pgoff(b);2076 if (vma_end_pgoff(a) != vma_start_pgoff(b))
2077 return false;
2078 /* Only reached from anon path, so either MAP_PRIVATE file or anon. */
2079 if (vma_end_anon_pgoff(a) != vma_start_anon_pgoff(b))
2080 return false;
2081 return true;
2040}2082}
2041 2083
2042/*2084/*
@@ -2612,7 +2654,7 @@ static int __mmap_new_vma(struct mmap_state *map, struct vm_area_struct **vmap, · 569 unmodified lines
2612 if (is_anon)2654 if (is_anon)
2613 vma_set_anonymous(vma);2655 vma_set_anonymous(vma);
2614 2656
2615 vma_set_range(vma, map->addr, map->end, map->pgoff);2657 vma_set_range(vma, map->addr, map->end, map->pgoff, map->anon_pgoff);
2616 vma->flags = map->vma_flags;2658 vma->flags = map->vma_flags;
2617 vma->vm_page_prot = map->page_prot;2659 vma->vm_page_prot = map->page_prot;
2618 2660
@@ -2801,7 +2843,8 @@ static unsigned long __mmap_region(struct file *file, unsigned long addr, · 182 unmodified lines
2801 struct vm_area_struct *vma = NULL;2843 struct vm_area_struct *vma = NULL;
2802 bool have_mmap_prepare = file && file->f_op->mmap_prepare;2844 bool have_mmap_prepare = file && file->f_op->mmap_prepare;
2803 VMA_ITERATOR(vmi, mm, addr);2845 VMA_ITERATOR(vmi, mm, addr);
2804 MMAP_STATE(map, mm, &vmi, addr, len, pgoff, vma_flags, file);2846 const pgoff_t anon_pgoff = addr >> PAGE_SHIFT;
2847 MMAP_STATE(map, mm, &vmi, addr, len, pgoff, anon_pgoff, vma_flags, file);
2805 struct vm_area_desc desc = {2848 struct vm_area_desc desc = {
2806 .mm = mm,2849 .mm = mm,
2807 .file = file,2850 .file = file,
@@ -2946,6 +2989,7 @@ int do_brk_flags(struct vma_iterator *vmi, struct vm_area_struct *vma, · 138 unmodified lines
2946 unsigned long addr, unsigned long len, vma_flags_t vma_flags)2989 unsigned long addr, unsigned long len, vma_flags_t vma_flags)
2947{2990{
2948 struct mm_struct *mm = current->mm;2991 struct mm_struct *mm = current->mm;
2992 const pgoff_t pgoff = addr >> PAGE_SHIFT;
2949 2993
2950 /*2994 /*
2951 * Check against address space limits by the changed size2995 * Check against address space limits by the changed size
@@ -2970,7 +3014,7 @@ int do_brk_flags(struct vma_iterator *vmi, struct vm_area_struct *vma, · 18 unmodified lines
2970 * occur after forking, so the expand will only happen on new VMAs.3014 * occur after forking, so the expand will only happen on new VMAs.
2971 */3015 */
2972 if (vma && vma->vm_end == addr) {3016 if (vma && vma->vm_end == addr) {
2973 VMG_STATE(vmg, mm, vmi, addr, addr + len, vma_flags, PHYS_PFN(addr));3017 VMG_STATE(vmg, mm, vmi, addr, addr + len, vma_flags, pgoff, pgoff);
2974 3018
2975 vmg.prev = vma;3019 vmg.prev = vma;
2976 /* vmi is positioned at prev, which this mode expects. */3020 /* vmi is positioned at prev, which this mode expects. */
@@ -2990,7 +3034,7 @@ int do_brk_flags(struct vma_iterator *vmi, struct vm_area_struct *vma, · 13 unmodified lines
2990 goto unacct_fail;3034 goto unacct_fail;
2991 3035
2992 vma_set_anonymous(vma);3036 vma_set_anonymous(vma);
2993 vma_set_range(vma, addr, addr + len, addr >> PAGE_SHIFT);3037 vma_set_range(vma, addr, addr + len, pgoff, pgoff);
2994 vma->flags = vma_flags;3038 vma->flags = vma_flags;
2995 vma->vm_page_prot = vm_get_page_prot(vma_flags_to_legacy(vma_flags));3039 vma->vm_page_prot = vm_get_page_prot(vma_flags_to_legacy(vma_flags));
2996 vma_start_write(vma);3040 vma_start_write(vma);
@@ -3382,6 +3426,7 @@ int insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma) · 385 unmodified lines
3382 WARN_ON_ONCE(vma->anon_vma);3426 WARN_ON_ONCE(vma->anon_vma);
3383 vma_set_pgoff(vma, vma->vm_start >> PAGE_SHIFT);3427 vma_set_pgoff(vma, vma->vm_start >> PAGE_SHIFT);
3384 }3428 }
3429 vma_set_anon_pgoff(vma, vma->vm_start >> PAGE_SHIFT);
3385 3430
3386 if (vma_link(mm, vma)) {3431 if (vma_link(mm, vma)) {
3387 if (vma_test(vma, VMA_ACCOUNT_BIT))3432 if (vma_test(vma, VMA_ACCOUNT_BIT))
@@ -3437,7 +3482,7 @@ struct vm_area_struct *__install_special_mapping( · 49 unmodified lines
3437 3482
3438 vma->vm_ops = ops;3483 vma->vm_ops = ops;
3439 vma->vm_private_data = priv;3484 vma->vm_private_data = priv;
3440 vma_set_range(vma, addr, addr + len, 0);3485 vma_set_range(vma, addr, addr + len, 0, addr >> PAGE_SHIFT);
3441 3486
3442 ret = insert_vm_struct(mm, vma);3487 ret = insert_vm_struct(mm, vma);
3443 if (ret)3488 if (ret)
mm/vma.h+59−30
@@ -104,6 +104,7 @@ struct vma_merge_struct { · 103 unmodified lines
104 unsigned long start;104 unsigned long start;
105 unsigned long end;105 unsigned long end;
106 pgoff_t pgoff;106 pgoff_t pgoff;
107 pgoff_t anon_pgoff;
107 108
108 union {109 union {
109 /* Temporary while VMA flags are being converted. */110 /* Temporary while VMA flags are being converted. */
@@ -237,11 +238,6 @@ static inline bool vmg_nomem(struct vma_merge_struct *vmg) · 127 unmodified lines
237 return vmg->state == VMA_MERGE_ERROR_NOMEM;238 return vmg->state == VMA_MERGE_ERROR_NOMEM;
238}239}
239 240
240static inline pgoff_t vmg_start_pgoff(const struct vma_merge_struct *vmg)
241{
242 return vmg->pgoff;
243}
244
245static inline pgoff_t vmg_pages(const struct vma_merge_struct *vmg)241static inline pgoff_t vmg_pages(const struct vma_merge_struct *vmg)
246{242{
247 const unsigned long size = vmg->end - vmg->start;243 const unsigned long size = vmg->end - vmg->start;
@@ -249,6 +245,11 @@ static inline pgoff_t vmg_pages(const struct vma_merge_struct *vmg) · 1 unmodified line
249 return size >> PAGE_SHIFT;245 return size >> PAGE_SHIFT;
250}246}
251 247
248static inline pgoff_t vmg_start_pgoff(const struct vma_merge_struct *vmg)
249{
250 return vmg->pgoff;
251}
252
252static inline pgoff_t vmg_end_pgoff(const struct vma_merge_struct *vmg)253static inline pgoff_t vmg_end_pgoff(const struct vma_merge_struct *vmg)
253{254{
254 return vmg_start_pgoff(vmg) + vmg_pages(vmg);255 return vmg_start_pgoff(vmg) + vmg_pages(vmg);
@@ -283,48 +284,76 @@ static inline void vma_set_pgoff(struct vm_area_struct *vma, pgoff_t pgoff) · 28 unmodified lines
283 vma->vm_pgoff = pgoff;284 vma->vm_pgoff = pgoff;
284}285}
285 286
287static inline pgoff_t vmg_start_anon_pgoff(const struct vma_merge_struct *vmg)
288{
289 return vmg->anon_pgoff;
290}
291
292static inline pgoff_t vmg_end_anon_pgoff(const struct vma_merge_struct *vmg)
293{
294 return vmg_start_anon_pgoff(vmg) + vmg_pages(vmg);
295}
296
297static inline void __vma_set_anon_pgoff(struct vm_area_struct *vma, pgoff_t pgoff)
298{
299#ifdef CONFIG_64BIT
300 vma->__vm_anon_pgoff_hi = pgoff >> 32;
301#endif
302 vma->__vm_anon_pgoff_lo = pgoff & GENMASK(31, 0);
303}
304
305static inline void vma_set_anon_pgoff(struct vm_area_struct *vma, pgoff_t pgoff)
306{
307 vma_assert_can_modify(vma);
308 __vma_set_anon_pgoff(vma, pgoff);
309}
310
286static inline void vma_add_pgoff(struct vm_area_struct *vma, pgoff_t delta)311static inline void vma_add_pgoff(struct vm_area_struct *vma, pgoff_t delta)
287{312{
288 vma_assert_can_modify(vma);313 vma_assert_can_modify(vma);
289 vma_set_pgoff(vma, vma_start_pgoff(vma) + delta);314 vma_set_pgoff(vma, vma_start_pgoff(vma) + delta);
315 vma_set_anon_pgoff(vma, vma_start_anon_pgoff(vma) + delta);
290}316}
291 317
292static inline void vma_sub_pgoff(struct vm_area_struct *vma, pgoff_t delta)318static inline void vma_sub_pgoff(struct vm_area_struct *vma, pgoff_t delta)
293{319{
294 vma_assert_can_modify(vma);320 vma_assert_can_modify(vma);
295 vma_set_pgoff(vma, vma_start_pgoff(vma) - delta);321 vma_set_pgoff(vma, vma_start_pgoff(vma) - delta);
296}322 vma_set_anon_pgoff(vma, vma_start_anon_pgoff(vma) - delta);
323}
324
325#define VMG_STATE(name, mm_, vmi_, start_, end_, vma_flags_, pgoff_, anon_pgoff_) \
326 struct vma_merge_struct name = { \
327 .mm = mm_, \
328 .vmi = vmi_, \
329 .start = start_, \
330 .end = end_, \
331 .vma_flags = vma_flags_, \
332 .pgoff = pgoff_, \
333 .anon_pgoff = anon_pgoff_, \
334 .state = VMA_MERGE_START, \
335 }
297 336
298#define VMG_STATE(name, mm_, vmi_, start_, end_, vma_flags_, pgoff_) \337#define VMG_VMA_STATE(name, vmi_, prev_, vma_, start_, end_) \
299 struct vma_merge_struct name = { \338 struct vma_merge_struct name = { \
300 .mm = mm_, \339 .mm = vma_->vm_mm, \
301 .vmi = vmi_, \340 .vmi = vmi_, \
341 .prev = prev_, \
342 .middle = vma_, \
343 .next = NULL, \
302 .start = start_, \344 .start = start_, \
303 .end = end_, \345 .end = end_, \
304 .vma_flags = vma_flags_, \346 .vm_flags = vma_->vm_flags, \
305 .pgoff = pgoff_, \347 .pgoff = linear_page_index(vma_, start_), \
348 .anon_pgoff = __linear_anon_page_index(vma_, start_), \
349 .file = vma_->vm_file, \
350 .anon_vma = vma_->anon_vma, \
351 .policy = vma_policy(vma_), \
352 .uffd_ctx = vma_->vm_userfaultfd_ctx, \
353 .anon_name = anon_vma_name(vma_), \
306 .state = VMA_MERGE_START, \354 .state = VMA_MERGE_START, \
307 }355 }
308 356
309#define VMG_VMA_STATE(name, vmi_, prev_, vma_, start_, end_) \
310 struct vma_merge_struct name = { \
311 .mm = vma_->vm_mm, \
312 .vmi = vmi_, \
313 .prev = prev_, \
314 .middle = vma_, \
315 .next = NULL, \
316 .start = start_, \
317 .end = end_, \
318 .vm_flags = vma_->vm_flags, \
319 .pgoff = linear_page_index(vma_, start_), \
320 .file = vma_->vm_file, \
321 .anon_vma = vma_->anon_vma, \
322 .policy = vma_policy(vma_), \
323 .uffd_ctx = vma_->vm_userfaultfd_ctx, \
324 .anon_name = anon_vma_name(vma_), \
325 .state = VMA_MERGE_START, \
326 }
327
328#ifdef CONFIG_DEBUG_VM_MAPLE_TREE357#ifdef CONFIG_DEBUG_VM_MAPLE_TREE
329void validate_mm(struct mm_struct *mm);358void validate_mm(struct mm_struct *mm);
330#else359#else
@@ -506,7 +535,7 @@ void unlink_file_vma_batch_add(struct unlink_vma_file_batch *vb, · 175 unmodified lines
506 535
507struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,536struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
508 unsigned long addr, unsigned long len, pgoff_t pgoff,537 unsigned long addr, unsigned long len, pgoff_t pgoff,
509 bool *need_rmap_locks);538 pgoff_t anon_pgoff, bool *need_rmap_locks);
510 539
511struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *vma);540struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *vma);
512 541
mm/vma_exec.c+1−1
@@ -41,7 +41,7 @@ int relocate_vma_down(struct vm_area_struct *vma, unsigned long shift) · 40 unmodified lines
41 unsigned long new_end = old_end - shift;41 unsigned long new_end = old_end - shift;
42 VMA_ITERATOR(vmi, mm, new_start);42 VMA_ITERATOR(vmi, mm, new_start);
43 VMG_STATE(vmg, mm, &vmi, new_start, old_end, EMPTY_VMA_FLAGS,43 VMG_STATE(vmg, mm, &vmi, new_start, old_end, EMPTY_VMA_FLAGS,
44 vma_start_pgoff(vma));44 vma_start_pgoff(vma), vma_start_anon_pgoff(vma));
45 struct vm_area_struct *next;45 struct vm_area_struct *next;
46 struct mmu_gather tlb;46 struct mmu_gather tlb;
47 PAGETABLE_MOVE(pmc, vma, vma, old_start, new_start, length);47 PAGETABLE_MOVE(pmc, vma, vma, old_start, new_start, length);
mm/vma_init.c+1−0
@@ -51,6 +51,7 @@ static void vm_area_init_from(const struct vm_area_struct *src, · 50 unmodified lines
51 dest->vm_end = src->vm_end;51 dest->vm_end = src->vm_end;
52 dest->anon_vma = src->anon_vma;52 dest->anon_vma = src->anon_vma;
53 dest->vm_pgoff = vma_start_pgoff(src);53 dest->vm_pgoff = vma_start_pgoff(src);
54 __vma_set_anon_pgoff(dest, vma_start_anon_pgoff(src));
54 dest->vm_file = src->vm_file;55 dest->vm_file = src->vm_file;
55 dest->vm_private_data = src->vm_private_data;56 dest->vm_private_data = src->vm_private_data;
56 vm_flags_init(dest, src->vm_flags);57 vm_flags_init(dest, src->vm_flags);
mm/vmalloc.c+34−37
@@ -1840,8 +1840,10 @@ va_alloc(struct vmap_area *va, · 1839 unmodified lines
1840 1840
1841 /* Update the free vmap_area. */1841 /* Update the free vmap_area. */
1842 ret = va_clip(root, head, va, nva_start_addr, size);1842 ret = va_clip(root, head, va, nva_start_addr, size);
1843 if (WARN_ON_ONCE(ret))1843 if (ret) {
1844 WARN_ON_ONCE(ret != -ENOMEM);
1844 return ret;1845 return ret;
1846 }
1845 1847
1846 return nva_start_addr;1848 return nva_start_addr;
1847}1849}
@@ -1914,12 +1916,9 @@ preload_this_cpu_lock(spinlock_t *lock, gfp_t gfp_mask, int node) · 66 unmodified lines
1914 1916
1915 /*1917 /*
1916 * Preload this CPU with one extra vmap_area object. It is used1918 * Preload this CPU with one extra vmap_area object. It is used
1917 * when fit type of free area is NE_FIT_TYPE. It guarantees that1919 * when fit type of free area is NE_FIT_TYPE. It is best effort
1918 * a CPU that does an allocation is preloaded.1920 * pre-loading. If it fails va_clip() may return -ENOMEM from its
1919 *1921 * GFP_NOWAIT fallback.
1920 * We do it in non-atomic context, thus it allows us to use more
1921 * permissive allocation masks to be more stable under low memory
1922 * condition and high memory pressure.
1923 */1922 */
1924 if (!this_cpu_read(ne_fit_preload_node))1923 if (!this_cpu_read(ne_fit_preload_node))
1925 va = kmem_cache_alloc_node(vmap_area_cachep, gfp_mask, node);1924 va = kmem_cache_alloc_node(vmap_area_cachep, gfp_mask, node);
@@ -3361,7 +3360,7 @@ struct vm_struct *remove_vm_area(const void *addr) · 1435 unmodified lines
3361static inline void set_area_direct_map(const struct vm_struct *area,3360static inline void set_area_direct_map(const struct vm_struct *area,
3362 int (*set_direct_map)(struct page *page))3361 int (*set_direct_map)(struct page *page))
3363{3362{
3364 int i;3363 unsigned long i;
3365 3364
3366 /* HUGE_VMALLOC passes small pages to set_direct_map */3365 /* HUGE_VMALLOC passes small pages to set_direct_map */
3367 for (i = 0; i < area->nr_pages; i++)3366 for (i = 0; i < area->nr_pages; i++)
@@ -3377,7 +3376,7 @@ static void vm_reset_perms(struct vm_struct *area) · 9 unmodified lines
3377 unsigned long start = ULONG_MAX, end = 0;3376 unsigned long start = ULONG_MAX, end = 0;
3378 unsigned int page_order = vm_area_page_order(area);3377 unsigned int page_order = vm_area_page_order(area);
3379 int flush_dmap = 0;3378 int flush_dmap = 0;
3380 int i;3379 unsigned long i;
3381 3380
3382 /*3381 /*
3383 * Find the start and end range of the direct mappings to make sure that3382 * Find the start and end range of the direct mappings to make sure that
@@ -3450,10 +3449,10 @@ void vfree_atomic(const void *addr) · 66 unmodified lines
3450 * Caller is responsible for unmapping (vunmap_range) and KASAN3449 * Caller is responsible for unmapping (vunmap_range) and KASAN
3451 * poisoning before calling this.3450 * poisoning before calling this.
3452 */3451 */
3453static void vm_area_free_pages(struct vm_struct *vm, unsigned int start_idx,3452static void vm_area_free_pages(struct vm_struct *vm, unsigned long start_idx,
3454 unsigned int end_idx)3453 unsigned long end_idx)
3455{3454{
3456 unsigned int i;3455 unsigned long i;
3457 3456
3458 if (!(vm->flags & VM_MAP_PUT_PAGES)) {3457 if (!(vm->flags & VM_MAP_PUT_PAGES)) {
3459 for (i = start_idx; i < end_idx; i++)3458 for (i = start_idx; i < end_idx; i++)
@@ -3665,12 +3664,12 @@ static inline gfp_t vmalloc_gfp_adjust(gfp_t flags, const bool large) · 205 unmodified lines
3665 return flags;3664 return flags;
3666}3665}
3667 3666
3668static inline unsigned int3667static inline unsigned long
3669vm_area_alloc_pages(gfp_t gfp, int nid,3668vm_area_alloc_pages(gfp_t gfp, int nid,
3670 unsigned int order, unsigned int nr_pages, struct page **pages)3669 unsigned int order, unsigned long nr_pages, struct page **pages)
3671{3670{
3672 unsigned int nr_allocated = 0;3671 unsigned long nr_allocated = 0;
3673 unsigned int nr_remaining = nr_pages;3672 unsigned long nr_remaining = nr_pages;
3674 unsigned int max_attempt_order = MAX_PAGE_ORDER;3673 unsigned int max_attempt_order = MAX_PAGE_ORDER;
3675 struct page *page;3674 struct page *page;
3676 int i;3675 int i;
@@ -3718,7 +3717,7 @@ vm_area_alloc_pages(gfp_t gfp, int nid, · 41 unmodified lines
3718 if (!order) {3717 if (!order) {
3719 while (nr_allocated < nr_pages) {3718 while (nr_allocated < nr_pages) {
3720 unsigned int nr, nr_pages_request;3719 unsigned int nr, nr_pages_request;
3721 int i;3720 unsigned long i;
3722 3721
3723 /*3722 /*
3724 * A maximum allowed request is hard-coded and is 1003723 * A maximum allowed request is hard-coded and is 100
@@ -3726,7 +3725,7 @@ vm_area_alloc_pages(gfp_t gfp, int nid, · 1 unmodified line
3726 * long preemption off scenario in the bulk-allocator3725 * long preemption off scenario in the bulk-allocator
3727 * so the range is [1:100].3726 * so the range is [1:100].
3728 */3727 */
3729 nr_pages_request = min(100U, nr_pages - nr_allocated);3728 nr_pages_request = min(100UL, nr_pages - nr_allocated);
3730 3729
3731 /* memory allocation should consider mempolicy, we can't3730 /* memory allocation should consider mempolicy, we can't
3732 * wrongly use nearest node when nid == NUMA_NO_NODE,3731 * wrongly use nearest node when nid == NUMA_NO_NODE,
@@ -3872,12 +3871,12 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, · 139 unmodified lines
3872 unsigned long addr = (unsigned long)area->addr;3871 unsigned long addr = (unsigned long)area->addr;
3873 unsigned long size = get_vm_area_size(area);3872 unsigned long size = get_vm_area_size(area);
3874 unsigned long array_size;3873 unsigned long array_size;
3875 unsigned int nr_small_pages = size >> PAGE_SHIFT;3874 unsigned long nr_small_pages = size >> PAGE_SHIFT;
3876 unsigned int page_order;3875 unsigned int page_order;
3877 unsigned int flags;3876 unsigned int flags;
3878 int ret;3877 int ret;
3879 3878
3880 array_size = (unsigned long)nr_small_pages * sizeof(struct page *);3879 array_size = nr_small_pages * sizeof(struct page *);
3881 3880
3882 /* __GFP_NOFAIL and "noblock" flags are mutually exclusive. */3881 /* __GFP_NOFAIL and "noblock" flags are mutually exclusive. */
3883 if (!gfpflags_allow_blocking(gfp_mask))3882 if (!gfpflags_allow_blocking(gfp_mask))
@@ -4375,7 +4374,7 @@ void *vrealloc_node_align_noprof(const void *p, size_t size, unsigned long align · 491 unmodified lines
4375 }4374 }
4376 4375
4377 if (size <= old_size) {4376 if (size <= old_size) {
4378 unsigned int new_nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;4377 unsigned long new_nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
4379 4378
4380 /* Zero out "freed" memory, potentially for future realloc. */4379 /* Zero out "freed" memory, potentially for future realloc. */
4381 if (want_init_on_free() || want_init_on_alloc(flags))4380 if (want_init_on_free() || want_init_on_alloc(flags))
@@ -4404,7 +4403,7 @@ void *vrealloc_node_align_noprof(const void *p, size_t size, unsigned long align · 22 unmodified lines
4404 !(vm->flags & (VM_FLUSH_RESET_PERMS | VM_USERMAP)) &&4403 !(vm->flags & (VM_FLUSH_RESET_PERMS | VM_USERMAP)) &&
4405 gfp_has_io_fs(flags)) {4404 gfp_has_io_fs(flags)) {
4406 unsigned long addr = (unsigned long)kasan_reset_tag(p);4405 unsigned long addr = (unsigned long)kasan_reset_tag(p);
4407 unsigned int old_nr_pages = vm->nr_pages;4406 unsigned long old_nr_pages = vm->nr_pages;
4408 4407
4409 /*4408 /*
4410 * Use the node lock to synchronize with concurrent4409 * Use the node lock to synchronize with concurrent
@@ -4417,16 +4416,13 @@ void *vrealloc_node_align_noprof(const void *p, size_t size, unsigned long align · 6 unmodified lines
4417 spin_unlock(&vn->busy.lock);4416 spin_unlock(&vn->busy.lock);
4418 4417
4419 /* Notify kmemleak of the reduced allocation size before unmapping. */4418 /* Notify kmemleak of the reduced allocation size before unmapping. */
4420 kmemleak_free_part(4419 kmemleak_free_part((void *)addr +
4421 (void *)addr + ((unsigned long)new_nr_pages4420 (new_nr_pages << PAGE_SHIFT),
4422 << PAGE_SHIFT),4421 (old_nr_pages - new_nr_pages)
4423 (unsigned long)(old_nr_pages - new_nr_pages)4422 << PAGE_SHIFT);
4424 << PAGE_SHIFT);
4425 4423
4426 vunmap_range(addr + ((unsigned long)new_nr_pages4424 vunmap_range(addr + (new_nr_pages << PAGE_SHIFT),
4427 << PAGE_SHIFT),4425 addr + (old_nr_pages << PAGE_SHIFT));
4428 addr + ((unsigned long)old_nr_pages
4429 << PAGE_SHIFT));
4430 4426
4431 vm_area_free_pages(vm, new_nr_pages, old_nr_pages);4427 vm_area_free_pages(vm, new_nr_pages, old_nr_pages);
4432 }4428 }
@@ -5250,7 +5246,7 @@ bool vmalloc_dump_obj(void *object) · 817 unmodified lines
5250 struct vmap_area *va;5246 struct vmap_area *va;
5251 struct vmap_node *vn;5247 struct vmap_node *vn;
5252 unsigned long addr;5248 unsigned long addr;
5253 unsigned int nr_pages;5249 unsigned long nr_pages;
5254 5250
5255 addr = PAGE_ALIGN((unsigned long) object);5251 addr = PAGE_ALIGN((unsigned long) object);
5256 vn = addr_to_node(addr);5252 vn = addr_to_node(addr);
@@ -5270,7 +5266,7 @@ bool vmalloc_dump_obj(void *object) · 13 unmodified lines
5270 nr_pages = vm->nr_pages;5266 nr_pages = vm->nr_pages;
5271 spin_unlock(&vn->busy.lock);5267 spin_unlock(&vn->busy.lock);
5272 5268
5273 pr_cont(" %u-page vmalloc region starting at %#lx allocated at %pS\n",5269 pr_cont(" %lu-page vmalloc region starting at %#lx allocated at %pS\n",
5274 nr_pages, addr, caller);5270 nr_pages, addr, caller);
5275 5271
5276 return true;5272 return true;
@@ -5288,16 +5284,17 @@ bool vmalloc_dump_obj(void *object) · 11 unmodified lines
5288static void show_numa_info(struct seq_file *m, struct vm_struct *v,5284static void show_numa_info(struct seq_file *m, struct vm_struct *v,
5289 unsigned int *counters)5285 unsigned int *counters)
5290{5286{
5291 unsigned int nr;
5292 unsigned int step = 1U << vm_area_page_order(v);5287 unsigned int step = 1U << vm_area_page_order(v);
5288 unsigned long i;
5289 unsigned int nr;
5293 5290
5294 if (!counters)5291 if (!counters)
5295 return;5292 return;
5296 5293
5297 memset(counters, 0, nr_node_ids * sizeof(unsigned int));5294 memset(counters, 0, nr_node_ids * sizeof(unsigned int));
5298 5295
5299 for (nr = 0; nr < v->nr_pages; nr += step)5296 for (i = 0; i < v->nr_pages; i += step)
5300 counters[page_to_nid(v->pages[nr])] += step;5297 counters[page_to_nid(v->pages[i])] += step;
5301 for_each_node_state(nr, N_HIGH_MEMORY)5298 for_each_node_state(nr, N_HIGH_MEMORY)
5302 if (counters[nr])5299 if (counters[nr])
5303 seq_printf(m, " N%u=%u", nr, counters[nr]);5300 seq_printf(m, " N%u=%u", nr, counters[nr]);
@@ -5355,7 +5352,7 @@ static int vmalloc_info_show(struct seq_file *m, void *p) · 51 unmodified lines
5355 seq_printf(m, " %pS", v->caller);5352 seq_printf(m, " %pS", v->caller);
5356 5353
5357 if (v->nr_pages)5354 if (v->nr_pages)
5358 seq_printf(m, " pages=%d", v->nr_pages);5355 seq_printf(m, " pages=%lu", v->nr_pages);
5359 5356
5360 if (v->phys_addr)5357 if (v->phys_addr)
5361 seq_printf(m, " phys=%pa", &v->phys_addr);5358 seq_printf(m, " phys=%pa", &v->phys_addr);
mm/vmalloc.h+2−0
@@ -5,6 +5,8 @@ · 4 unmodified lines
5#ifndef __MM_VMALLOC_H5#ifndef __MM_VMALLOC_H
6#define __MM_VMALLOC_H6#define __MM_VMALLOC_H
7 7
8#include <linux/vmalloc.h>
9
8#ifdef CONFIG_MMU10#ifdef CONFIG_MMU
9void __init vmalloc_init(void);11void __init vmalloc_init(void);
10int __must_check vmap_pages_range_noflush(unsigned long addr, unsigned long end,12int __must_check vmap_pages_range_noflush(unsigned long addr, unsigned long end,
mm/vmscan.c+151−79
@@ -58,6 +58,7 @@ · 57 unmodified lines
58#include <linux/random.h>58#include <linux/random.h>
59#include <linux/mmu_notifier.h>59#include <linux/mmu_notifier.h>
60#include <linux/parser.h>60#include <linux/parser.h>
61#include <linux/swap_ops.h>
61 62
62#include <asm/tlbflush.h>63#include <asm/tlbflush.h>
63#include <asm/div64.h>64#include <asm/div64.h>
@@ -199,6 +200,13 @@ struct scan_control { · 135 unmodified lines
199 */200 */
200int vm_swappiness = 60;201int vm_swappiness = 60;
201 202
203static int sc_swappiness(struct scan_control *sc, struct mem_cgroup *memcg)
204{
205 if (sc->proactive && sc->proactive_swappiness)
206 return *sc->proactive_swappiness;
207 return mem_cgroup_swappiness(memcg);
208}
209
202#ifdef CONFIG_MEMCG210#ifdef CONFIG_MEMCG
203 211
204/* Returns true for reclaim through cgroup limits or cgroup interfaces. */212/* Returns true for reclaim through cgroup limits or cgroup interfaces. */
@@ -239,13 +247,6 @@ static bool writeback_throttling_sane(struct scan_control *sc) · 34 unmodified lines
239#endif247#endif
240 return false;248 return false;
241}249}
242
243static int sc_swappiness(struct scan_control *sc, struct mem_cgroup *memcg)
244{
245 if (sc->proactive && sc->proactive_swappiness)
246 return *sc->proactive_swappiness;
247 return mem_cgroup_swappiness(memcg);
248}
249#else250#else
250static bool cgroup_reclaim(struct scan_control *sc)251static bool cgroup_reclaim(struct scan_control *sc)
251{252{
@@ -261,12 +262,13 @@ static bool writeback_throttling_sane(struct scan_control *sc) · 9 unmodified lines
261{262{
262 return true;263 return true;
263}264}
265#endif
264 266
265static int sc_swappiness(struct scan_control *sc, struct mem_cgroup *memcg)267static inline bool is_exec_file_folio(const struct folio *folio,
268 const vma_flags_t *vma_flags)
266{269{
267 return READ_ONCE(vm_swappiness);270 return vma_flags_test(vma_flags, VMA_EXEC_BIT) && folio_is_file_lru(folio);
268}271}
269#endif
270 272
271static void set_task_reclaim_state(struct task_struct *task,273static void set_task_reclaim_state(struct task_struct *task,
272 struct reclaim_state *rs)274 struct reclaim_state *rs)
@@ -616,8 +618,8 @@ typedef enum { · 343 unmodified lines
616/*618/*
617 * pageout is called by shrink_folio_list() for each dirty folio.619 * pageout is called by shrink_folio_list() for each dirty folio.
618 */620 */
619static pageout_t pageout(struct folio *folio, struct address_space *mapping,621static pageout_t pageout(struct swap_io_ctx *ctx, struct address_space *mapping,
620 struct swap_iocb **plug, struct list_head *folio_list)622 struct folio *folio, struct list_head *folio_list)
621{623{
622 int res;624 int res;
623 625
@@ -653,9 +655,9 @@ static pageout_t pageout(struct folio *folio, struct address_space *mapping, · 29 unmodified lines
653 * the split out folios get added back to folio_list.655 * the split out folios get added back to folio_list.
654 */656 */
655 if (shmem_mapping(mapping))657 if (shmem_mapping(mapping))
656 res = shmem_writeout(folio, plug, folio_list);658 res = shmem_writeout(ctx, folio, folio_list);
657 else659 else
658 res = swap_writeout(folio, plug);660 res = swap_writeout(ctx, folio);
659 661
660 if (res < 0)662 if (res < 0)
661 handle_write_error(mapping, folio, res);663 handle_write_error(mapping, folio, res);
@@ -669,7 +671,7 @@ static pageout_t pageout(struct folio *folio, struct address_space *mapping, · 7 unmodified lines
669 folio_clear_reclaim(folio);671 folio_clear_reclaim(folio);
670 672
671 trace_mm_vmscan_write_folio(folio);673 trace_mm_vmscan_write_folio(folio);
672 node_stat_add_folio(folio, NR_VMSCAN_WRITE);674 lruvec_stat_mod_folio(folio, NR_VMSCAN_WRITE, folio_nr_pages(folio));
673 return PAGE_SUCCESS;675 return PAGE_SUCCESS;
674}676}
675 677
@@ -835,10 +837,16 @@ enum folio_references { · 159 unmodified lines
835 * with PG_active set. In contrast, the aging (page table walk) path uses837 * with PG_active set. In contrast, the aging (page table walk) path uses
836 * folio_update_gen().838 * folio_update_gen().
837 */839 */
838static bool lru_gen_set_refs(struct folio *folio)840static bool lru_gen_set_refs(struct folio *folio, const vma_flags_t *vma_flags)
839{841{
840 /* see the comment on LRU_REFS_FLAGS */842 /* see the comment on LRU_REFS_FLAGS */
841 if (!folio_test_referenced(folio) && !folio_test_workingset(folio)) {843 if (!folio_test_referenced(folio) && !folio_test_workingset(folio)) {
844 /* Activate file-backed executable folios after first usage. */
845 if (is_exec_file_folio(folio, vma_flags)) {
846 set_mask_bits(&folio->flags.f, LRU_REFS_FLAGS, BIT(PG_workingset));
847 return true;
848 }
849
842 set_mask_bits(&folio->flags.f, LRU_REFS_MASK, BIT(PG_referenced));850 set_mask_bits(&folio->flags.f, LRU_REFS_MASK, BIT(PG_referenced));
843 return false;851 return false;
844 }852 }
@@ -851,7 +859,7 @@ static bool lru_gen_set_refs(struct folio *folio) · 6 unmodified lines
851 return true;859 return true;
852}860}
853#else861#else
854static bool lru_gen_set_refs(struct folio *folio)862static bool lru_gen_set_refs(struct folio *folio, const vma_flags_t *vma_flags)
855{863{
856 return false;864 return false;
857}865}
@@ -861,16 +869,16 @@ static enum folio_references folio_check_references(struct folio *folio, · 3 unmodified lines
861 struct scan_control *sc)869 struct scan_control *sc)
862{870{
863 int referenced_ptes, referenced_folio;871 int referenced_ptes, referenced_folio;
864 vm_flags_t vm_flags;872 vma_flags_t vma_flags;
865 873
866 referenced_ptes = folio_referenced(folio, 1, sc->target_mem_cgroup,874 referenced_ptes = folio_referenced(folio, 1, sc->target_mem_cgroup,
867 &vm_flags);875 &vma_flags);
868 876
869 /*877 /*
870 * The supposedly reclaimable folio was found to be in a VM_LOCKED vma.878 * The supposedly reclaimable folio was found to be in a VM_LOCKED vma.
871 * Let the folio, now marked Mlocked, be moved to the unevictable list.879 * Let the folio, now marked Mlocked, be moved to the unevictable list.
872 */880 */
873 if (vm_flags & VM_LOCKED)881 if (vma_flags_test(&vma_flags, VMA_LOCKED_BIT))
874 return FOLIOREF_ACTIVATE;882 return FOLIOREF_ACTIVATE;
875 883
876 /*884 /*
@@ -886,7 +894,7 @@ static enum folio_references folio_check_references(struct folio *folio, · 9 unmodified lines
886 if (!referenced_ptes)894 if (!referenced_ptes)
887 return FOLIOREF_RECLAIM;895 return FOLIOREF_RECLAIM;
888 896
889 return lru_gen_set_refs(folio) ? FOLIOREF_ACTIVATE : FOLIOREF_KEEP;897 return lru_gen_set_refs(folio, &vma_flags) ? FOLIOREF_ACTIVATE : FOLIOREF_KEEP;
890 }898 }
891 899
892 referenced_folio = folio_test_clear_referenced(folio);900 referenced_folio = folio_test_clear_referenced(folio);
@@ -914,7 +922,7 @@ static enum folio_references folio_check_references(struct folio *folio, · 21 unmodified lines
914 /*922 /*
915 * Activate file-backed executable folios after first usage.923 * Activate file-backed executable folios after first usage.
916 */924 */
917 if ((vm_flags & VM_EXEC) && folio_is_file_lru(folio))925 if (is_exec_file_folio(folio, &vma_flags))
918 return FOLIOREF_ACTIVATE;926 return FOLIOREF_ACTIVATE;
919 927
920 return FOLIOREF_KEEP;928 return FOLIOREF_KEEP;
@@ -1033,16 +1041,15 @@ static bool may_enter_fs(struct folio *folio, gfp_t gfp_mask) · 112 unmodified lines
1033{1041{
1034 if (gfp_mask & __GFP_FS)1042 if (gfp_mask & __GFP_FS)
1035 return true;1043 return true;
1036 if (!folio_test_swapcache(folio) || !(gfp_mask & __GFP_IO))
1037 return false;
1038 /*1044 /*
1039 * We can "enter_fs" for swap-cache with only __GFP_IO1045 * We can "enter_fs" for swap-cache with only __GFP_IO unless backed by
1040 * providing this isn't SWP_FS_OPS.1046 * a swapfile that requires GFP_NOFS I/O.
1041 * ->flags can be updated non-atomically,
1042 * but that will never affect SWP_FS_OPS, so the data_race
1043 * is safe.
1044 */1047 */
1045 return !data_race(folio_swap_flags(folio) & SWP_FS_OPS);1048 if (folio_test_swapcache(folio) && (gfp_mask & __GFP_IO) &&
1049 !(__swap_entry_to_info(folio->swap)->ops->flags &
1050 SWAP_OPS_F_REQUIRE_NOFS))
1051 return true;
1052 return false;
1046}1053}
1047 1054
1048/*1055/*
@@ -1059,7 +1066,7 @@ static unsigned int shrink_folio_list(struct list_head *folio_list, · 10 unmodified lines
1059 unsigned int nr_reclaimed = 0, nr_demoted = 0;1066 unsigned int nr_reclaimed = 0, nr_demoted = 0;
1060 unsigned int pgactivate = 0;1067 unsigned int pgactivate = 0;
1061 bool do_demote_pass;1068 bool do_demote_pass;
1062 struct swap_iocb *plug = NULL;1069 struct swap_io_ctx ctx = {};
1063 1070
1064 folio_batch_init(&free_folios);1071 folio_batch_init(&free_folios);
1065 memset(stat, 0, sizeof(*stat));1072 memset(stat, 0, sizeof(*stat));
@@ -1387,7 +1394,7 @@ retry: · 321 unmodified lines
1387 * starts and then write it out here.1394 * starts and then write it out here.
1388 */1395 */
1389 try_to_unmap_flush_dirty();1396 try_to_unmap_flush_dirty();
1390 switch (pageout(folio, mapping, &plug, folio_list)) {1397 switch (pageout(&ctx, mapping, folio, folio_list)) {
1391 case PAGE_KEEP:1398 case PAGE_KEEP:
1392 goto keep_locked;1399 goto keep_locked;
1393 case PAGE_ACTIVATE:1400 case PAGE_ACTIVATE:
@@ -1406,8 +1413,6 @@ retry: · 12 unmodified lines
1406 sc->nr_scanned -= (nr_pages - 1);1413 sc->nr_scanned -= (nr_pages - 1);
1407 nr_pages = 1;1414 nr_pages = 1;
1408 }1415 }
1409 stat->nr_pageout += nr_pages;
1410
1411 if (folio_test_writeback(folio))1416 if (folio_test_writeback(folio))
1412 goto keep;1417 goto keep;
1413 if (folio_test_dirty(folio))1418 if (folio_test_dirty(folio))
@@ -1577,8 +1582,7 @@ keep: · 163 unmodified lines
1577 list_splice(&ret_folios, folio_list);1582 list_splice(&ret_folios, folio_list);
1578 count_vm_events(PGACTIVATE, pgactivate);1583 count_vm_events(PGACTIVATE, pgactivate);
1579 1584
1580 if (plug)1585 swap_write_submit(&ctx);
1581 swap_write_unplug(plug);
1582 return nr_reclaimed;1586 return nr_reclaimed;
1583}1587}
1584 1588
@@ -2031,10 +2035,10 @@ static unsigned long shrink_inactive_list(unsigned long nr_to_scan, · 446 unmodified lines
2031 item = PGSTEAL_KSWAPD + reclaimer_offset(sc);2035 item = PGSTEAL_KSWAPD + reclaimer_offset(sc);
2032 mod_lruvec_state(lruvec, item, nr_reclaimed);2036 mod_lruvec_state(lruvec, item, nr_reclaimed);
2033 mod_lruvec_state(lruvec, PGSTEAL_ANON + file, nr_reclaimed);2037 mod_lruvec_state(lruvec, PGSTEAL_ANON + file, nr_reclaimed);
2038 if (nr_scanned > nr_reclaimed)
2039 mod_lruvec_state(lruvec, PGROTATE_ANON + file,
2040 nr_scanned - nr_reclaimed);
2034 2041
2035 lruvec_lock_irq(lruvec);
2036 lru_note_cost_unlock_irq(lruvec, file, stat.nr_pageout,
2037 nr_scanned - nr_reclaimed);
2038 handle_reclaim_writeback(nr_taken, pgdat, sc, &stat);2042 handle_reclaim_writeback(nr_taken, pgdat, sc, &stat);
2039 trace_mm_vmscan_lru_shrink_inactive(pgdat->node_id,2043 trace_mm_vmscan_lru_shrink_inactive(pgdat->node_id,
2040 nr_scanned, nr_reclaimed, &stat, sc->priority, file);2044 nr_scanned, nr_reclaimed, &stat, sc->priority, file);
@@ -2065,7 +2069,7 @@ static void shrink_active_list(unsigned long nr_to_scan, · 24 unmodified lines
2065{2069{
2066 unsigned long nr_taken;2070 unsigned long nr_taken;
2067 unsigned long nr_scanned;2071 unsigned long nr_scanned;
2068 vm_flags_t vm_flags;2072 vma_flags_t vma_flags;
2069 LIST_HEAD(l_hold); /* The folios which were snipped off */2073 LIST_HEAD(l_hold); /* The folios which were snipped off */
2070 LIST_HEAD(l_active);2074 LIST_HEAD(l_active);
2071 LIST_HEAD(l_inactive);2075 LIST_HEAD(l_inactive);
@@ -2109,7 +2113,7 @@ static void shrink_active_list(unsigned long nr_to_scan, · 37 unmodified lines
2109 2113
2110 /* Referenced or rmap lock contention: rotate */2114 /* Referenced or rmap lock contention: rotate */
2111 if (folio_referenced(folio, 0, sc->target_mem_cgroup,2115 if (folio_referenced(folio, 0, sc->target_mem_cgroup,
2112 &vm_flags) != 0) {2116 &vma_flags) != 0) {
2113 /*2117 /*
2114 * Identify referenced, file-backed active folios and2118 * Identify referenced, file-backed active folios and
2115 * give them one more trip around the active list. So2119 * give them one more trip around the active list. So
@@ -2119,7 +2123,7 @@ static void shrink_active_list(unsigned long nr_to_scan, · 3 unmodified lines
2119 * IO, plus JVM can create lots of anon VM_EXEC folios,2123 * IO, plus JVM can create lots of anon VM_EXEC folios,
2120 * so we ignore them here.2124 * so we ignore them here.
2121 */2125 */
2122 if ((vm_flags & VM_EXEC) && folio_is_file_lru(folio)) {2126 if (is_exec_file_folio(folio, &vma_flags)) {
2123 nr_rotated += folio_nr_pages(folio);2127 nr_rotated += folio_nr_pages(folio);
2124 list_add(&folio->lru, &l_active);2128 list_add(&folio->lru, &l_active);
2125 continue;2129 continue;
@@ -2140,9 +2144,9 @@ static void shrink_active_list(unsigned long nr_to_scan, · 14 unmodified lines
2140 count_vm_events(PGDEACTIVATE, nr_deactivate);2144 count_vm_events(PGDEACTIVATE, nr_deactivate);
2141 count_memcg_events(lruvec_memcg(lruvec), PGDEACTIVATE, nr_deactivate);2145 count_memcg_events(lruvec_memcg(lruvec), PGDEACTIVATE, nr_deactivate);
2142 mod_node_page_state(pgdat, NR_ISOLATED_ANON + file, -nr_taken);2146 mod_node_page_state(pgdat, NR_ISOLATED_ANON + file, -nr_taken);
2147 if (nr_rotated)
2148 mod_lruvec_state(lruvec, PGROTATE_ANON + file, nr_rotated);
2143 2149
2144 lruvec_lock_irq(lruvec);
2145 lru_note_cost_unlock_irq(lruvec, file, 0, nr_rotated);
2146 trace_mm_vmscan_lru_shrink_active(pgdat->node_id, nr_taken, nr_activate,2150 trace_mm_vmscan_lru_shrink_active(pgdat->node_id, nr_taken, nr_activate,
2147 nr_deactivate, nr_rotated, sc->priority, file);2151 nr_deactivate, nr_rotated, sc->priority, file);
2148}2152}
@@ -2275,8 +2279,10 @@ enum scan_balance { · 126 unmodified lines
2275 2279
2276static void prepare_scan_control(pg_data_t *pgdat, struct scan_control *sc)2280static void prepare_scan_control(pg_data_t *pgdat, struct scan_control *sc)
2277{2281{
2278 unsigned long file;2282 struct lru_cost *anon_cost, *file_cost;
2279 struct lruvec *target_lruvec;2283 struct lruvec *target_lruvec;
2284 unsigned long lrusize;
2285 unsigned long file;
2280 2286
2281 if (lru_gen_enabled() && !lru_gen_switching())2287 if (lru_gen_enabled() && !lru_gen_switching())
2282 return;2288 return;
@@ -2292,11 +2298,69 @@ static void prepare_scan_control(pg_data_t *pgdat, struct scan_control *sc) · 9 unmodified lines
2292 2298
2293 /*2299 /*
2294 * Determine the scan balance between anon and file LRUs.2300 * Determine the scan balance between anon and file LRUs.
2301 *
2302 * The cost model is based on rotations, refaults and
2303 * reclaim-driven writes (anon only) on each side.
2304 *
2305 * These event counters are monotonic, so each reclaim cycle
2306 * the delta since the last scan is extracted and incorporated
2307 * into a decaying average. This ensures currency, as workloads
2308 * change over time, and avoids overflow in the calculations.
2309 *
2310 * Use lruvec_page_state_monotonic() so unsigned subtraction
2311 * yields the correct delta across a signed-long wraparound of
2312 * the underlying counter (a real hazard on 32-bit that the
2313 * clamp in lruvec_page_state() would otherwise turn into a huge
2314 * spurious delta).
2295 */2315 */
2296 spin_lock_irq(&target_lruvec->lru_lock);2316 spin_lock(&target_lruvec->cost_lock);
2297 sc->anon_cost = target_lruvec->anon_cost;2317
2298 sc->file_cost = target_lruvec->file_cost;2318 for (int f = 0; f <= 1; f++) {
2299 spin_unlock_irq(&target_lruvec->lru_lock);2319 struct lru_cost *cost = &target_lruvec->cost[f];
2320 unsigned long rotated, io, nr_rotated, nr_io;
2321
2322 rotated = lruvec_page_state_monotonic(target_lruvec,
2323 PGROTATE_ANON + f);
2324 io = lruvec_page_state_monotonic(target_lruvec,
2325 WORKINGSET_RESTORE_BASE + f);
2326 if (f == WORKINGSET_ANON)
2327 io += lruvec_page_state_monotonic(target_lruvec,
2328 NR_VMSCAN_WRITE);
2329
2330 nr_rotated = rotated - cost->last_rotated;
2331 nr_io = io - cost->last_io;
2332
2333 /*
2334 * Reflect the relative cost of incurring IO and spending
2335 * CPU time on rotations. This doesn't attempt to make a
2336 * precise comparison, it just says: if reloads are about
2337 * comparable between the LRU lists, or rotations are
2338 * overwhelmingly different between them, adjust scan
2339 * balance for CPU work.
2340 */
2341 cost->count += nr_io * SWAP_CLUSTER_MAX + nr_rotated;
2342
2343 cost->last_rotated = rotated;
2344 cost->last_io = io;
2345 }
2346
2347 anon_cost = &target_lruvec->cost[WORKINGSET_ANON];
2348 file_cost = &target_lruvec->cost[WORKINGSET_FILE];
2349
2350 lrusize = lruvec_page_state(target_lruvec, NR_INACTIVE_ANON) +
2351 lruvec_page_state(target_lruvec, NR_ACTIVE_ANON) +
2352 lruvec_page_state(target_lruvec, NR_INACTIVE_FILE) +
2353 lruvec_page_state(target_lruvec, NR_ACTIVE_FILE);
2354
2355 while (anon_cost->count + file_cost->count > lrusize / 4) {
2356 anon_cost->count /= 2;
2357 file_cost->count /= 2;
2358 }
2359
2360 sc->anon_cost = anon_cost->count;
2361 sc->file_cost = file_cost->count;
2362
2363 spin_unlock(&target_lruvec->cost_lock);
2300 2364
2301 /*2365 /*
2302 * Target desirable inactive:active list ratios for the anon2366 * Target desirable inactive:active list ratios for the anon
@@ -3202,14 +3266,19 @@ static bool positive_ctrl_err(struct ctrl_pos *sp, struct ctrl_pos *pv) · 899 unmodified lines
3202 ******************************************************************************/3266 ******************************************************************************/
3203 3267
3204/* promote pages accessed through page tables */3268/* promote pages accessed through page tables */
3205static int folio_update_gen(struct folio *folio, int gen)3269static int folio_update_gen(struct folio *folio, int gen, const vma_flags_t *vma_flags)
3206{3270{
3207 unsigned long new_flags, old_flags = READ_ONCE(folio->flags.f);3271 unsigned long new_flags, old_flags = READ_ONCE(folio->flags.f);
3208 3272
3209 VM_WARN_ON_ONCE(gen >= MAX_NR_GENS);3273 VM_WARN_ON_ONCE(gen >= MAX_NR_GENS);
3210 3274
3211 /* see the comment on LRU_REFS_FLAGS */3275 /*
3212 if (!folio_test_referenced(folio) && !folio_test_workingset(folio)) {3276 * See the comment on LRU_REFS_FLAGS, and activate file-backed
3277 * executable folios after first usage to avoid typical IO
3278 * thrashing from reclaiming.
3279 */
3280 if (!folio_test_referenced(folio) && !folio_test_workingset(folio) &&
3281 !is_exec_file_folio(folio, vma_flags)) {
3213 set_mask_bits(&folio->flags.f, LRU_REFS_MASK, BIT(PG_referenced));3282 set_mask_bits(&folio->flags.f, LRU_REFS_MASK, BIT(PG_referenced));
3214 return -1;3283 return -1;
3215 }3284 }
@@ -3442,8 +3511,8 @@ static bool suitable_to_scan(int total, int young) · 226 unmodified lines
3442 return young * n >= total;3511 return young * n >= total;
3443}3512}
3444 3513
3445static void walk_update_folio(struct lru_gen_mm_walk *walk, struct folio *folio,3514static void walk_update_folio(struct lru_gen_mm_walk *walk, struct vm_area_struct *vma,
3446 int new_gen, bool dirty)3515 struct folio *folio, int new_gen, bool dirty)
3447{3516{
3448 int old_gen;3517 int old_gen;
3449 3518
@@ -3456,10 +3525,10 @@ static void walk_update_folio(struct lru_gen_mm_walk *walk, struct folio *folio, · 6 unmodified lines
3456 folio_mark_dirty(folio);3525 folio_mark_dirty(folio);
3457 3526
3458 if (walk) {3527 if (walk) {
3459 old_gen = folio_update_gen(folio, new_gen);3528 old_gen = folio_update_gen(folio, new_gen, &vma->flags);
3460 if (old_gen >= 0 && old_gen != new_gen)3529 if (old_gen >= 0 && old_gen != new_gen)
3461 update_batch_size(walk, folio, old_gen, new_gen);3530 update_batch_size(walk, folio, old_gen, new_gen);
3462 } else if (lru_gen_set_refs(folio)) {3531 } else if (lru_gen_set_refs(folio, &vma->flags)) {
3463 old_gen = folio_lru_gen(folio);3532 old_gen = folio_lru_gen(folio);
3464 if (old_gen >= 0 && old_gen != new_gen)3533 if (old_gen >= 0 && old_gen != new_gen)
3465 folio_activate(folio);3534 folio_activate(folio);
@@ -3532,7 +3601,7 @@ restart: · 66 unmodified lines
3532 continue;3601 continue;
3533 3602
3534 if (last != folio) {3603 if (last != folio) {
3535 walk_update_folio(walk, last, gen, dirty);3604 walk_update_folio(walk, args->vma, last, gen, dirty);
3536 3605
3537 last = folio;3606 last = folio;
3538 dirty = false;3607 dirty = false;
@@ -3545,7 +3614,7 @@ restart: · 6 unmodified lines
3545 walk->mm_stats[MM_LEAF_YOUNG] += nr;3614 walk->mm_stats[MM_LEAF_YOUNG] += nr;
3546 }3615 }
3547 3616
3548 walk_update_folio(walk, last, gen, dirty);3617 walk_update_folio(walk, args->vma, last, gen, dirty);
3549 last = NULL;3618 last = NULL;
3550 3619
3551 if (i < PTRS_PER_PTE && get_next_vma(PMD_MASK, PAGE_SIZE, args, &start, &end))3620 if (i < PTRS_PER_PTE && get_next_vma(PMD_MASK, PAGE_SIZE, args, &start, &end))
@@ -3623,7 +3692,7 @@ static void walk_pmd_range_locked(pud_t *pud, unsigned long addr, struct vm_area · 71 unmodified lines
3623 goto next;3692 goto next;
3624 3693
3625 if (last != folio) {3694 if (last != folio) {
3626 walk_update_folio(walk, last, gen, dirty);3695 walk_update_folio(walk, vma, last, gen, dirty);
3627 3696
3628 last = folio;3697 last = folio;
3629 dirty = false;3698 dirty = false;
@@ -3637,7 +3706,7 @@ next: · 7 unmodified lines
3637 i = i > MIN_LRU_BATCH ? 0 : find_next_bit(bitmap, MIN_LRU_BATCH, i) + 1;3706 i = i > MIN_LRU_BATCH ? 0 : find_next_bit(bitmap, MIN_LRU_BATCH, i) + 1;
3638 } while (i <= MIN_LRU_BATCH);3707 } while (i <= MIN_LRU_BATCH);
3639 3708
3640 walk_update_folio(walk, last, gen, dirty);3709 walk_update_folio(walk, vma, last, gen, dirty);
3641 3710
3642 lazy_mmu_mode_disable();3711 lazy_mmu_mode_disable();
3643 spin_unlock(ptl);3712 spin_unlock(ptl);
@@ -4192,7 +4261,7 @@ bool lru_gen_look_around(struct page_vma_mapped_walk *pvmw, unsigned int nr) · 548 unmodified lines
4192 unsigned long end;4261 unsigned long end;
4193 struct lru_gen_mm_walk *walk;4262 struct lru_gen_mm_walk *walk;
4194 struct folio *last = NULL;4263 struct folio *last = NULL;
4195 int young = 1;4264 int young = nr;
4196 pte_t *pte = pvmw->pte;4265 pte_t *pte = pvmw->pte;
4197 unsigned long addr = pvmw->address;4266 unsigned long addr = pvmw->address;
4198 struct vm_area_struct *vma = pvmw->vma;4267 struct vm_area_struct *vma = pvmw->vma;
@@ -4272,7 +4341,7 @@ bool lru_gen_look_around(struct page_vma_mapped_walk *pvmw, unsigned int nr) · 73 unmodified lines
4272 continue;4341 continue;
4273 4342
4274 if (last != folio) {4343 if (last != folio) {
4275 walk_update_folio(walk, last, gen, dirty);4344 walk_update_folio(walk, vma, last, gen, dirty);
4276 4345
4277 last = folio;4346 last = folio;
4278 dirty = false;4347 dirty = false;
@@ -4284,7 +4353,7 @@ bool lru_gen_look_around(struct page_vma_mapped_walk *pvmw, unsigned int nr) · 5 unmodified lines
4284 young += nr;4353 young += nr;
4285 }4354 }
4286 4355
4287 walk_update_folio(walk, last, gen, dirty);4356 walk_update_folio(walk, vma, last, gen, dirty);
4288 4357
4289 lazy_mmu_mode_disable();4358 lazy_mmu_mode_disable();
4290 4359
@@ -4566,7 +4635,12 @@ void lru_gen_reparent_memcg(struct mem_cgroup *memcg, struct mem_cgroup *parent, · 275 unmodified lines
4566 for_each_managed_zone_pgdat(zone, NODE_DATA(nid), zid, MAX_NR_ZONES - 1) {4635 for_each_managed_zone_pgdat(zone, NODE_DATA(nid), zid, MAX_NR_ZONES - 1) {
4567 unsigned long size = mem_cgroup_get_zone_lru_size(child_lruvec, lru, zid);4636 unsigned long size = mem_cgroup_get_zone_lru_size(child_lruvec, lru, zid);
4568 4637
4638 if (!size)
4639 continue;
4640
4641 /* Move the accounting, do not duplicate it. */
4569 mem_cgroup_update_lru_size(parent_lruvec, lru, zid, size);4642 mem_cgroup_update_lru_size(parent_lruvec, lru, zid, size);
4643 mem_cgroup_update_lru_size(child_lruvec, lru, zid, -(long)size);
4570 }4644 }
4571 }4645 }
4572}4646}
@@ -4580,7 +4654,6 @@ void lru_gen_reparent_memcg(struct mem_cgroup *memcg, struct mem_cgroup *parent, · 7 unmodified lines
4580static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_control *sc,4654static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_control *sc,
4581 int tier_idx)4655 int tier_idx)
4582{4656{
4583 bool success;
4584 int gen = folio_lru_gen(folio);4657 int gen = folio_lru_gen(folio);
4585 int type = folio_is_file_lru(folio);4658 int type = folio_is_file_lru(folio);
4586 int zone = folio_zonenum(folio);4659 int zone = folio_zonenum(folio);
@@ -4592,15 +4665,9 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_c · 5 unmodified lines
4592 4665
4593 VM_WARN_ON_ONCE_FOLIO(gen >= MAX_NR_GENS, folio);4666 VM_WARN_ON_ONCE_FOLIO(gen >= MAX_NR_GENS, folio);
4594 4667
4595 /* unevictable */4668 /* unevictable: let it through and the generic path will cull it */
4596 if (!folio_evictable(folio)) {4669 if (!folio_evictable(folio))
4597 success = lru_gen_del_folio(lruvec, folio, true);4670 return false;
4598 VM_WARN_ON_ONCE_FOLIO(!success, folio);
4599 folio_set_unevictable(folio);
4600 lruvec_add_folio(lruvec, folio);
4601 __count_vm_events(UNEVICTABLE_PGCULLED, delta);
4602 return true;
4603 }
4604 4671
4605 /* promoted */4672 /* promoted */
4606 if (gen != lru_gen_from_seq(lrugen->min_seq[type])) {4673 if (gen != lru_gen_from_seq(lrugen->min_seq[type])) {
@@ -4816,7 +4883,8 @@ static int evict_folios(unsigned long nr_to_scan, struct lruvec *lruvec, · 209 unmodified lines
4816 struct reclaim_stat stat;4883 struct reclaim_stat stat;
4817 struct lru_gen_mm_walk *walk;4884 struct lru_gen_mm_walk *walk;
4818 int scanned, reclaimed;4885 int scanned, reclaimed;
4819 int isolated = 0, type, type_scanned;4886 int isolated = 0, nr_isolated = 0, type, type_scanned;
4887 unsigned long total_reclaimed = 0;
4820 bool skip_retry = false;4888 bool skip_retry = false;
4821 struct mem_cgroup *memcg = lruvec_memcg(lruvec);4889 struct mem_cgroup *memcg = lruvec_memcg(lruvec);
4822 struct pglist_data *pgdat = lruvec_pgdat(lruvec);4890 struct pglist_data *pgdat = lruvec_pgdat(lruvec);
@@ -4828,6 +4896,7 @@ static int evict_folios(unsigned long nr_to_scan, struct lruvec *lruvec, · 5 unmodified lines
4828 4896
4829 scanned = isolate_folios(nr_to_scan, lruvec, sc, swappiness,4897 scanned = isolate_folios(nr_to_scan, lruvec, sc, swappiness,
4830 &list, &isolated, &type, &type_scanned);4898 &list, &isolated, &type, &type_scanned);
4899 nr_isolated = isolated;
4831 4900
4832 /* Scanning may have emptied the oldest gen, flush it */4901 /* Scanning may have emptied the oldest gen, flush it */
4833 if (scanned)4902 if (scanned)
@@ -4840,6 +4909,7 @@ static int evict_folios(unsigned long nr_to_scan, struct lruvec *lruvec, · 6 unmodified lines
4840retry:4909retry:
4841 reclaimed = shrink_folio_list(&list, pgdat, sc, &stat, false, memcg);4910 reclaimed = shrink_folio_list(&list, pgdat, sc, &stat, false, memcg);
4842 sc->nr_reclaimed += reclaimed;4911 sc->nr_reclaimed += reclaimed;
4912 total_reclaimed += reclaimed;
4843 /* Retry pass is only meant for clean folios without new isolation */4913 /* Retry pass is only meant for clean folios without new isolation */
4844 if (isolated)4914 if (isolated)
4845 handle_reclaim_writeback(isolated, pgdat, sc, &stat);4915 handle_reclaim_writeback(isolated, pgdat, sc, &stat);
@@ -4850,11 +4920,9 @@ retry: · 4 unmodified lines
4850 list_for_each_entry_safe_reverse(folio, next, &list, lru) {4920 list_for_each_entry_safe_reverse(folio, next, &list, lru) {
4851 DEFINE_MIN_SEQ(lruvec);4921 DEFINE_MIN_SEQ(lruvec);
4852 4922
4853 if (!folio_evictable(folio)) {4923 /* move_folios_to_lru() culls unevictable folios via folio_putback_lru() */
4854 list_del(&folio->lru);4924 if (!folio_evictable(folio))
4855 folio_putback_lru(folio);
4856 continue;4925 continue;
4857 }
4858 4926
4859 /* retry folios that may have missed folio_rotate_reclaimable() */4927 /* retry folios that may have missed folio_rotate_reclaimable() */
4860 if (!skip_retry && !folio_test_active(folio) && !folio_mapped(folio) &&4928 if (!skip_retry && !folio_test_active(folio) && !folio_mapped(folio) &&
@@ -4891,6 +4959,10 @@ retry: · 30 unmodified lines
4891 goto retry;4959 goto retry;
4892 }4960 }
4893 4961
4962 if (nr_isolated > total_reclaimed)
4963 mod_lruvec_state(lruvec, PGROTATE_ANON + type,
4964 nr_isolated - total_reclaimed);
4965
4894 return scanned;4966 return scanned;
4895}4967}
4896 4968
@@ -7209,7 +7281,7 @@ restart: · 2312 unmodified lines
7209 7281
7210 /*7282 /*
7211 * If the low watermark is met there is no need for processes7283 * If the low watermark is met there is no need for processes
7212 * to be throttled on pfmemalloc_wait as they should not be7284 * to be throttled on pfmemalloc_wait as they should now be
7213 * able to safely make forward progress. Wake them7285 * able to safely make forward progress. Wake them
7214 */7286 */
7215 if (waitqueue_active(&pgdat->pfmemalloc_wait) &&7287 if (waitqueue_active(&pgdat->pfmemalloc_wait) &&
mm/vmstat.c+18−1
@@ -1025,6 +1025,17 @@ unsigned long node_page_state(struct pglist_data *pgdat, · 1024 unmodified lines
1025 1025
1026 return node_page_state_pages(pgdat, item);1026 return node_page_state_pages(pgdat, item);
1027}1027}
1028
1029/*
1030 * Non-clamping variant of node_page_state() intended for callers that
1031 * snapshot a monotonically-incremented counter and subtract two samples.
1032 * See global_node_page_state_monotonic() for the rationale.
1033 */
1034unsigned long node_page_state_monotonic(struct pglist_data *pgdat,
1035 enum node_stat_item item)
1036{
1037 return (unsigned long)atomic_long_read(&pgdat->vm_stat[item]);
1038}
1028#endif1039#endif
1029 1040
1030/*1041/*
@@ -1290,6 +1301,8 @@ const char * const vmstat_text[] = { · 259 unmodified lines
1290 [I(PGSCAN_PROACTIVE)] = "pgscan_proactive",1301 [I(PGSCAN_PROACTIVE)] = "pgscan_proactive",
1291 [I(PGSCAN_ANON)] = "pgscan_anon",1302 [I(PGSCAN_ANON)] = "pgscan_anon",
1292 [I(PGSCAN_FILE)] = "pgscan_file",1303 [I(PGSCAN_FILE)] = "pgscan_file",
1304 [I(PGROTATE_ANON)] = "pgrotate_anon",
1305 [I(PGROTATE_FILE)] = "pgrotate_file",
1293 [I(PGREFILL)] = "pgrefill",1306 [I(PGREFILL)] = "pgrefill",
1294#ifdef CONFIG_HUGETLB_PAGE1307#ifdef CONFIG_HUGETLB_PAGE
1295 [I(NR_HUGETLB)] = "nr_hugetlb",1308 [I(NR_HUGETLB)] = "nr_hugetlb",
@@ -1489,7 +1502,11 @@ const char * const vmstat_text[] = { · 193 unmodified lines
1489#if THREAD_SIZE > 655361502#if THREAD_SIZE > 65536
1490 [I(KSTACK_REST)] = "kstack_rest",1503 [I(KSTACK_REST)] = "kstack_rest",
1491#endif1504#endif
1492#endif1505#endif /* CONFIG_DEBUG_STACK_USAGE */
1506#ifdef CONFIG_SWAP
1507 [I(NRSWPIN)] = "nrswpin",
1508 [I(NRSWPOUT)] = "nrswpout",
1509#endif /* CONFIG_SWAP */
1493#undef I1510#undef I
1494#endif /* CONFIG_VM_EVENT_COUNTERS */1511#endif /* CONFIG_VM_EVENT_COUNTERS */
1495};1512};
mm/workingset.c+0−5
@@ -584,11 +584,6 @@ void workingset_refault(struct folio *folio, void *shadow) · 583 unmodified lines
584 /* Folio was active prior to eviction */584 /* Folio was active prior to eviction */
585 if (workingset) {585 if (workingset) {
586 folio_set_workingset(folio);586 folio_set_workingset(folio);
587 /*
588 * XXX: Move to folio_add_lru() when it supports new vs
589 * putback
590 */
591 lru_note_cost_refault(folio);
592 mod_lruvec_state(lruvec, WORKINGSET_RESTORE_BASE + file, nr);587 mod_lruvec_state(lruvec, WORKINGSET_RESTORE_BASE + file, nr);
593 }588 }
594out:589out:
mm/zsmalloc.c+7−4
@@ -552,6 +552,11 @@ static int get_size_class_index(int size) · 551 unmodified lines
552 return min_t(int, ZS_SIZE_CLASSES - 1, idx);552 return min_t(int, ZS_SIZE_CLASSES - 1, idx);
553}553}
554 554
555static struct size_class *lookup_size_class(struct zs_pool *pool, size_t size)
556{
557 return pool->size_class[get_size_class_index(size + ZS_HANDLE_SIZE)];
558}
559
555static inline void class_stat_add(struct size_class *class, int type,560static inline void class_stat_add(struct size_class *class, int type,
556 unsigned long cnt)561 unsigned long cnt)
557{562{
@@ -1117,7 +1122,7 @@ unsigned int zs_lookup_class_index(struct zs_pool *pool, unsigned int size) · 559 unmodified lines
1117{1122{
1118 struct size_class *class;1123 struct size_class *class;
1119 1124
1120 class = pool->size_class[get_size_class_index(size)];1125 class = lookup_size_class(pool, size);
1121 1126
1122 return class->index;1127 return class->index;
1123}1128}
@@ -1407,9 +1412,7 @@ unsigned long zs_malloc(struct zs_pool *pool, size_t size, gfp_t gfp, · 283 unmodified lines
1407 if (!handle)1412 if (!handle)
1408 return (unsigned long)ERR_PTR(-ENOMEM);1413 return (unsigned long)ERR_PTR(-ENOMEM);
1409 1414
1410 /* extra space in chunk to keep the handle */1415 class = lookup_size_class(pool, size);
1411 size += ZS_HANDLE_SIZE;
1412 class = pool->size_class[get_size_class_index(size)];
1413 1416
1414 /* class->lock effectively protects the zpage migration */1417 /* class->lock effectively protects the zpage migration */
1415 spin_lock(&class->lock);1418 spin_lock(&class->lock);
mm/zswap.c+29−17
@@ -20,7 +20,7 @@ · 19 unmodified lines
20#include <linux/spinlock.h>20#include <linux/spinlock.h>
21#include <linux/types.h>21#include <linux/types.h>
22#include <linux/atomic.h>22#include <linux/atomic.h>
23#include <linux/swap.h>23#include <linux/swap_ops.h>
24#include <linux/crypto.h>24#include <linux/crypto.h>
25#include <linux/scatterlist.h>25#include <linux/scatterlist.h>
26#include <linux/mempolicy.h>26#include <linux/mempolicy.h>
@@ -665,7 +665,7 @@ static inline int entry_to_nid(struct zswap_entry *entry) · 638 unmodified lines
665 return page_to_nid(virt_to_page(entry));665 return page_to_nid(virt_to_page(entry));
666}666}
667 667
668static void zswap_lru_add(struct list_lru *list_lru, struct zswap_entry *entry)668static void zswap_lru_add(struct zswap_entry *entry)
669{669{
670 int nid = entry_to_nid(entry);670 int nid = entry_to_nid(entry);
671 struct mem_cgroup *memcg;671 struct mem_cgroup *memcg;
@@ -684,11 +684,11 @@ static void zswap_lru_add(struct list_lru *list_lru, struct zswap_entry *entry) · 12 unmodified lines
684 rcu_read_lock();684 rcu_read_lock();
685 memcg = mem_cgroup_from_entry(entry);685 memcg = mem_cgroup_from_entry(entry);
686 /* will always succeed */686 /* will always succeed */
687 list_lru_add(list_lru, &entry->lru, nid, memcg);687 list_lru_add(&zswap_list_lru, &entry->lru, nid, memcg);
688 rcu_read_unlock();688 rcu_read_unlock();
689}689}
690 690
691static void zswap_lru_del(struct list_lru *list_lru, struct zswap_entry *entry)691static void zswap_lru_del(struct zswap_entry *entry)
692{692{
693 int nid = entry_to_nid(entry);693 int nid = entry_to_nid(entry);
694 struct mem_cgroup *memcg;694 struct mem_cgroup *memcg;
@@ -696,7 +696,7 @@ static void zswap_lru_del(struct list_lru *list_lru, struct zswap_entry *entry) · 1 unmodified line
696 rcu_read_lock();696 rcu_read_lock();
697 memcg = mem_cgroup_from_entry(entry);697 memcg = mem_cgroup_from_entry(entry);
698 /* will always succeed */698 /* will always succeed */
699 list_lru_del(list_lru, &entry->lru, nid, memcg);699 list_lru_del(&zswap_list_lru, &entry->lru, nid, memcg);
700 rcu_read_unlock();700 rcu_read_unlock();
701}701}
702 702
@@ -764,7 +764,7 @@ static void zswap_entry_cache_free(struct zswap_entry *entry) · 61 unmodified lines
764 */764 */
765static void zswap_entry_free(struct zswap_entry *entry)765static void zswap_entry_free(struct zswap_entry *entry)
766{766{
767 zswap_lru_del(&zswap_list_lru, entry);767 zswap_lru_del(entry);
768 zs_free(entry->pool->zs_pool, entry->handle);768 zs_free(entry->pool->zs_pool, entry->handle);
769 zswap_pool_put(entry->pool);769 zswap_pool_put(entry->pool);
770 if (entry->objcg) {770 if (entry->objcg) {
@@ -992,6 +992,7 @@ static int zswap_writeback_entry(struct zswap_entry *entry, · 221 unmodified lines
992 struct folio *folio;992 struct folio *folio;
993 struct mempolicy *mpol;993 struct mempolicy *mpol;
994 struct swap_info_struct *si;994 struct swap_info_struct *si;
995 struct swap_io_ctx ctx = {};
995 int ret = 0;996 int ret = 0;
996 997
997 /* try to allocate swap cache folio */998 /* try to allocate swap cache folio */
@@ -1049,7 +1050,8 @@ static int zswap_writeback_entry(struct zswap_entry *entry, · 51 unmodified lines
1049 folio_set_reclaim(folio);1050 folio_set_reclaim(folio);
1050 1051
1051 /* start writeback */1052 /* start writeback */
1052 __swap_writepage(folio, NULL);1053 __swap_writepage(&ctx, folio);
1054 swap_write_submit(&ctx);
1053 1055
1054out:1056out:
1055 if (ret) {1057 if (ret) {
@@ -1217,7 +1219,7 @@ static unsigned long zswap_shrinker_count(struct shrinker *shrinker, · 161 unmodified lines
1217 * Without memcg, use the zswap pool-wide metrics.1219 * Without memcg, use the zswap pool-wide metrics.
1218 */1220 */
1219 if (!mem_cgroup_disabled()) {1221 if (!mem_cgroup_disabled()) {
1220 mem_cgroup_flush_stats(memcg);1222 mem_cgroup_flush_stats_ratelimited(memcg);
1221 nr_backing = memcg_page_state(memcg, MEMCG_ZSWAP_B) >> PAGE_SHIFT;1223 nr_backing = memcg_page_state(memcg, MEMCG_ZSWAP_B) >> PAGE_SHIFT;
1222 nr_stored = memcg_page_state(memcg, MEMCG_ZSWAPPED);1224 nr_stored = memcg_page_state(memcg, MEMCG_ZSWAPPED);
1223 } else {1225 } else {
@@ -1275,6 +1277,14 @@ static struct shrinker *zswap_alloc_shrinker(void) · 51 unmodified lines
1275 return shrinker;1277 return shrinker;
1276}1278}
1277 1279
1280/*
1281 * Scan up to SWAP_CLUSTER_MAX pages on each per-node zswap LRU of @memcg
1282 * and write back the reclaimable ones.
1283 *
1284 * Return: 0 if at least one entry was written back, -EAGAIN if entries
1285 * were scanned but none could be written back, or -ENOENT if @memcg has
1286 * writeback disabled, is a zombie cgroup, or has empty zswap LRUs.
1287 */
1278static int shrink_memcg(struct mem_cgroup *memcg)1288static int shrink_memcg(struct mem_cgroup *memcg)
1279{1289{
1280 int nid, shrunk = 0, scanned = 0;1290 int nid, shrunk = 0, scanned = 0;
@@ -1290,13 +1300,14 @@ static int shrink_memcg(struct mem_cgroup *memcg) · 9 unmodified lines
1290 return -ENOENT;1300 return -ENOENT;
1291 1301
1292 for_each_node_state(nid, N_NORMAL_MEMORY) {1302 for_each_node_state(nid, N_NORMAL_MEMORY) {
1293 unsigned long nr_to_walk = 1;1303 unsigned long nr_to_walk = SWAP_CLUSTER_MAX;
1294 1304
1295 shrunk += list_lru_walk_one(&zswap_list_lru, nid, memcg,1305 shrunk += list_lru_walk_one(&zswap_list_lru, nid, memcg,
1296 &shrink_memcg_cb, NULL, &nr_to_walk);1306 &shrink_memcg_cb, NULL, &nr_to_walk);
1297 scanned += 1 - nr_to_walk;1307 scanned += SWAP_CLUSTER_MAX - nr_to_walk;
1298 }1308 }
1299 1309
1310 /* Nothing was scanned: every LRU under @memcg was empty. */
1300 if (!scanned)1311 if (!scanned)
1301 return -ENOENT;1312 return -ENOENT;
1302 1313
@@ -1356,11 +1367,12 @@ static void shrink_worker(struct work_struct *w) · 53 unmodified lines
1356 } while (memcg && !mem_cgroup_tryget_online(memcg));1367 } while (memcg && !mem_cgroup_tryget_online(memcg));
1357 spin_unlock(&zswap_shrink_lock);1368 spin_unlock(&zswap_shrink_lock);
1358 1369
1359 if (!memcg) {1370 /*
1360 /*1371 * A NULL memcg ends a full hierarchy pass (except when memcg is
1361 * Continue shrinking without incrementing failures if1372 * disabled, where it is always NULL: fall through to the root LRU).
1362 * we found candidate memcgs in the last tree walk.1373 * Count a failure only if the last pass found no candidates.
1363 */1374 */
1375 if (!memcg && !mem_cgroup_disabled()) {
1364 if (!attempts && ++failures == MAX_RECLAIM_RETRIES)1376 if (!attempts && ++failures == MAX_RECLAIM_RETRIES)
1365 break;1377 break;
1366 1378
@@ -1379,7 +1391,7 @@ static void shrink_worker(struct work_struct *w) · 12 unmodified lines
1379 * and failures.1391 * and failures.
1380 */1392 */
1381 if (ret == -ENOENT)1393 if (ret == -ENOENT)
1382 continue;1394 goto resched;
1383 ++attempts;1395 ++attempts;
1384 1396
1385 if (ret && ++failures == MAX_RECLAIM_RETRIES)1397 if (ret && ++failures == MAX_RECLAIM_RETRIES)
@@ -1461,7 +1473,7 @@ static bool zswap_store_page(struct page *page, · 75 unmodified lines
1461 entry->referenced = true;1473 entry->referenced = true;
1462 if (entry->length) {1474 if (entry->length) {
1463 INIT_LIST_HEAD(&entry->lru);1475 INIT_LIST_HEAD(&entry->lru);
1464 zswap_lru_add(&zswap_list_lru, entry);1476 zswap_lru_add(entry);
1465 }1477 }
1466 1478
1467 return true;1479 return true;
tools/testing/radix-tree/maple.c+2−2
@@ -35234,7 +35234,7 @@ static noinline void __init check_prealloc(struct maple_tree *mt) · 35233 unmodified lines
35234 mt_set_non_kernel(1);35234 mt_set_non_kernel(1);
35235 /* Spanning store */35235 /* Spanning store */
35236 mas_set_range(&mas, 1, 100);35236 mas_set_range(&mas, 1, 100);
35237 MT_BUG_ON(mt, mas_preallocate(&mas, ptr, GFP_KERNEL & GFP_NOWAIT) == 0);35237 MT_BUG_ON(mt, mas_preallocate(&mas, ptr, GFP_NOWAIT) == 0);
35238 allocated = mas_allocated(&mas);35238 allocated = mas_allocated(&mas);
35239 height = mas_mt_height(&mas);35239 height = mas_mt_height(&mas);
35240 MT_BUG_ON(mt, allocated != 0);35240 MT_BUG_ON(mt, allocated != 0);
@@ -35257,7 +35257,7 @@ static noinline void __init check_prealloc(struct maple_tree *mt) · 16 unmodified lines
35257 MT_BUG_ON(mt, mas_allocated(&mas) != 0);35257 MT_BUG_ON(mt, mas_allocated(&mas) != 0);
35258 mas_set_range(&mas, 0, 200);35258 mas_set_range(&mas, 0, 200);
35259 mt_set_non_kernel(1);35259 mt_set_non_kernel(1);
35260 MT_BUG_ON(mt, mas_preallocate(&mas, ptr, GFP_KERNEL & GFP_NOWAIT) == 0);35260 MT_BUG_ON(mt, mas_preallocate(&mas, ptr, GFP_NOWAIT) == 0);
35261 allocated = mas_allocated(&mas);35261 allocated = mas_allocated(&mas);
35262 height = mas_mt_height(&mas);35262 height = mas_mt_height(&mas);
35263 MT_BUG_ON(mt, allocated != 0);35263 MT_BUG_ON(mt, allocated != 0);
tools/testing/selftests/Makefile+1−0
@@ -1,5 +1,6 @@
1# SPDX-License-Identifier: GPL-2.01# SPDX-License-Identifier: GPL-2.0
2TARGETS += acct2TARGETS += acct
3TARGETS += alloc_tag
3TARGETS += alsa4TARGETS += alsa
4TARGETS += amd-pstate5TARGETS += amd-pstate
5TARGETS += arm646TARGETS += arm64
tools/testing/selftests/alloc_tag/Makefile+8−0
@@ -0,0 +1,8 @@
1# SPDX-License-Identifier: GPL-2.0
2
3TEST_GEN_PROGS := allocinfo_ioctl_test
4
5CFLAGS += -Wall
6CFLAGS += $(KHDR_INCLUDES)
7
8include ../lib.mk
tools/testing/selftests/alloc_tag/allocinfo_ioctl_test.c+548−0
@@ -0,0 +1,548 @@
1// SPDX-License-Identifier: GPL-2.0-only
2
3/* kselftest for allocinfo ioctl
4 * allocinfo ioctl retrieves allocinfo data through ioctl
5 * Copyright (C) 2026 Google, Inc.
6 */
7
8#include <errno.h>
9#include <fcntl.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <stdbool.h>
14#include <unistd.h>
15#include <sys/ioctl.h>
16#include <linux/types.h>
17#include <linux/alloc_tag.h>
18#include "../kselftest.h"
19
20#define MAX_LINE_LEN 512
21#define ALLOCINFO_PROC "/proc/allocinfo"
22
23enum ioctl_ret {
24 IOCTL_SUCCESS = 0,
25 IOCTL_FAILURE = 1,
26 IOCTL_INVALID_DATA = 2,
27};
28
29#define VEC_MAX_ENTRIES 32
30
31struct allocinfo_tag_data_vec {
32 struct allocinfo_tag_data tag[VEC_MAX_ENTRIES];
33 __u64 count;
34};
35
36static inline int __allocinfo_get_content_id(int dev_fd, struct allocinfo_content_id *params)
37{
38 return ioctl(dev_fd, ALLOCINFO_IOC_CONTENT_ID, params);
39}
40
41static inline int __allocinfo_get_at(int dev_fd, struct allocinfo_get_at *params)
42{
43 return ioctl(dev_fd, ALLOCINFO_IOC_GET_AT, params);
44}
45
46static inline int __allocinfo_get_next(int dev_fd, struct allocinfo_tag_data *params)
47{
48 return ioctl(dev_fd, ALLOCINFO_IOC_GET_NEXT, params);
49}
50
51static bool match_entry(const struct allocinfo_tag_data *procfs_entry,
52 const struct allocinfo_tag_data *tag_data,
53 bool match_bytes, bool match_calls, bool match_lineno,
54 bool match_function, bool match_filename)
55{
56 if (match_bytes && tag_data->counter.bytes != procfs_entry->counter.bytes) {
57 ksft_print_msg("size retrieved through ioctl does not match procfs\n");
58 return false;
59 }
60
61 if (match_calls && tag_data->counter.calls != procfs_entry->counter.calls) {
62 ksft_print_msg("call count retrieved through ioctl does not match procfs\n");
63 return false;
64 }
65
66 if (match_lineno && tag_data->tag.lineno != procfs_entry->tag.lineno) {
67 ksft_print_msg("lineno retrieved through ioctl does not match procfs\n");
68 return false;
69 }
70
71 if (match_function &&
72 strncmp(tag_data->tag.function, procfs_entry->tag.function, ALLOCINFO_STR_SIZE)) {
73 ksft_print_msg("function retrieved through ioctl does not match procfs\n");
74 return false;
75 }
76
77 if (match_filename &&
78 strncmp(tag_data->tag.filename, procfs_entry->tag.filename, ALLOCINFO_STR_SIZE)) {
79 ksft_print_msg("filename retrieved through ioctl does not match procfs\n");
80 return false;
81 }
82 return true;
83}
84
85static bool match_entries(const struct allocinfo_tag_data_vec *procfs_entries,
86 const struct allocinfo_tag_data_vec *tags,
87 bool match_bytes, bool match_calls, bool match_lineno,
88 bool match_function, bool match_filename)
89{
90 __u64 i;
91
92 if (procfs_entries->count != tags->count) {
93 ksft_print_msg("Entry count mismatch. ioctl entries: %llu, proc entries: %llu\n",
94 tags->count, procfs_entries->count);
95 return false;
96 }
97 for (i = 0; i < procfs_entries->count; i++) {
98 if (!match_entry(&procfs_entries->tag[i], &tags->tag[i],
99 match_bytes, match_calls, match_lineno,
100 match_function, match_filename)) {
101 ksft_print_msg("%lluth entry does not match.\n", i);
102 return false;
103 }
104 }
105 return true;
106}
107
108static const char *allocinfo_str(const char *str)
109{
110 size_t len = strlen(str);
111
112 if (len >= ALLOCINFO_STR_SIZE)
113 str += (len - ALLOCINFO_STR_SIZE) + 1;
114 return str;
115}
116
117static void allocinfo_copy_str(char *dest, const char *src)
118{
119 strncpy(dest, allocinfo_str(src), ALLOCINFO_STR_SIZE - 1);
120 dest[ALLOCINFO_STR_SIZE - 1] = '\0';
121}
122
123static int get_filtered_procfs_entries(struct allocinfo_tag_data_vec *procfs_entries,
124 const struct allocinfo_filter *filter)
125{
126 FILE *fp = fopen(ALLOCINFO_PROC, "r");
127 char line[MAX_LINE_LEN];
128 int matches;
129 struct allocinfo_tag_data procfs_entry;
130
131 if (!fp) {
132 ksft_print_msg("Failed to open " ALLOCINFO_PROC " for reading\n");
133 return 1;
134 }
135 memset(procfs_entries, 0, sizeof(*procfs_entries));
136 while (fgets(line, sizeof(line), fp) && procfs_entries->count < VEC_MAX_ENTRIES) {
137 char filename[MAX_LINE_LEN];
138 char function[MAX_LINE_LEN];
139
140 memset(&procfs_entry, 0, sizeof(procfs_entry));
141 matches = sscanf(line, "%llu %llu %[^:]:%llu func:%s",
142 &procfs_entry.counter.bytes,
143 &procfs_entry.counter.calls,
144 filename,
145 &procfs_entry.tag.lineno,
146 function);
147
148 if (matches != 5)
149 continue;
150
151 allocinfo_copy_str(procfs_entry.tag.filename, filename);
152 allocinfo_copy_str(procfs_entry.tag.function, function);
153
154 if (filter->mask & ALLOCINFO_FILTER_MASK_FILENAME) {
155 if (strncmp(procfs_entry.tag.filename,
156 filter->fields.filename, ALLOCINFO_STR_SIZE))
157 continue;
158 }
159 if (filter->mask & ALLOCINFO_FILTER_MASK_FUNCTION) {
160 if (strncmp(procfs_entry.tag.function,
161 filter->fields.function, ALLOCINFO_STR_SIZE))
162 continue;
163 }
164 if (filter->mask & ALLOCINFO_FILTER_MASK_LINENO) {
165 if (procfs_entry.tag.lineno != filter->fields.lineno)
166 continue;
167 }
168 if (filter->mask & ALLOCINFO_FILTER_MASK_MIN_SIZE) {
169 if (procfs_entry.counter.bytes < filter->min_size)
170 continue;
171 }
172 if (filter->mask & ALLOCINFO_FILTER_MASK_MAX_SIZE) {
173 if (procfs_entry.counter.bytes > filter->max_size)
174 continue;
175 }
176
177 memcpy(&procfs_entries->tag[procfs_entries->count++], &procfs_entry,
178 sizeof(procfs_entry));
179 }
180 fclose(fp);
181 return 0;
182}
183
184static enum ioctl_ret get_filtered_ioctl_entries(struct allocinfo_tag_data_vec *tags,
185 const struct allocinfo_filter *filter,
186 __u64 start_pos)
187{
188 int fd = open(ALLOCINFO_PROC, O_RDONLY);
189
190 if (fd < 0) {
191 ksft_print_msg("Failed to open " ALLOCINFO_PROC " for IOCTL\n");
192 return IOCTL_FAILURE;
193 }
194
195 struct allocinfo_content_id start_cont_id, end_cont_id;
196 struct allocinfo_get_at get_at_params;
197 const int max_retries = 10;
198 int retry_count = 0;
199 int status;
200
201 /*
202 * __allocinfo_get_content_id may return different values if a kernel module was loaded
203 * between the two calls. If that happens, the data gathered cannot be considered consistent
204 * and hence needs to be fetched again to avoid flakiness.
205 */
206 do {
207 if (__allocinfo_get_content_id(fd, &start_cont_id)) {
208 ksft_print_msg("allocinfo_get_content_id failed\n");
209 status = IOCTL_FAILURE;
210 break;
211 }
212
213 memset(tags, 0, sizeof(*tags));
214 memset(&get_at_params, 0, sizeof(get_at_params));
215 memcpy(&get_at_params.filter, filter, sizeof(*filter));
216 get_at_params.pos = start_pos;
217 if (__allocinfo_get_at(fd, &get_at_params)) {
218 ksft_print_msg("allocinfo_get_at failed\n");
219 status = IOCTL_FAILURE;
220 break;
221 }
222 memcpy(&tags->tag[tags->count++], &get_at_params.data, sizeof(get_at_params.data));
223
224 while (tags->count < VEC_MAX_ENTRIES &&
225 __allocinfo_get_next(fd, &tags->tag[tags->count]) == 0)
226 tags->count++;
227
228 if (__allocinfo_get_content_id(fd, &end_cont_id)) {
229 ksft_print_msg("allocinfo_get_content_id failed\n");
230 status = IOCTL_FAILURE;
231 break;
232 }
233
234 if (start_cont_id.id == end_cont_id.id) {
235 status = IOCTL_SUCCESS;
236 } else {
237 ksft_print_msg("allocinfo_get_content_id mismatch, retrying...\n");
238 status = IOCTL_INVALID_DATA;
239 }
240 } while (status == IOCTL_INVALID_DATA && retry_count++ < max_retries);
241
242 close(fd);
243 return status;
244}
245
246static int run_filter_test(const struct allocinfo_filter *filter)
247{
248 struct allocinfo_tag_data_vec *tags = malloc(sizeof(*tags));
249 struct allocinfo_tag_data_vec *procfs_entries = malloc(sizeof(*procfs_entries));
250 int ioctl_status;
251 int ret = KSFT_PASS;
252
253 if (!tags || !procfs_entries) {
254 ksft_print_msg("Memory allocation failed.\n");
255 ret = KSFT_FAIL;
256 goto exit;
257 }
258
259 if (get_filtered_procfs_entries(procfs_entries, filter)) {
260 ksft_print_msg("Error retrieving entries from " ALLOCINFO_PROC "\n");
261 ret = KSFT_SKIP;
262 goto exit;
263 }
264
265 if (procfs_entries->count == 0) {
266 ksft_print_msg("No entries found in " ALLOCINFO_PROC ", skipping test\n");
267 ret = KSFT_SKIP;
268 goto exit;
269 }
270
271 ioctl_status = get_filtered_ioctl_entries(tags, filter, 0);
272 if (ioctl_status == IOCTL_INVALID_DATA) {
273 ksft_print_msg("Trouble retrieving valid IOCTL entries, skipping.\n");
274 ret = KSFT_SKIP;
275 goto exit;
276 }
277 if (ioctl_status == IOCTL_FAILURE) {
278 ksft_print_msg("Error retrieving IOCTL entries.\n");
279 ret = KSFT_FAIL;
280 goto exit;
281 }
282
283 if (!match_entries(procfs_entries, tags, false, false, true, true, true))
284 ret = KSFT_FAIL;
285
286exit:
287 free(tags);
288 free(procfs_entries);
289 return ret;
290}
291
292static int test_filename_filter(void)
293{
294 struct allocinfo_filter filter;
295 const char *target_filename = "mm/memory.c";
296
297 memset(&filter, 0, sizeof(filter));
298 filter.mask |= ALLOCINFO_FILTER_MASK_FILENAME;
299 strncpy(filter.fields.filename, target_filename, ALLOCINFO_STR_SIZE);
300
301 return run_filter_test(&filter);
302}
303
304static int test_function_filter(void)
305{
306 struct allocinfo_filter filter;
307 const char *target_function = "dup_mm";
308
309 memset(&filter, 0, sizeof(filter));
310 filter.mask |= ALLOCINFO_FILTER_MASK_FUNCTION;
311 strncpy(filter.fields.function, target_function, ALLOCINFO_STR_SIZE);
312
313 return run_filter_test(&filter);
314}
315
316static int test_size_filter(void)
317{
318 int fd;
319 struct allocinfo_tag_data_vec *tags = malloc(sizeof(*tags));
320 struct allocinfo_tag_data_vec *procfs_entries = malloc(sizeof(*procfs_entries));
321 struct allocinfo_filter filter;
322 int ret = KSFT_PASS;
323 __u64 target_size, i, pos;
324 struct allocinfo_tag_data *found_tag = NULL;
325 const char *target_function = "do_init_module";
326 struct allocinfo_content_id start_cont_id, end_cont_id;
327 int retry = 0;
328 const int max_retries = 10;
329
330 if (!tags || !procfs_entries) {
331 ksft_print_msg("Memory allocation failed.\n");
332 ret = KSFT_FAIL;
333 goto freemem;
334 }
335
336 fd = open(ALLOCINFO_PROC, O_RDONLY);
337 if (fd < 0) {
338 ksft_print_msg("Failed to open " ALLOCINFO_PROC ": %s\n", strerror(errno));
339 ret = KSFT_SKIP;
340 goto freemem;
341 }
342
343 do {
344 found_tag = NULL;
345 pos = 0;
346
347 if (__allocinfo_get_content_id(fd, &start_cont_id)) {
348 ksft_print_msg("allocinfo_get_content_id failed\n");
349 ret = KSFT_FAIL;
350 goto exit;
351 }
352
353 memset(&filter, 0, sizeof(filter));
354 filter.mask |= ALLOCINFO_FILTER_MASK_FUNCTION;
355 strncpy(filter.fields.function, target_function, ALLOCINFO_STR_SIZE);
356
357 if (get_filtered_procfs_entries(procfs_entries, &filter)) {
358 ksft_print_msg("Error retrieving entries from " ALLOCINFO_PROC "\n");
359 ret = KSFT_SKIP;
360 goto exit;
361 }
362
363 if (procfs_entries->count == 0) {
364 ksft_print_msg("Function %s not found in procfs\n", target_function);
365 ret = KSFT_SKIP;
366 goto exit;
367 }
368
369 target_size = procfs_entries->tag[0].counter.bytes;
370
371 memset(&filter, 0, sizeof(filter));
372 filter.mask |= ALLOCINFO_FILTER_MASK_MIN_SIZE | ALLOCINFO_FILTER_MASK_MAX_SIZE;
373 filter.min_size = target_size;
374 filter.max_size = target_size;
375
376 while (1) {
377 struct allocinfo_get_at get_at_params;
378
379 memset(&get_at_params, 0, sizeof(get_at_params));
380 memcpy(&get_at_params.filter, &filter, sizeof(filter));
381 get_at_params.pos = pos;
382
383 if (__allocinfo_get_at(fd, &get_at_params))
384 break;
385
386 tags->count = 0;
387 memcpy(&tags->tag[tags->count++], &get_at_params.data,
388 sizeof(get_at_params.data));
389
390 while (tags->count < VEC_MAX_ENTRIES &&
391 __allocinfo_get_next(fd, &tags->tag[tags->count]) == 0)
392 tags->count++;
393
394 for (i = 0; i < tags->count; i++) {
395 if (strcmp(tags->tag[i].tag.function, target_function) == 0) {
396 found_tag = &tags->tag[i];
397 break;
398 }
399 }
400
401 if (found_tag || tags->count < VEC_MAX_ENTRIES)
402 break;
403
404 pos += tags->count;
405 }
406
407 if (__allocinfo_get_content_id(fd, &end_cont_id)) {
408 ksft_print_msg("allocinfo_get_content_id failed\n");
409 ret = KSFT_FAIL;
410 goto exit;
411 }
412
413 if (start_cont_id.id == end_cont_id.id)
414 break;
415
416 ksft_print_msg("Module load detected during size verification, retrying...\n");
417 } while (retry++ < max_retries);
418
419 if (start_cont_id.id == end_cont_id.id && !found_tag) {
420 ksft_print_msg("Entry with function %s not found in IOCTL results\n",
421 target_function);
422 ret = KSFT_FAIL;
423 } else if (start_cont_id.id != end_cont_id.id) {
424 ksft_print_msg("Failed to match content_ids for procfs and IOCTL, skipping...\n");
425 ret = KSFT_SKIP;
426 } else if (found_tag && found_tag->counter.bytes != target_size) {
427 ksft_print_msg("IOCTL entry size %llu does not match target size %llu\n",
428 found_tag->counter.bytes, target_size);
429 ret = KSFT_FAIL;
430 }
431
432exit:
433 close(fd);
434freemem:
435 free(tags);
436 free(procfs_entries);
437 return ret;
438}
439
440static int test_lineno_filter(void)
441{
442 struct allocinfo_tag_data_vec *tags = malloc(sizeof(*tags));
443 struct allocinfo_tag_data_vec *procfs_entries = malloc(sizeof(*procfs_entries));
444 struct allocinfo_filter filter;
445 enum ioctl_ret ioctl_status;
446 int ret = KSFT_PASS;
447 __u64 target_lineno, i;
448 struct allocinfo_tag_data *target_tag;
449 bool found = false;
450
451 if (!tags || !procfs_entries) {
452 ksft_print_msg("Memory allocation failed.\n");
453 ret = KSFT_FAIL;
454 goto exit;
455 }
456
457 memset(&filter, 0, sizeof(filter));
458
459 if (get_filtered_procfs_entries(procfs_entries, &filter)) {
460 ksft_print_msg("Error retrieving entries from " ALLOCINFO_PROC "\n");
461 ret = KSFT_SKIP;
462 goto exit;
463 }
464 if (procfs_entries->count == 0) {
465 ksft_print_msg("Could not retrieve procfs entries\n");
466 ret = KSFT_SKIP;
467 goto exit;
468 }
469 /*
470 * We depend on the procfs results to determine the line number for the filter before
471 * making the ioctl query. Hence, we cannot reuse run_filter_test here.
472 */
473 target_tag = &procfs_entries->tag[0];
474 target_lineno = target_tag->tag.lineno;
475
476 filter.mask |= ALLOCINFO_FILTER_MASK_LINENO;
477 filter.fields.lineno = target_lineno;
478
479 ioctl_status = get_filtered_ioctl_entries(tags, &filter, 0);
480 if (ioctl_status == IOCTL_INVALID_DATA) {
481 ksft_print_msg("Trouble retrieving valid IOCTL entries, skipping.\n");
482 ret = KSFT_SKIP;
483 goto exit;
484 }
485 if (ioctl_status == IOCTL_FAILURE) {
486 ksft_print_msg("Error retrieving IOCTL entries.\n");
487 ret = KSFT_FAIL;
488 goto exit;
489 }
490
491 for (i = 0; i < tags->count; i++) {
492 if (tags->tag[i].tag.lineno != target_lineno) {
493 ksft_print_msg("IOCTL entry %llu has incorrect lineno %llu.\n",
494 i, tags->tag[i].tag.lineno);
495 ret = KSFT_FAIL;
496 goto exit;
497 }
498
499 if (strncmp(tags->tag[i].tag.function, target_tag->tag.function,
500 ALLOCINFO_STR_SIZE) == 0 &&
501 strncmp(tags->tag[i].tag.filename, target_tag->tag.filename,
502 ALLOCINFO_STR_SIZE) == 0)
503 found = true;
504 }
505
506 if (!found) {
507 ksft_print_msg("Original procfs entry not found in IOCTL lineno filter results.\n");
508 ret = KSFT_FAIL;
509 }
510
511exit:
512 free(tags);
513 free(procfs_entries);
514 return ret;
515}
516
517int main(int argc, char *argv[])
518{
519 int ret;
520
521 ksft_set_plan(4);
522
523 ret = test_filename_filter();
524 if (ret == KSFT_SKIP)
525 ksft_test_result_skip("Skipping test_filename_filter\n");
526 else
527 ksft_test_result(ret == KSFT_PASS, "test_filename_filter\n");
528
529 ret = test_function_filter();
530 if (ret == KSFT_SKIP)
531 ksft_test_result_skip("Skipping test_function_filter\n");
532 else
533 ksft_test_result(ret == KSFT_PASS, "test_function_filter\n");
534
535 ret = test_size_filter();
536 if (ret == KSFT_SKIP)
537 ksft_test_result_skip("Skipping test_size_filter\n");
538 else
539 ksft_test_result(ret == KSFT_PASS, "test_size_filter\n");
540
541 ret = test_lineno_filter();
542 if (ret == KSFT_SKIP)
543 ksft_test_result_skip("Skipping test_lineno_filter\n");
544 else
545 ksft_test_result(ret == KSFT_PASS, "test_lineno_filter\n");
546
547 ksft_finished();
548}
tools/testing/selftests/cgroup/lib/include/cgroup_util.h+1−0
@@ -7,6 +7,7 @@ · 6 unmodified lines
7#endif7#endif
8 8
9#define MB(x) (x << 20)9#define MB(x) (x << 20)
10#define GB(x) ((unsigned long long)(x) << 30)
10 11
11#define NSEC_PER_USEC 1000L12#define NSEC_PER_USEC 1000L
12#define USEC_PER_SEC 1000000L13#define USEC_PER_SEC 1000000L
tools/testing/selftests/cgroup/test_zswap.c+11−2
@@ -20,6 +20,7 @@ static int page_size; · 19 unmodified lines
20 20
21#define PATH_ZSWAP "/sys/module/zswap"21#define PATH_ZSWAP "/sys/module/zswap"
22#define PATH_ZSWAP_ENABLED "/sys/module/zswap/parameters/enabled"22#define PATH_ZSWAP_ENABLED "/sys/module/zswap/parameters/enabled"
23#define PATH_ZSWAP_STORED_PAGES "/sys/kernel/debug/zswap/stored_pages"
23 24
24static int read_int(const char *path, size_t *value)25static int read_int(const char *path, size_t *value)
25{26{
@@ -55,7 +56,7 @@ static int read_min_free_kb(size_t *value) · 29 unmodified lines
55 56
56static int get_zswap_stored_pages(size_t *value)57static int get_zswap_stored_pages(size_t *value)
57{58{
58 return read_int("/sys/kernel/debug/zswap/stored_pages", value);59 return read_int(PATH_ZSWAP_STORED_PAGES, value);
59}60}
60 61
61static long get_cg_wb_count(const char *cg)62static long get_cg_wb_count(const char *cg)
@@ -570,8 +571,16 @@ static int test_no_kmem_bypass(const char *root) · 508 unmodified lines
570 /* Read sys info and compute test values accordingly */571 /* Read sys info and compute test values accordingly */
571 if (sysinfo(&sys_info) != 0)572 if (sysinfo(&sys_info) != 0)
572 return KSFT_FAIL;573 return KSFT_FAIL;
573 if (sys_info.totalram > 5000000000)574 if (sys_info.totalram > GB(4)) {
575 ksft_print_msg(
576 "requires less than 4GB total ram, sys_info.totalram: %.1fGB\n",
577 (double)sys_info.totalram / GB(1));
574 return KSFT_SKIP;578 return KSFT_SKIP;
579 }
580 if (access(PATH_ZSWAP_STORED_PAGES, R_OK)) {
581 ksft_print_msg("debugfs not mounted at /sys/kernel/debug\n");
582 return KSFT_SKIP;
583 }
575 values = mmap(0, sizeof(struct no_kmem_bypass_child_args), PROT_READ |584 values = mmap(0, sizeof(struct no_kmem_bypass_child_args), PROT_READ |
576 PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);585 PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
577 if (values == MAP_FAILED)586 if (values == MAP_FAILED)
tools/testing/selftests/mm/.gitignore+9−67
@@ -1,68 +1,10 @@
1# SPDX-License-Identifier: GPL-2.0-only1# SPDX-License-Identifier: GPL-2.0-only
2cow2*
3hugepage-mmap3!/**/
4hugepage-mremap4!*.c
5hugepage-shm5!*.h
6hugepage-vmemmap6!*.sh
7hugetlb-mmap7!.gitignore
8hugetlb-mremap8!Makefile
9hugetlb-shm9!config
10hugetlb-vmemmap10!settings
11hugetlb-madvise
12hugetlb-read-hwpoison
13hugetlb-soft-offline
14khugepaged
15map_hugetlb
16map_populate
17thuge-gen
18compaction_test
19memory-failure
20migration
21mlock2-tests
22mrelease_test
23mremap_dontunmap
24mremap_test
25on-fault-limit
26transhuge-stress
27pagemap_ioctl
28pfnmap
29process_madv
30*.tmp*
31protection_keys
32protection_keys_32
33protection_keys_64
34madv_populate
35uffd-stress
36uffd-unit-tests
37uffd-wp-mremap
38mlock-intersect-test
39mlock-random-test
40virtual_address_range
41gup_test
42va_128TBswitch
43map_fixed_noreplace
44write_to_hugetlbfs
45hmm-tests
46memfd_secret
47soft-dirty
48split_huge_page_test
49ksm_tests
50local_config.h
51local_config.mk
52ksm_functional_tests
53mdwe_test
54gup_longterm
55mkdirty
56va_high_addr_switch
57hugetlb_fault_after_madv
58hugetlb_madv_vs_map
59mseal_test
60droppable
61hugetlb_dio
62pkey_sighandler_tests_32
63pkey_sighandler_tests_64
64guard-regions
65merge
66prctl_thp_disable
67rmap
68folio_split_race_test
tools/testing/selftests/mm/Makefile+4−3
@@ -5,7 +5,7 @@ · 4 unmodified lines
5# script so kunit knows to run it, and add it to the list below.5# script so kunit knows to run it, and add it to the list below.
6# If you do not YOUR TESTS WILL NOT RUN IN THE CI.6# If you do not YOUR TESTS WILL NOT RUN IN THE CI.
7 7
8LOCAL_HDRS += $(selfdir)/mm/local_config.h $(top_srcdir)/mm/gup_test.h8LOCAL_HDRS += $(selfdir)/mm/local_config.h_gen $(top_srcdir)/mm/gup_test.h
9LOCAL_HDRS += $(selfdir)/mm/mseal_helpers.h9LOCAL_HDRS += $(selfdir)/mm/mseal_helpers.h
10 10
11include local_config.mk11include local_config.mk
@@ -149,6 +149,7 @@ TEST_PROGS += ksft_gup_test.sh · 137 unmodified lines
149TEST_PROGS += ksft_hmm.sh149TEST_PROGS += ksft_hmm.sh
150TEST_PROGS += ksft_hugetlb.sh150TEST_PROGS += ksft_hugetlb.sh
151TEST_PROGS += ksft_hugevm.sh151TEST_PROGS += ksft_hugevm.sh
152TEST_PROGS += ksft_kmemleak_confirm.sh
152TEST_PROGS += ksft_kmemleak_dedup.sh153TEST_PROGS += ksft_kmemleak_dedup.sh
153TEST_PROGS += ksft_ksm.sh154TEST_PROGS += ksft_ksm.sh
154TEST_PROGS += ksft_ksm_numa.sh155TEST_PROGS += ksft_ksm_numa.sh
@@ -261,11 +262,11 @@ $(OUTPUT)/migration: LDLIBS += -lnuma · 106 unmodified lines
261 262
262$(OUTPUT)/rmap: LDLIBS += -lnuma263$(OUTPUT)/rmap: LDLIBS += -lnuma
263 264
264local_config.mk local_config.h: check_config.sh265local_config.mk local_config.h_gen: check_config.sh
265 $(call msg,CHK,config,$@)266 $(call msg,CHK,config,$@)
266 $(Q)CC="$(CC)" CFLAGS="$(CFLAGS)" ./check_config.sh267 $(Q)CC="$(CC)" CFLAGS="$(CFLAGS)" ./check_config.sh
267 268
268EXTRA_CLEAN += local_config.mk local_config.h269EXTRA_CLEAN += local_config.mk local_config.h_gen
269 270
270ifeq ($(IOURING_EXTRA_LIBS),)271ifeq ($(IOURING_EXTRA_LIBS),)
271all: warn_missing_liburing272all: warn_missing_liburing
tools/testing/selftests/mm/check_config.sh+1−1
@@ -4,7 +4,7 @@ · 3 unmodified lines
4# Probe for libraries and create header files to record the results. Both C4# Probe for libraries and create header files to record the results. Both C
5# header files and Makefile include fragments are created.5# header files and Makefile include fragments are created.
6 6
7OUTPUT_H_FILE=local_config.h7OUTPUT_H_FILE=local_config.h_gen
8OUTPUT_MKFILE=local_config.mk8OUTPUT_MKFILE=local_config.mk
9 9
10tmpname=$(mktemp)10tmpname=$(mktemp)
tools/testing/selftests/mm/compaction_test.c+21−17
@@ -29,30 +29,34 @@ struct map_list { · 28 unmodified lines
29 29
30int read_memory_info(unsigned long *memfree, unsigned long *hugepagesize)30int read_memory_info(unsigned long *memfree, unsigned long *hugepagesize)
31{31{
32 char buffer[256] = {0};32 char buffer[256];
33 char *cmd = "cat /proc/meminfo | grep -i memfree | grep -o '[0-9]*'";33 int found = 0;
34 FILE *cmdfile = popen(cmd, "r");34 FILE *file;
35 int ret = -1;
35 36
36 if (!(fgets(buffer, sizeof(buffer), cmdfile))) {37 file = fopen("/proc/meminfo", "r");
37 ksft_print_msg("Failed to read meminfo: %s\n", strerror(errno));38 if (!file) {
39 ksft_print_msg("Failed to open /proc/meminfo: %s\n",
40 strerror(errno));
38 return -1;41 return -1;
39 }42 }
40 43
41 pclose(cmdfile);44 while (fgets(buffer, sizeof(buffer), file) && found != 2) {
42 45 if (sscanf(buffer, "MemFree: %lu kB", memfree) == 1 ||
43 *memfree = atoll(buffer);46 sscanf(buffer, "Hugepagesize: %lu kB", hugepagesize) == 1)
44 cmd = "cat /proc/meminfo | grep -i hugepagesize | grep -o '[0-9]*'";47 found++;
45 cmdfile = popen(cmd, "r");
46
47 if (!(fgets(buffer, sizeof(buffer), cmdfile))) {
48 ksft_print_msg("Failed to read meminfo: %s\n", strerror(errno));
49 return -1;
50 }48 }
51 49
52 pclose(cmdfile);50 if (ferror(file))
53 *hugepagesize = atoll(buffer);51 ksft_print_msg("Failed to read /proc/meminfo: %s\n",
52 strerror(errno));
53 else if (found != 2)
54 ksft_print_msg("Failed to parse /proc/meminfo\n");
55 else
56 ret = 0;
54 57
55 return 0;58 fclose(file);
59 return ret;
56}60}
57 61
58int prereq(void)62int prereq(void)
tools/testing/selftests/mm/cow.c+8−3
@@ -21,7 +21,7 @@ · 20 unmodified lines
21#include <sys/wait.h>21#include <sys/wait.h>
22#include <linux/memfd.h>22#include <linux/memfd.h>
23 23
24#include "local_config.h"24#include "local_config.h_gen"
25#ifdef LOCAL_CONFIG_HAVE_LIBURING25#ifdef LOCAL_CONFIG_HAVE_LIBURING
26#include <liburing.h>26#include <liburing.h>
27#endif /* LOCAL_CONFIG_HAVE_LIBURING */27#endif /* LOCAL_CONFIG_HAVE_LIBURING */
@@ -1718,8 +1718,13 @@ static void run_with_tmpfile(non_anon_test_fn fn, const char *desc) · 1690 unmodified lines
1718 1718
1719 /* File consists of a single page filled with zeroes. */1719 /* File consists of a single page filled with zeroes. */
1720 if (fallocate(fd, 0, 0, pagesize)) {1720 if (fallocate(fd, 0, 0, pagesize)) {
1721 ksft_perror("fallocate() failed");1721 if (errno == EOPNOTSUPP) {
1722 log_test_result(KSFT_FAIL);1722 ksft_print_msg("fallocate() not supported by filesystem\n");
1723 log_test_result(KSFT_SKIP);
1724 } else {
1725 ksft_perror("fallocate() failed");
1726 log_test_result(KSFT_FAIL);
1727 }
1723 goto close;1728 goto close;
1724 }1729 }
1725 1730
tools/testing/selftests/mm/folio_split_race_test.c+1−1
@@ -182,7 +182,7 @@ static uint64_t run_iteration(void) · 181 unmodified lines
182 for (i = 0; i < TOTAL_PAGES; i++)182 for (i = 0; i < TOTAL_PAGES; i++)
183 fill_page(mmap_base, i);183 fill_page(mmap_base, i);
184 184
185 if (!check_huge_shmem(mmap_base, NR_PMD_PAGE, pmd_pagesize))185 if (!check_huge_shmem(mmap_base, FILE_SIZE, NR_PMD_PAGE, pmd_pagesize))
186 ksft_exit_fail_msg("No shmem THP is allocated\n");186 ksft_exit_fail_msg("No shmem THP is allocated\n");
187 187
188 if (pthread_barrier_init(&ctl.barrier, NULL, NUM_READER_THREADS + 1) != 0)188 if (pthread_barrier_init(&ctl.barrier, NULL, NUM_READER_THREADS + 1) != 0)
tools/testing/selftests/mm/guard-regions.c+7−3
@@ -1912,7 +1912,7 @@ TEST_F(guard_regions, hole_punch) · 1911 unmodified lines
1912{1912{
1913 const unsigned long page_size = self->page_size;1913 const unsigned long page_size = self->page_size;
1914 char *ptr;1914 char *ptr;
1915 int i;1915 int i, ret;
1916 1916
1917 if (variant->backing == ANON_BACKED)1917 if (variant->backing == ANON_BACKED)
1918 SKIP(return, "Truncation test specific to file-backed");1918 SKIP(return, "Truncation test specific to file-backed");
@@ -1944,8 +1944,12 @@ TEST_F(guard_regions, hole_punch) · 25 unmodified lines
1944 }1944 }
1945 1945
1946 /* Now hole punch the guarded region. */1946 /* Now hole punch the guarded region. */
1947 ASSERT_EQ(madvise(&ptr[3 * page_size], 4 * page_size,1947 ret = madvise(&ptr[3 * page_size], 4 * page_size, MADV_REMOVE);
1948 MADV_REMOVE), 0);1948 if (ret == -1 && errno == EOPNOTSUPP) {
1949 ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
1950 SKIP(return, "MADV_REMOVE not supported by filesystem");
1951 }
1952 ASSERT_EQ(ret, 0);
1949 1953
1950 /* Ensure guard regions remain. */1954 /* Ensure guard regions remain. */
1951 for (i = 0; i < 10; i++) {1955 for (i = 0; i < 10; i++) {
tools/testing/selftests/mm/gup_longterm.c+1−1
@@ -21,7 +21,7 @@ · 20 unmodified lines
21#include <linux/magic.h>21#include <linux/magic.h>
22#include <linux/memfd.h>22#include <linux/memfd.h>
23 23
24#include "local_config.h"24#include "local_config.h_gen"
25#ifdef LOCAL_CONFIG_HAVE_LIBURING25#ifdef LOCAL_CONFIG_HAVE_LIBURING
26#include <liburing.h>26#include <liburing.h>
27#endif /* LOCAL_CONFIG_HAVE_LIBURING */27#endif /* LOCAL_CONFIG_HAVE_LIBURING */
tools/testing/selftests/mm/khugepaged.c+155−49
@@ -26,9 +26,11 @@ · 25 unmodified lines
26 26
27#define BASE_ADDR ((void *)(1UL << 30))27#define BASE_ADDR ((void *)(1UL << 30))
28static unsigned long hpage_pmd_size;28static unsigned long hpage_pmd_size;
29static int hpage_pmd_order;
29static unsigned long page_size;30static unsigned long page_size;
30static int hpage_pmd_nr;31static int hpage_pmd_nr;
31static int anon_order;32static int anon_order;
33static int collapse_order;
32 34
33#define PID_SMAPS "/proc/self/smaps"35#define PID_SMAPS "/proc/self/smaps"
34#define TEST_FILE "collapse_test_file"36#define TEST_FILE "collapse_test_file"
@@ -51,7 +53,7 @@ struct mem_ops { · 16 unmodified lines
51 void *(*setup_area)(int nr_hpages);53 void *(*setup_area)(int nr_hpages);
52 void (*cleanup_area)(void *p, unsigned long size);54 void (*cleanup_area)(void *p, unsigned long size);
53 void (*fault)(void *p, unsigned long start, unsigned long end);55 void (*fault)(void *p, unsigned long start, unsigned long end);
54 bool (*check_huge)(void *addr, int nr_hpages);56 bool (*check_huge)(void *addr, size_t len, int nr_hpages, unsigned long hpage_size);
55 const char *name;57 const char *name;
56};58};
57 59
@@ -69,6 +71,7 @@ struct collapse_context { · 11 unmodified lines
69};71};
70 72
71static struct collapse_context *khugepaged_context;73static struct collapse_context *khugepaged_context;
74static struct collapse_context *mthp_khugepaged_context;
72static struct collapse_context *madvise_context;75static struct collapse_context *madvise_context;
73 76
74struct file_info {77struct file_info {
@@ -121,7 +124,8 @@ static void get_finfo(const char *dir) · 46 unmodified lines
121 char *str, *end;124 char *str, *end;
122 125
123 finfo.dir = dir;126 finfo.dir = dir;
124 stat(finfo.dir, &path_stat);127 if (stat(finfo.dir, &path_stat))
128 ksft_exit_fail_perror("stat()");
125 if (!S_ISDIR(path_stat.st_mode))129 if (!S_ISDIR(path_stat.st_mode))
126 ksft_exit_fail_msg("%s: Not a directory (%s)\n", __func__, finfo.dir);130 ksft_exit_fail_msg("%s: Not a directory (%s)\n", __func__, finfo.dir);
127 if (snprintf(finfo.path, sizeof(finfo.path), "%s/" TEST_FILE,131 if (snprintf(finfo.path, sizeof(finfo.path), "%s/" TEST_FILE,
@@ -138,8 +142,8 @@ static void get_finfo(const char *dir) · 10 unmodified lines
138 major(path_stat.st_dev), minor(path_stat.st_dev))142 major(path_stat.st_dev), minor(path_stat.st_dev))
139 >= sizeof(path))143 >= sizeof(path))
140 ksft_exit_fail_msg("%s: Pathname is too long\n", __func__);144 ksft_exit_fail_msg("%s: Pathname is too long\n", __func__);
141 if (read_file(path, buf, sizeof(buf)) < 0)145 if (!read_file(path, buf, sizeof(buf)))
142 ksft_exit_fail_perror("read_file(read_num)");146 ksft_exit_fail_perror("read_file(uevent)");
143 if (strstr(buf, "DEVTYPE=disk")) {147 if (strstr(buf, "DEVTYPE=disk")) {
144 /* Found it */148 /* Found it */
145 if (snprintf(finfo.dev_queue_read_ahead_path,149 if (snprintf(finfo.dev_queue_read_ahead_path,
@@ -276,7 +280,7 @@ static void *alloc_hpage(struct mem_ops *ops) · 130 unmodified lines
276 ksft_print_msg("Allocate huge page...");280 ksft_print_msg("Allocate huge page...");
277 if (madvise_collapse_retry(p, hpage_pmd_size))281 if (madvise_collapse_retry(p, hpage_pmd_size))
278 ksft_exit_fail_perror("madvise(MADV_COLLAPSE)");282 ksft_exit_fail_perror("madvise(MADV_COLLAPSE)");
279 if (!ops->check_huge(p, 1))283 if (!ops->check_huge(p, hpage_pmd_size, 1, hpage_pmd_size))
280 ksft_exit_fail_perror("madvise(MADV_COLLAPSE)");284 ksft_exit_fail_perror("madvise(MADV_COLLAPSE)");
281 if (madvise(p, hpage_pmd_size, MADV_HUGEPAGE))285 if (madvise(p, hpage_pmd_size, MADV_HUGEPAGE))
282 ksft_exit_fail_perror("madvise(MADV_HUGEPAGE)");286 ksft_exit_fail_perror("madvise(MADV_HUGEPAGE)");
@@ -310,9 +314,10 @@ static void anon_fault(void *p, unsigned long start, unsigned long end) · 27 unmodified lines
310 fill_memory(p, start, end);314 fill_memory(p, start, end);
311}315}
312 316
313static bool anon_check_huge(void *addr, int nr_hpages)317static bool anon_check_huge(void *addr, size_t len, int nr_hpages,
318 unsigned long hpage_size)
314{319{
315 return check_huge_anon(addr, nr_hpages, hpage_pmd_size);320 return check_huge_anon(addr, len, nr_hpages, hpage_size);
316}321}
317 322
318static void *file_setup_area_common(int nr_hpages, enum file_setup_ops setup)323static void *file_setup_area_common(int nr_hpages, enum file_setup_ops setup)
@@ -412,13 +417,14 @@ static void file_fault_write(void *p, unsigned long start, unsigned long end) · 93 unmodified lines
412 ksft_exit_fail_perror("madvise(MADV_POPULATE_WRITE)");417 ksft_exit_fail_perror("madvise(MADV_POPULATE_WRITE)");
413}418}
414 419
415static bool file_check_huge(void *addr, int nr_hpages)420static bool file_check_huge(void *addr, size_t len, int nr_hpages,
421 unsigned long hpage_size)
416{422{
417 switch (finfo.type) {423 switch (finfo.type) {
418 case VMA_FILE:424 case VMA_FILE:
419 return check_huge_file(addr, nr_hpages, hpage_pmd_size);425 return check_huge_file(addr, len, nr_hpages, hpage_size);
420 case VMA_SHMEM:426 case VMA_SHMEM:
421 return check_huge_shmem(addr, nr_hpages, hpage_pmd_size);427 return check_huge_shmem(addr, len, nr_hpages, hpage_size);
422 default:428 default:
423 exit(EXIT_FAILURE);429 exit(EXIT_FAILURE);
424 return false;430 return false;
@@ -448,9 +454,10 @@ static void shmem_cleanup_area(void *p, unsigned long size) · 23 unmodified lines
448 close(finfo.fd);454 close(finfo.fd);
449}455}
450 456
451static bool shmem_check_huge(void *addr, int nr_hpages)457static bool shmem_check_huge(void *addr, size_t len, int nr_hpages,
458 unsigned long hpage_size)
452{459{
453 return check_huge_shmem(addr, nr_hpages, hpage_pmd_size);460 return check_huge_shmem(addr, len, nr_hpages, hpage_size);
454}461}
455 462
456static struct mem_ops __anon_ops = {463static struct mem_ops __anon_ops = {
@@ -533,7 +540,7 @@ static void __madvise_collapse(const char *msg, char *p, int nr_hpages, · 76 unmodified lines
533 ret = madvise_collapse_retry(p, nr_hpages * hpage_pmd_size);540 ret = madvise_collapse_retry(p, nr_hpages * hpage_pmd_size);
534 if (((bool)ret) == expect)541 if (((bool)ret) == expect)
535 fail("Fail: Bad return value");542 fail("Fail: Bad return value");
536 else if (!ops->check_huge(p, expect ? nr_hpages : 0))543 else if (!ops->check_huge(p, nr_hpages * hpage_pmd_size, expect ? nr_hpages : 0, hpage_pmd_size))
537 fail("Fail: check_huge()");544 fail("Fail: check_huge()");
538 else545 else
539 success("OK");546 success("OK");
@@ -545,30 +552,31 @@ static void madvise_collapse(const char *msg, char *p, int nr_hpages, · 5 unmodified lines
545 struct mem_ops *ops, bool expect)552 struct mem_ops *ops, bool expect)
546{553{
547 /* Sanity check */554 /* Sanity check */
548 if (!ops->check_huge(p, 0))555 if (!ops->check_huge(p, nr_hpages * hpage_pmd_size, 0, hpage_pmd_size))
549 ksft_exit_fail_msg("Unexpected huge page\n");556 ksft_exit_fail_msg("Unexpected huge page\n");
550 __madvise_collapse(msg, p, nr_hpages, ops, expect);557 __madvise_collapse(msg, p, nr_hpages, ops, expect);
551}558}
552 559
553#define TICK 500000560#define TICK 500000
554static bool wait_for_scan(const char *msg, char *p, int nr_hpages,561static bool wait_for_scan(const char *msg, char *p, size_t len,
555 struct mem_ops *ops)562 int nr_hpages, int collap_order, struct mem_ops *ops)
556{563{
564 unsigned long hpage_size = page_size << collap_order;
557 int full_scans;565 int full_scans;
558 int timeout = 6; /* 3 seconds */566 int timeout = 6; /* 3 seconds */
559 567
560 /* Sanity check */568 /* Sanity check */
561 if (!ops->check_huge(p, 0))569 if (!ops->check_huge(p, len, 0, hpage_size))
562 ksft_exit_fail_msg("Unexpected huge page\n");570 ksft_exit_fail_msg("Unexpected huge page\n");
563 571
564 madvise(p, nr_hpages * hpage_pmd_size, MADV_HUGEPAGE);572 madvise(p, len, MADV_HUGEPAGE);
565 573
566 /* Wait until the second full_scan completed */574 /* Wait until the second full_scan completed */
567 full_scans = thp_read_num("khugepaged/full_scans") + 2;575 full_scans = thp_read_num("khugepaged/full_scans") + 2;
568 576
569 ksft_print_msg("%s...", msg);577 ksft_print_msg("%s...", msg);
570 while (timeout--) {578 while (timeout--) {
571 if (ops->check_huge(p, nr_hpages))579 if (ops->check_huge(p, len, nr_hpages, hpage_size))
572 break;580 break;
573 if (thp_read_num("khugepaged/full_scans") >= full_scans)581 if (thp_read_num("khugepaged/full_scans") >= full_scans)
574 break;582 break;
@@ -582,6 +590,8 @@ static bool wait_for_scan(const char *msg, char *p, int nr_hpages, · 7 unmodified lines
582static void khugepaged_collapse(const char *msg, char *p, int nr_hpages,590static void khugepaged_collapse(const char *msg, char *p, int nr_hpages,
583 struct mem_ops *ops, bool expect)591 struct mem_ops *ops, bool expect)
584{592{
593 size_t len = nr_hpages * hpage_pmd_size;
594
585 /*595 /*
586 * read&write file collapse fails since khugepaged does not flush596 * read&write file collapse fails since khugepaged does not flush
587 * the target dirty folios597 * the target dirty folios
@@ -589,7 +599,7 @@ static void khugepaged_collapse(const char *msg, char *p, int nr_hpages, · 1 unmodified line
589 if (!is_tmpfs(ops) && ops == &__read_write_file_write_ops)599 if (!is_tmpfs(ops) && ops == &__read_write_file_write_ops)
590 expect = false;600 expect = false;
591 601
592 if (wait_for_scan(msg, p, nr_hpages, ops)) {602 if (wait_for_scan(msg, p, len, nr_hpages, hpage_pmd_order, ops)) {
593 if (expect)603 if (expect)
594 fail("Timeout");604 fail("Timeout");
595 else605 else
@@ -605,10 +615,54 @@ static void khugepaged_collapse(const char *msg, char *p, int nr_hpages, · 9 unmodified lines
605 if (ops != &__anon_ops)615 if (ops != &__anon_ops)
606 ops->fault(p, 0, nr_hpages * hpage_pmd_size);616 ops->fault(p, 0, nr_hpages * hpage_pmd_size);
607 617
608 if (ops->check_huge(p, expect ? nr_hpages : 0))618 if (ops->check_huge(p, len, expect ? nr_hpages : 0, hpage_pmd_size))
619 success("OK");
620 else
621 fail("Fail");
622}
623
624static void mthp_khugepaged_collapse(const char *msg, char *p, int nr_hpages,
625 struct mem_ops *ops, bool expect)
626{
627 unsigned long hpage_size = page_size << collapse_order;
628 struct thp_settings settings = *thp_current_settings();
629 /* mTHP collpase only allocates PMD sized memory */
630 size_t len = hpage_pmd_size;
631
632 /* Set mTHP setting for mTHP collapse */
633 if (ops == &__anon_ops) {
634 settings.thp_enabled = THP_NEVER;
635 settings.hugepages[collapse_order].enabled = THP_MADVISE;
636 }
637
638 thp_push_settings(&settings);
639
640 if (wait_for_scan(msg, p, len, nr_hpages, collapse_order, ops)) {
641 if (expect)
642 fail("Timeout");
643 else
644 success("OK");
645
646 /* Restore THP settings for mTHP collapse. */
647 thp_pop_settings();
648 return;
649 }
650
651 /*
652 * For file and shmem memory, khugepaged only retracts pte entries after
653 * putting the new hugepage in the page cache. The hugepage must be
654 * subsequently refaulted to install the pmd mapping for the mm.
655 */
656 if (ops != &__anon_ops)
657 ops->fault(p, 0, nr_hpages * hpage_size);
658
659 if (ops->check_huge(p, len, expect ? nr_hpages : 0, hpage_size))
609 success("OK");660 success("OK");
610 else661 else
611 fail("Fail");662 fail("Fail");
663
664 /* Restore THP settings for mTHP collapse. */
665 thp_pop_settings();
612}666}
613 667
614static struct collapse_context __khugepaged_context = {668static struct collapse_context __khugepaged_context = {
@@ -617,6 +671,12 @@ static struct collapse_context __khugepaged_context = { · 2 unmodified lines
617 .name = "khugepaged",671 .name = "khugepaged",
618};672};
619 673
674static struct collapse_context __mthp_khugepaged_context = {
675 .collapse = &mthp_khugepaged_collapse,
676 .enforce_pte_scan_limits = true,
677 .name = "mthp_khugepaged",
678};
679
620static struct collapse_context __madvise_context = {680static struct collapse_context __madvise_context = {
621 .collapse = &madvise_collapse,681 .collapse = &madvise_collapse,
622 .enforce_pte_scan_limits = false,682 .enforce_pte_scan_limits = false,
@@ -634,7 +694,7 @@ static void alloc_at_fault(void) · 11 unmodified lines
634 p = alloc_mapping(1);694 p = alloc_mapping(1);
635 *p = 1;695 *p = 1;
636 ksft_print_msg("Allocate huge page on fault...");696 ksft_print_msg("Allocate huge page on fault...");
637 if (check_huge_anon(p, 1, hpage_pmd_size))697 if (check_huge_anon(p, hpage_pmd_size, 1, hpage_pmd_size))
638 success("OK");698 success("OK");
639 else699 else
640 fail("Fail");700 fail("Fail");
@@ -643,7 +703,7 @@ static void alloc_at_fault(void) · 2 unmodified lines
643 703
644 madvise(p, page_size, MADV_DONTNEED);704 madvise(p, page_size, MADV_DONTNEED);
645 ksft_print_msg("Split huge PMD on MADV_DONTNEED...");705 ksft_print_msg("Split huge PMD on MADV_DONTNEED...");
646 if (check_huge_anon(p, 0, hpage_pmd_size))706 if (check_huge_anon(p, hpage_pmd_size, 0, hpage_pmd_size))
647 success("OK");707 success("OK");
648 else708 else
649 fail("Fail");709 fail("Fail");
@@ -655,10 +715,17 @@ static void alloc_at_fault(void) · 5 unmodified lines
655static void collapse_full(struct collapse_context *c, struct mem_ops *ops)715static void collapse_full(struct collapse_context *c, struct mem_ops *ops)
656{716{
657 void *p;717 void *p;
658 int nr_hpages = 4;718 int nr_pmds = 4, nr_hpages = 4;
659 unsigned long size = nr_hpages * hpage_pmd_size;719 unsigned long size = nr_hpages * hpage_pmd_size;
660 720
661 p = ops->setup_area(nr_hpages);721 /* Only try 1 PMD sized range for mTHP collapse. */
722 if (c == &__mthp_khugepaged_context) {
723 nr_pmds = 1;
724 nr_hpages = 1 << (hpage_pmd_order - collapse_order);
725 size = hpage_pmd_size;
726 }
727
728 p = ops->setup_area(nr_pmds);
662 ops->fault(p, 0, size);729 ops->fault(p, 0, size);
663 c->collapse("Collapse multiple fully populated PTE table", p, nr_hpages,730 c->collapse("Collapse multiple fully populated PTE table", p, nr_hpages,
664 ops, true);731 ops, true);
@@ -670,10 +737,31 @@ static void collapse_full(struct collapse_context *c, struct mem_ops *ops) · 5 unmodified lines
670 737
671static void collapse_empty(struct collapse_context *c, struct mem_ops *ops)738static void collapse_empty(struct collapse_context *c, struct mem_ops *ops)
672{739{
740 int nr_hpages = 1;
741 void *p;
742
743 if (c == &__mthp_khugepaged_context)
744 nr_hpages = 1 << (hpage_pmd_order - collapse_order);
745
746 p = ops->setup_area(1);
747 c->collapse("Do not collapse empty PTE table", p, nr_hpages, ops, false);
748 ops->cleanup_area(p, hpage_pmd_size);
749 ksft_test_result_report(exit_status, "%s\n", __func__);
750}
751
752static void collapse_single_mthp(struct collapse_context *c, struct mem_ops *ops)
753{
754 unsigned long hpage_size = page_size << collapse_order;
673 void *p;755 void *p;
674 756
675 p = ops->setup_area(1);757 p = ops->setup_area(1);
676 c->collapse("Do not collapse empty PTE table", p, 1, ops, false);758 /*
759 * Only fault collapse_order sized ranges, and only check 1
760 * collapse_order sized huge page.
761 */
762 ops->fault(p, 0, hpage_size);
763 c->collapse("Collapse PTE table with half PTE entries present",
764 p, 1, ops, true);
677 ops->cleanup_area(p, hpage_pmd_size);765 ops->cleanup_area(p, hpage_pmd_size);
678 ksft_test_result_report(exit_status, "%s\n", __func__);766 ksft_test_result_report(exit_status, "%s\n", __func__);
679}767}
@@ -815,7 +903,7 @@ static void collapse_single_pte_entry_compound(struct collapse_context *c, struc · 135 unmodified lines
815 madvise(p, hpage_pmd_size, MADV_NOHUGEPAGE);903 madvise(p, hpage_pmd_size, MADV_NOHUGEPAGE);
816 ksft_print_msg("Split huge page leaving single PTE mapping compound page...");904 ksft_print_msg("Split huge page leaving single PTE mapping compound page...");
817 madvise(p + page_size, hpage_pmd_size - page_size, MADV_DONTNEED);905 madvise(p + page_size, hpage_pmd_size - page_size, MADV_DONTNEED);
818 if (ops->check_huge(p, 0))906 if (ops->check_huge(p, hpage_pmd_size, 0, hpage_pmd_size))
819 success("OK");907 success("OK");
820 else908 else
821 fail("Fail");909 fail("Fail");
@@ -836,7 +924,7 @@ static void collapse_full_of_compound(struct collapse_context *c, struct mem_ops · 14 unmodified lines
836 ksft_print_msg("Split huge page leaving single PTE page table full of compound pages...");924 ksft_print_msg("Split huge page leaving single PTE page table full of compound pages...");
837 madvise(p, page_size, MADV_NOHUGEPAGE);925 madvise(p, page_size, MADV_NOHUGEPAGE);
838 madvise(p, hpage_pmd_size, MADV_NOHUGEPAGE);926 madvise(p, hpage_pmd_size, MADV_NOHUGEPAGE);
839 if (ops->check_huge(p, 0))927 if (ops->check_huge(p, hpage_pmd_size, 0, hpage_pmd_size))
840 success("OK");928 success("OK");
841 else929 else
842 fail("Fail");930 fail("Fail");
@@ -858,7 +946,7 @@ static void collapse_compound_extreme(struct collapse_context *c, struct mem_ops · 15 unmodified lines
858 for (i = 0; i < hpage_pmd_nr; i++) {946 for (i = 0; i < hpage_pmd_nr; i++) {
859 madvise(BASE_ADDR, hpage_pmd_size, MADV_HUGEPAGE);947 madvise(BASE_ADDR, hpage_pmd_size, MADV_HUGEPAGE);
860 ops->fault(BASE_ADDR, 0, hpage_pmd_size);948 ops->fault(BASE_ADDR, 0, hpage_pmd_size);
861 if (!ops->check_huge(BASE_ADDR, 1))949 if (!ops->check_huge(BASE_ADDR, hpage_pmd_size, 1, hpage_pmd_size))
862 ksft_exit_fail_msg("Failed to allocate huge page\n");950 ksft_exit_fail_msg("Failed to allocate huge page\n");
863 madvise(BASE_ADDR, hpage_pmd_size, MADV_NOHUGEPAGE);951 madvise(BASE_ADDR, hpage_pmd_size, MADV_NOHUGEPAGE);
864 952
@@ -881,7 +969,7 @@ static void collapse_compound_extreme(struct collapse_context *c, struct mem_ops · 16 unmodified lines
881 969
882 ops->cleanup_area(BASE_ADDR, hpage_pmd_size);970 ops->cleanup_area(BASE_ADDR, hpage_pmd_size);
883 ops->fault(p, 0, hpage_pmd_size);971 ops->fault(p, 0, hpage_pmd_size);
884 if (!ops->check_huge(p, 1))972 if (!ops->check_huge(p, hpage_pmd_size, 1, hpage_pmd_size))
885 success("OK");973 success("OK");
886 else974 else
887 fail("Fail");975 fail("Fail");
@@ -903,7 +991,7 @@ static void collapse_fork(struct collapse_context *c, struct mem_ops *ops) · 15 unmodified lines
903 991
904 ksft_print_msg("Allocate small page...");992 ksft_print_msg("Allocate small page...");
905 ops->fault(p, 0, page_size);993 ops->fault(p, 0, page_size);
906 if (ops->check_huge(p, 0))994 if (ops->check_huge(p, hpage_pmd_size, 0, hpage_pmd_size))
907 success("OK");995 success("OK");
908 else996 else
909 fail("Fail");997 fail("Fail");
@@ -911,7 +999,7 @@ static void collapse_fork(struct collapse_context *c, struct mem_ops *ops) · 1 unmodified line
911 ksft_print_msg("Share small page over fork()...");999 ksft_print_msg("Share small page over fork()...");
912 if (!fork()) {1000 if (!fork()) {
913 /* Do not touch settings on child exit */1001 /* Do not touch settings on child exit */
914 if (ops->check_huge(p, 0))1002 if (ops->check_huge(p, hpage_pmd_size, 0, hpage_pmd_size))
915 success("OK");1003 success("OK");
916 else1004 else
917 fail("Fail");1005 fail("Fail");
@@ -929,7 +1017,7 @@ static void collapse_fork(struct collapse_context *c, struct mem_ops *ops) · 11 unmodified lines
929 exit_status = WEXITSTATUS(wstatus);1017 exit_status = WEXITSTATUS(wstatus);
930 1018
931 ksft_print_msg("Check if parent still has small page...");1019 ksft_print_msg("Check if parent still has small page...");
932 if (ops->check_huge(p, 0))1020 if (ops->check_huge(p, hpage_pmd_size, 0, hpage_pmd_size))
933 success("OK");1021 success("OK");
934 else1022 else
935 fail("Fail");1023 fail("Fail");
@@ -947,7 +1035,7 @@ static void collapse_fork_compound(struct collapse_context *c, struct mem_ops *o · 11 unmodified lines
947 ksft_print_msg("Share huge page over fork()...");1035 ksft_print_msg("Share huge page over fork()...");
948 if (!fork()) {1036 if (!fork()) {
949 /* Do not touch settings on child exit */1037 /* Do not touch settings on child exit */
950 if (ops->check_huge(p, 1))1038 if (ops->check_huge(p, hpage_pmd_size, 1, hpage_pmd_size))
951 success("OK");1039 success("OK");
952 else1040 else
953 fail("Fail");1041 fail("Fail");
@@ -955,7 +1043,7 @@ static void collapse_fork_compound(struct collapse_context *c, struct mem_ops *o · 1 unmodified line
955 ksft_print_msg("Split huge page PMD in child process...");1043 ksft_print_msg("Split huge page PMD in child process...");
956 madvise(p, page_size, MADV_NOHUGEPAGE);1044 madvise(p, page_size, MADV_NOHUGEPAGE);
957 madvise(p, hpage_pmd_size, MADV_NOHUGEPAGE);1045 madvise(p, hpage_pmd_size, MADV_NOHUGEPAGE);
958 if (ops->check_huge(p, 0))1046 if (ops->check_huge(p, hpage_pmd_size, 0, hpage_pmd_size))
959 success("OK");1047 success("OK");
960 else1048 else
961 fail("Fail");1049 fail("Fail");
@@ -976,7 +1064,7 @@ static void collapse_fork_compound(struct collapse_context *c, struct mem_ops *o · 14 unmodified lines
976 exit_status = WEXITSTATUS(wstatus);1064 exit_status = WEXITSTATUS(wstatus);
977 1065
978 ksft_print_msg("Check if parent still has huge page...");1066 ksft_print_msg("Check if parent still has huge page...");
979 if (ops->check_huge(p, 1))1067 if (ops->check_huge(p, hpage_pmd_size, 1, hpage_pmd_size))
980 success("OK");1068 success("OK");
981 else1069 else
982 fail("Fail");1070 fail("Fail");
@@ -995,7 +1083,7 @@ static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops · 12 unmodified lines
995 ksft_print_msg("Share huge page over fork()...");1083 ksft_print_msg("Share huge page over fork()...");
996 if (!fork()) {1084 if (!fork()) {
997 /* Do not touch settings on child exit */1085 /* Do not touch settings on child exit */
998 if (ops->check_huge(p, 1))1086 if (ops->check_huge(p, hpage_pmd_size, 1, hpage_pmd_size))
999 success("OK");1087 success("OK");
1000 else1088 else
1001 fail("Fail");1089 fail("Fail");
@@ -1003,7 +1091,7 @@ static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops · 1 unmodified line
1003 ksft_print_msg("Trigger CoW on page %d of %d...",1091 ksft_print_msg("Trigger CoW on page %d of %d...",
1004 hpage_pmd_nr - max_ptes_shared - 1, hpage_pmd_nr);1092 hpage_pmd_nr - max_ptes_shared - 1, hpage_pmd_nr);
1005 ops->fault(p, 0, (hpage_pmd_nr - max_ptes_shared - 1) * page_size);1093 ops->fault(p, 0, (hpage_pmd_nr - max_ptes_shared - 1) * page_size);
1006 if (ops->check_huge(p, 0))1094 if (ops->check_huge(p, hpage_pmd_size, 0, hpage_pmd_size))
1007 success("OK");1095 success("OK");
1008 else1096 else
1009 fail("Fail");1097 fail("Fail");
@@ -1016,7 +1104,7 @@ static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops · 6 unmodified lines
1016 hpage_pmd_nr - max_ptes_shared, hpage_pmd_nr);1104 hpage_pmd_nr - max_ptes_shared, hpage_pmd_nr);
1017 ops->fault(p, 0, (hpage_pmd_nr - max_ptes_shared) *1105 ops->fault(p, 0, (hpage_pmd_nr - max_ptes_shared) *
1018 page_size);1106 page_size);
1019 if (ops->check_huge(p, 0))1107 if (ops->check_huge(p, hpage_pmd_size, 0, hpage_pmd_size))
1020 success("OK");1108 success("OK");
1021 else1109 else
1022 fail("Fail");1110 fail("Fail");
@@ -1034,7 +1122,7 @@ static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops · 11 unmodified lines
1034 exit_status = WEXITSTATUS(wstatus);1122 exit_status = WEXITSTATUS(wstatus);
1035 1123
1036 ksft_print_msg("Check if parent still has huge page...");1124 ksft_print_msg("Check if parent still has huge page...");
1037 if (ops->check_huge(p, 1))1125 if (ops->check_huge(p, hpage_pmd_size, 1, hpage_pmd_size))
1038 success("OK");1126 success("OK");
1039 else1127 else
1040 fail("Fail");1128 fail("Fail");
@@ -1075,8 +1163,8 @@ static void madvise_retracted_page_tables(struct collapse_context *c, · 34 unmodified lines
1075 ops->fault(p, 0, size);1163 ops->fault(p, 0, size);
1076 1164
1077 /* Let khugepaged collapse and leave pmd cleared */1165 /* Let khugepaged collapse and leave pmd cleared */
1078 if (wait_for_scan("Collapse and leave PMD cleared", p, nr_hpages,1166 if (wait_for_scan("Collapse and leave PMD cleared", p, size, nr_hpages,
1079 ops)) {1167 hpage_pmd_order, ops)) {
1080 fail("Timeout");1168 fail("Timeout");
1081 return;1169 return;
1082 }1170 }
@@ -1092,17 +1180,19 @@ static void usage(void) · 9 unmodified lines
1092{1180{
1093 fprintf(stderr, "\nUsage: ./khugepaged [OPTIONS] <test type> [dir]\n\n");1181 fprintf(stderr, "\nUsage: ./khugepaged [OPTIONS] <test type> [dir]\n\n");
1094 fprintf(stderr, "\t<test type>\t: <context>:<mem_type>\n");1182 fprintf(stderr, "\t<test type>\t: <context>:<mem_type>\n");
1095 fprintf(stderr, "\t<context>\t: [all|khugepaged|madvise]\n");1183 fprintf(stderr, "\t<context>\t: [all|khugepaged|mthp_khugepaged|madvise]\n");
1096 fprintf(stderr, "\t<mem_type>\t: [all|anon|file|shmem]\n");1184 fprintf(stderr, "\t<mem_type>\t: [all|anon|file|shmem]\n");
1097 fprintf(stderr, "\n\t\"file,all\" mem_type requires [dir] argument\n");1185 fprintf(stderr, "\n\t\"file,all\" mem_type requires [dir] argument\n");
1098 fprintf(stderr, "\n\t\"file,all\" mem_type requires a file system\n");1186 fprintf(stderr, "\n\t\"file,all\" mem_type requires a file system\n");
1099 fprintf(stderr, "\twith PMD-sized large folio support\n");1187 fprintf(stderr, "\twith PMD-sized large folio support\n");
1100 fprintf(stderr, "\n\tif [dir] is a (sub)directory of a tmpfs mount, tmpfs must be\n");1188 fprintf(stderr, "\n\tif [dir] is a (sub)directory of a tmpfs mount, tmpfs must be\n");
1101 fprintf(stderr, "\tmounted with huge=advise option for khugepaged tests to work\n");1189 fprintf(stderr, "\tmounted with huge=advise option for khugepaged tests to work\n");
1190 fprintf(stderr, "\n\tmthp_khugepaged only supports anon mem_type now.\n");
1102 fprintf(stderr, "\n\tSupported Options:\n");1191 fprintf(stderr, "\n\tSupported Options:\n");
1103 fprintf(stderr, "\t\t-h: This help message.\n");1192 fprintf(stderr, "\t\t-h: This help message.\n");
1104 fprintf(stderr, "\t\t-s: mTHP size, expressed as page order.\n");1193 fprintf(stderr, "\t\t-s: mTHP size, expressed as page order.\n");
1105 fprintf(stderr, "\t\t Defaults to 0. Use this size for anon or shmem allocations.\n");1194 fprintf(stderr, "\t\t Defaults to 0. Use this size for anon or shmem allocations.\n");
1195 fprintf(stderr, "\t\t-c: collapse order for mTHP collapse, expressed as page order.\n");
1106 exit(1);1196 exit(1);
1107}1197}
1108 1198
@@ -1112,11 +1202,14 @@ static void parse_test_type(int argc, char **argv) · 3 unmodified lines
1112 char *buf;1202 char *buf;
1113 const char *token;1203 const char *token;
1114 1204
1115 while ((opt = getopt(argc, argv, "s:h")) != -1) {1205 while ((opt = getopt(argc, argv, "s:c:h")) != -1) {
1116 switch (opt) {1206 switch (opt) {
1117 case 's':1207 case 's':
1118 anon_order = atoi(optarg);1208 anon_order = atoi(optarg);
1119 break;1209 break;
1210 case 'c':
1211 collapse_order = atoi(optarg);
1212 break;
1120 case 'h':1213 case 'h':
1121 default:1214 default:
1122 usage();1215 usage();
@@ -1142,6 +1235,10 @@ static void parse_test_type(int argc, char **argv) · 19 unmodified lines
1142 madvise_context = &__madvise_context;1235 madvise_context = &__madvise_context;
1143 } else if (!strcmp(token, "khugepaged")) {1236 } else if (!strcmp(token, "khugepaged")) {
1144 khugepaged_context = &__khugepaged_context;1237 khugepaged_context = &__khugepaged_context;
1238 } else if (!strcmp(token, "mthp_khugepaged")) {
1239 mthp_khugepaged_context = &__mthp_khugepaged_context;
1240 if (collapse_order <= 0 || collapse_order >= hpage_pmd_order)
1241 usage();
1145 } else if (!strcmp(token, "madvise")) {1242 } else if (!strcmp(token, "madvise")) {
1146 madvise_context = &__madvise_context;1243 madvise_context = &__madvise_context;
1147 } else {1244 } else {
@@ -1157,14 +1254,20 @@ static void parse_test_type(int argc, char **argv) · 9 unmodified lines
1157 read_write_file_write_ops = &__read_write_file_write_ops;1254 read_write_file_write_ops = &__read_write_file_write_ops;
1158 anon_ops = &__anon_ops;1255 anon_ops = &__anon_ops;
1159 shmem_ops = &__shmem_ops;1256 shmem_ops = &__shmem_ops;
1257 if (mthp_khugepaged_context)
1258 usage();
1160 } else if (!strcmp(buf, "anon")) {1259 } else if (!strcmp(buf, "anon")) {
1161 anon_ops = &__anon_ops;1260 anon_ops = &__anon_ops;
1162 } else if (!strcmp(buf, "file")) {1261 } else if (!strcmp(buf, "file")) {
1163 read_only_file_ops = &__read_only_file_ops;1262 read_only_file_ops = &__read_only_file_ops;
1164 read_write_file_read_ops = &__read_write_file_read_ops;1263 read_write_file_read_ops = &__read_write_file_read_ops;
1165 read_write_file_write_ops = &__read_write_file_write_ops;1264 read_write_file_write_ops = &__read_write_file_write_ops;
1265 if (mthp_khugepaged_context)
1266 usage();
1166 } else if (!strcmp(buf, "shmem")) {1267 } else if (!strcmp(buf, "shmem")) {
1167 shmem_ops = &__shmem_ops;1268 shmem_ops = &__shmem_ops;
1269 if (mthp_khugepaged_context)
1270 usage();
1168 } else {1271 } else {
1169 usage();1272 usage();
1170 }1273 }
@@ -1207,7 +1310,6 @@ static int nr_test_cases; · 36 unmodified lines
1207 1310
1208int main(int argc, char **argv)1311int main(int argc, char **argv)
1209{1312{
1210 int hpage_pmd_order;
1211 struct thp_settings default_settings = {1313 struct thp_settings default_settings = {
1212 .thp_enabled = THP_MADVISE,1314 .thp_enabled = THP_MADVISE,
1213 .thp_defrag = THP_DEFRAG_ALWAYS,1315 .thp_defrag = THP_DEFRAG_ALWAYS,
@@ -1233,10 +1335,6 @@ int main(int argc, char **argv) · 19 unmodified lines
1233 if (!thp_is_enabled())1335 if (!thp_is_enabled())
1234 ksft_exit_skip("Transparent Hugepages not available\n");1336 ksft_exit_skip("Transparent Hugepages not available\n");
1235 1337
1236 parse_test_type(argc, argv);
1237
1238 setbuf(stdout, NULL);
1239
1240 page_size = getpagesize();1338 page_size = getpagesize();
1241 hpage_pmd_size = read_pmd_pagesize();1339 hpage_pmd_size = read_pmd_pagesize();
1242 if (!hpage_pmd_size)1340 if (!hpage_pmd_size)
@@ -1244,6 +1342,10 @@ int main(int argc, char **argv) · 1 unmodified line
1244 hpage_pmd_nr = hpage_pmd_size / page_size;1342 hpage_pmd_nr = hpage_pmd_size / page_size;
1245 hpage_pmd_order = __builtin_ctz(hpage_pmd_nr);1343 hpage_pmd_order = __builtin_ctz(hpage_pmd_nr);
1246 1344
1345 parse_test_type(argc, argv);
1346
1347 setbuf(stdout, NULL);
1348
1247 default_settings.khugepaged.max_ptes_none = hpage_pmd_nr - 1;1349 default_settings.khugepaged.max_ptes_none = hpage_pmd_nr - 1;
1248 default_settings.khugepaged.max_ptes_swap = hpage_pmd_nr / 8;1350 default_settings.khugepaged.max_ptes_swap = hpage_pmd_nr / 8;
1249 default_settings.khugepaged.max_ptes_shared = hpage_pmd_nr / 2;1351 default_settings.khugepaged.max_ptes_shared = hpage_pmd_nr / 2;
@@ -1261,6 +1363,7 @@ int main(int argc, char **argv) · 11 unmodified lines
1261 TEST(collapse_full, khugepaged_context, read_write_file_read_ops);1363 TEST(collapse_full, khugepaged_context, read_write_file_read_ops);
1262 TEST(collapse_full, khugepaged_context, read_write_file_write_ops);1364 TEST(collapse_full, khugepaged_context, read_write_file_write_ops);
1263 TEST(collapse_full, khugepaged_context, shmem_ops);1365 TEST(collapse_full, khugepaged_context, shmem_ops);
1366 TEST(collapse_full, mthp_khugepaged_context, anon_ops);
1264 TEST(collapse_full, madvise_context, anon_ops);1367 TEST(collapse_full, madvise_context, anon_ops);
1265 TEST(collapse_full, madvise_context, read_only_file_ops);1368 TEST(collapse_full, madvise_context, read_only_file_ops);
1266 TEST(collapse_full, madvise_context, read_write_file_read_ops);1369 TEST(collapse_full, madvise_context, read_write_file_read_ops);
@@ -1268,8 +1371,11 @@ int main(int argc, char **argv) · 1 unmodified line
1268 TEST(collapse_full, madvise_context, shmem_ops);1371 TEST(collapse_full, madvise_context, shmem_ops);
1269 1372
1270 TEST(collapse_empty, khugepaged_context, anon_ops);1373 TEST(collapse_empty, khugepaged_context, anon_ops);
1374 TEST(collapse_empty, mthp_khugepaged_context, anon_ops);
1271 TEST(collapse_empty, madvise_context, anon_ops);1375 TEST(collapse_empty, madvise_context, anon_ops);
1272 1376
1377 TEST(collapse_single_mthp, mthp_khugepaged_context, anon_ops);
1378
1273 TEST(collapse_single_pte_entry, khugepaged_context, anon_ops);1379 TEST(collapse_single_pte_entry, khugepaged_context, anon_ops);
1274 TEST(collapse_single_pte_entry, khugepaged_context, read_only_file_ops);1380 TEST(collapse_single_pte_entry, khugepaged_context, read_only_file_ops);
1275 TEST(collapse_single_pte_entry, khugepaged_context, read_write_file_read_ops);1381 TEST(collapse_single_pte_entry, khugepaged_context, read_write_file_read_ops);
tools/testing/selftests/mm/ksft_kmemleak_confirm.sh+130−0
@@ -0,0 +1,130 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4# Functional test for kmemleak's N-consecutive-scan leak confirmation
5# (the min_unref_scans module parameter).
6#
7# kmemleak only reports an object once it has stayed unreferenced for
8# min_unref_scans consecutive scans. A threshold of 1 reports on the first
9# scan (historical behaviour); higher values filter transient false
10# positives where a live object's only reference is briefly invisible to a
11# single scan (e.g. an RCU tree update in flight while the scan runs). The
12# test loads samples/kmemleak's helper module to create orphan allocations
13# and, counting only those orphans (matched by their [kmemleak_test]
14# backtrace so unrelated leaks already present on the system are ignored),
15# checks that:
16# - a freshly allocated object is greyed on its first scan (its checksum
17# settles then), so nothing can be reported before that priming scan;
18# each case below primes once first,
19# - at min_unref_scans=1 one scan after priming reports the orphans,
20# - raising the threshold to 2 needs two scans after priming: one is not
21# enough, the second reports,
22# - the parameter reads back what was written.
23#
24# The "one post-prime scan is not enough at min_unref_scans=2" check is the
25# core regression test: raising min_unref_scans must push the report
26# strictly later. Like ksft_kmemleak_dedup.sh, if the module yields no
27# detectable orphan at all in the running environment the test skips rather
28# than failing.
29#
30# Author: Breno Leitao <leitao@debian.org>
31
32# KTAP output helpers (ktap_skip_all, ktap_exit_fail_msg, ktap_test_pass, ...).
33DIR="$(dirname "$(readlink -f "$0")")"
34# shellcheck source=../kselftest/ktap_helpers.sh
35source "${DIR}"/../kselftest/ktap_helpers.sh
36
37KMEMLEAK=/sys/kernel/debug/kmemleak
38PARAM=/sys/module/kmemleak/parameters/min_unref_scans
39MODULE=kmemleak-test
40AGE=6 # seconds; must exceed kmemleak's 5s minimum object age
41
42ktap_print_header
43
44[ "$(id -u)" -eq 0 ] || { ktap_skip_all "must run as root"; exit "$KSFT_SKIP"; }
45[ -r "$KMEMLEAK" ] ||
46 { ktap_skip_all "no kmemleak debugfs (CONFIG_DEBUG_KMEMLEAK)"; exit "$KSFT_SKIP"; }
47[ -w "$PARAM" ] ||
48 { ktap_skip_all "min_unref_scans module parameter not present"; exit "$KSFT_SKIP"; }
49modinfo "$MODULE" >/dev/null 2>&1 ||
50 { ktap_skip_all "$MODULE not built (CONFIG_SAMPLE_KMEMLEAK)"; exit "$KSFT_SKIP"; }
51
52# kmemleak can be present but disabled at runtime (kmemleak=off boot arg,
53# or it self-disabled after an internal error); a "scan" then returns
54# EPERM. Probe once and skip if so.
55echo scan > "$KMEMLEAK" 2>/dev/null ||
56 { ktap_skip_all "kmemleak is disabled (check dmesg or kmemleak= boot arg)"; exit "$KSFT_SKIP"; }
57
58prev=$(cat "$PARAM")
59# shellcheck disable=SC2317 # invoked indirectly via trap
60cleanup() {
61 echo "$prev" > "$PARAM" 2>/dev/null # restore the parameter
62 echo scan=on > "$KMEMLEAK" 2>/dev/null # re-enable auto scan
63 rmmod "$MODULE" 2>/dev/null
64 echo clear > "$KMEMLEAK" 2>/dev/null
65}
66trap cleanup EXIT
67
68# Stop the automatic scan thread: only our manual scans should advance an
69# object's consecutive-unreferenced run. An auto scan landing between two
70# manual scans would change the result and make the test flaky.
71echo scan=off > "$KMEMLEAK" 2>/dev/null
72
73# Create a fresh, aged set of orphan objects from the helper module's init
74# path (its kmalloc/vmalloc/percpu allocations are dropped right away).
75# Pre-existing reported leaks are greyed first ("clear") so only our
76# orphans are counted. The module is left loaded on purpose: once it is
77# unloaded its symbols are gone, so the orphan backtraces no longer resolve
78# to [kmemleak_test] and could not be matched below.
79gen_orphans() {
80 rmmod "$MODULE" 2>/dev/null
81 echo clear > "$KMEMLEAK"
82 modprobe "$MODULE" ||
83 { ktap_skip_all "failed to load $MODULE"; exit "$KSFT_SKIP"; }
84 sleep "$AGE"
85}
86
87scan() { echo scan > "$KMEMLEAK"; }
88
89# Number of helper-module orphans currently reported by kmemleak. Matching
90# the module's own backtrace ([kmemleak_test]) keeps the count immune to
91# unrelated leaks on the running system. kmemleak only lists an object here
92# once it has been reported, so this reflects the confirmation gating.
93count_orphans() {
94 c=$(grep -c '\[kmemleak_test\]' "$KMEMLEAK" 2>/dev/null)
95 echo "${c:-0}"
96}
97
98# 0) the parameter reads back what was written.
99echo 3 > "$PARAM"
100[ "$(cat "$PARAM")" = "3" ] || ktap_exit_fail_msg "min_unref_scans did not read back as 3"
101
102# Priming scan: kmemleak greys a freshly allocated object on its first scan
103# (its checksum settles then), so nothing can be reported until a second
104# scan. Every case below runs this priming scan before counting.
105prime() { scan; }
106
107# 1) min_unref_scans=1: one scan after priming reports the orphans. This
108# also establishes that the helper produces detectable orphans here.
109echo 1 > "$PARAM"
110gen_orphans
111prime
112scan
113first=$(count_orphans)
114[ "$first" -gt 0 ] ||
115 { ktap_skip_all "$MODULE produced no detectable orphans (cannot test min_unref_scans)"; exit "$KSFT_SKIP"; }
116
117# 2) min_unref_scans=2: after priming, one scan is not enough (still
118# gated), the second reports. The gated-scan-zero check is the core
119# regression.
120echo 2 > "$PARAM"
121gen_orphans
122prime
123scan; s1=$(count_orphans)
124scan; s2=$(count_orphans)
125[ "$s1" -eq 0 ] || ktap_exit_fail_msg "min_unref_scans=2: $s1 orphan(s) after 1 post-prime scan (must be 0)"
126[ "$s2" -gt 0 ] || ktap_exit_fail_msg "min_unref_scans=2: no report after 2 post-prime scans (false negative)"
127
128ktap_set_plan 1
129ktap_test_pass "min_unref_scans=1 reported $first orphan(s) one scan after priming; =2 held them one scan longer ($s1 after one scan, $s2 after two); param read-back ok"
130ktap_finished
tools/testing/selftests/mm/memory-failure.c+12−2
@@ -287,8 +287,10 @@ TEST_F(memory_failure, clean_pagecache) · 286 unmodified lines
287 if (fd < 0)287 if (fd < 0)
288 SKIP(return, "failed to open test file.\n");288 SKIP(return, "failed to open test file.\n");
289 fs_type = get_fs_type(fd);289 fs_type = get_fs_type(fd);
290 if (!fs_type || fs_type == TMPFS_MAGIC)290 if (!fs_type || fs_type == TMPFS_MAGIC) {
291 close(fd);
291 SKIP(return, "unsupported filesystem :%x\n", fs_type);292 SKIP(return, "unsupported filesystem :%x\n", fs_type);
293 }
292 294
293 addr = mmap(0, self->page_size, PROT_READ | PROT_WRITE,295 addr = mmap(0, self->page_size, PROT_READ | PROT_WRITE,
294 MAP_SHARED, fd, 0);296 MAP_SHARED, fd, 0);
@@ -327,8 +329,16 @@ TEST_F(memory_failure, dirty_pagecache) · 32 unmodified lines
327 if (fd < 0)329 if (fd < 0)
328 SKIP(return, "failed to open test file.\n");330 SKIP(return, "failed to open test file.\n");
329 fs_type = get_fs_type(fd);331 fs_type = get_fs_type(fd);
330 if (!fs_type || fs_type == TMPFS_MAGIC)332 /*
333 * MADV_HARD poisoning of dirty page-cache data records an expected
334 * -EIO in the file mapping. NFS reports this error on close(), so
335 * skip this variant.
336 */
337 if (!fs_type || fs_type == TMPFS_MAGIC ||
338 (fs_type == NFS_SUPER_MAGIC && variant->type == MADV_HARD)) {
339 close(fd);
331 SKIP(return, "unsupported filesystem :%x\n", fs_type);340 SKIP(return, "unsupported filesystem :%x\n", fs_type);
341 }
332 342
333 addr = mmap(0, self->page_size, PROT_READ | PROT_WRITE,343 addr = mmap(0, self->page_size, PROT_READ | PROT_WRITE,
334 MAP_SHARED, fd, 0);344 MAP_SHARED, fd, 0);
tools/testing/selftests/mm/merge.c+57−0
@@ -1305,6 +1305,63 @@ TEST_F(merge, merge_vmas_with_mseal) · 1304 unmodified lines
1305 ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr + 2 * page_size);1305 ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr + 2 * page_size);
1306}1306}
1307 1307
1308TEST_F(merge, anon_and_page_offset_mismatch_memfd)
1309{
1310 struct procmap_fd *procmap = &self->procmap;
1311 unsigned int page_size = self->page_size;
1312 char *carveout = self->carveout;
1313 char *ptr, *ptr2;
1314 int fd;
1315
1316 /* Create a 10 page memfd descriptor. */
1317 fd = memfd_create("anon_page_offset_test", MFD_CLOEXEC);
1318 ASSERT_NE(fd, -1);
1319 ASSERT_EQ(ftruncate(fd, 10 * page_size), 0);
1320
1321 /* Map a region using the memfd at page offset 0. */
1322 ptr = mmap(carveout, 5 * page_size, PROT_READ | PROT_WRITE,
1323 MAP_FIXED | MAP_PRIVATE, fd, 0);
1324 ASSERT_NE(ptr, MAP_FAILED);
1325
1326 /*
1327 * Map another separately and trigger a CoW fault at page offset 5:
1328 *
1329 * |-----------| |---------|
1330 * | unfaulted | | faulted |
1331 * |-----------| |---------|
1332 */
1333 ptr2 = mmap(&carveout[10 * page_size], 5 * page_size,
1334 PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE,
1335 fd, 5 * page_size);
1336 ASSERT_NE(ptr2, MAP_FAILED);
1337 ptr2[0] = 'x';
1338
1339 /*
1340 * Now move it in place:
1341 *
1342 * |----------|
1343 * | |
1344 * v |
1345 * |-----------| |---------|
1346 * | unfaulted | | faulted |
1347 * |-----------| |---------|
1348 *
1349 * Because the anonymous page offset of the faulted region is now
1350 * &carveout[10 * page_size], despite the two regions being mergeable
1351 * due to file page offset, they are NOT mergeable due to anonymous
1352 * page offset.
1353 */
1354 ptr2 = sys_mremap(ptr2, 5 * page_size, 5 * page_size,
1355 MREMAP_MAYMOVE | MREMAP_FIXED,
1356 &carveout[5 * page_size]);
1357 ASSERT_NE(ptr2, MAP_FAILED);
1358
1359 /* Assert that they did not merge. */
1360 ASSERT_TRUE(find_vma_procmap(procmap, ptr));
1361 ASSERT_EQ(procmap->query.vma_start, (unsigned long)ptr);
1362 ASSERT_EQ(procmap->query.vma_end, (unsigned long)ptr + 5 * page_size);
1363}
1364
1308TEST_F(merge_with_fork, mremap_faulted_to_unfaulted_prev)1365TEST_F(merge_with_fork, mremap_faulted_to_unfaulted_prev)
1309{1366{
1310 struct procmap_fd *procmap = &self->procmap;1367 struct procmap_fd *procmap = &self->procmap;
tools/testing/selftests/mm/migration.c+20−17
@@ -7,7 +7,7 @@ · 6 unmodified lines
7#include "kselftest_harness.h"7#include "kselftest_harness.h"
8#include "hugepage_settings.h"8#include "hugepage_settings.h"
9 9
10#include <strings.h>10#include <string.h>
11#include <pthread.h>11#include <pthread.h>
12#include <numa.h>12#include <numa.h>
13#include <numaif.h>13#include <numaif.h>
@@ -20,7 +20,6 @@ · 6 unmodified lines
20 20
21#define TWOMEG (2<<20)21#define TWOMEG (2<<20)
22#define RUNTIME (20)22#define RUNTIME (20)
23#define MAX_RETRIES 100
24#define ALIGN(x, a) (((x) + (a - 1)) & (~((a) - 1)))23#define ALIGN(x, a) (((x) + (a - 1)) & (~((a) - 1)))
25 24
26HUGETLB_SETUP_DEFAULT_PAGES(1)25HUGETLB_SETUP_DEFAULT_PAGES(1)
@@ -110,7 +109,7 @@ int migrate(uint64_t *ptr, int n1, int n2) · 83 unmodified lines
110 int ret, tmp;109 int ret, tmp;
111 int status = 0;110 int status = 0;
112 struct timespec ts1, ts2;111 struct timespec ts1, ts2;
113 int failures = 0;112 int success = 0;
114 113
115 if (clock_gettime(CLOCK_MONOTONIC, &ts1))114 if (clock_gettime(CLOCK_MONOTONIC, &ts1))
116 return -1;115 return -1;
@@ -119,29 +118,33 @@ int migrate(uint64_t *ptr, int n1, int n2) · 2 unmodified lines
119 if (clock_gettime(CLOCK_MONOTONIC, &ts2))118 if (clock_gettime(CLOCK_MONOTONIC, &ts2))
120 return -1;119 return -1;
121 120
122 if (ts2.tv_sec - ts1.tv_sec >= RUNTIME)121 if (ts2.tv_sec - ts1.tv_sec >= RUNTIME) {
123 return 0;122 /* Reaching both targets verifies a cross-node move. */
123 if (success >= 2)
124 return 0;
125 else
126 return -2;
127 }
124 128
125 ret = move_pages(0, 1, (void **) &ptr, &n2, &status,129 ret = move_pages(0, 1, (void **) &ptr, &n2, &status,
126 MPOL_MF_MOVE_ALL);130 MPOL_MF_MOVE_ALL);
127 if (ret) {131 if (ret < 0) {
128 if (ret > 0) {132 perror("Couldn't migrate pages");
129 /* Migration is best effort; try again */133 return ret;
130 if (++failures < MAX_RETRIES)134 }
131 continue;135 /* Migration is best effort. Try again */
132 printf("Didn't migrate %d pages\n", ret);136 if (ret > 0 || status < 0)
133 }137 continue;
134 else138 if (status != n2) {
135 perror("Couldn't migrate pages");139 printf("Page is on node %d instead of target node %d\n",
140 status, n2);
136 return -2;141 return -2;
137 }142 }
138 failures = 0;143 success++;
139 tmp = n2;144 tmp = n2;
140 n2 = n1;145 n2 = n1;
141 n1 = tmp;146 n1 = tmp;
142 }147 }
143
144 return 0;
145}148}
146 149
147void *access_mem(void *ptr)150void *access_mem(void *ptr)
tools/testing/selftests/mm/mseal_test.c+1−2
@@ -1876,7 +1876,7 @@ int main(void) · 1875 unmodified lines
1876 if (!pkey_supported())1876 if (!pkey_supported())
1877 ksft_print_msg("PKEY not supported\n");1877 ksft_print_msg("PKEY not supported\n");
1878 1878
1879 ksft_set_plan(88);1879 ksft_set_plan(87);
1880 1880
1881 test_seal_addseal();1881 test_seal_addseal();
1882 test_seal_unmapped_start();1882 test_seal_unmapped_start();
@@ -1913,7 +1913,6 @@ int main(void) · 30 unmodified lines
1913 test_seal_mprotect_partial_mprotect(false);1913 test_seal_mprotect_partial_mprotect(false);
1914 test_seal_mprotect_partial_mprotect(true);1914 test_seal_mprotect_partial_mprotect(true);
1915 1915
1916 test_seal_mprotect_two_vma_with_gap();
1917 test_seal_mprotect_two_vma_with_gap();1916 test_seal_mprotect_two_vma_with_gap();
1918 1917
1919 test_seal_mprotect_merge(false);1918 test_seal_mprotect_merge(false);
tools/testing/selftests/mm/pagemap_ioctl.c+1−7
@@ -1085,7 +1085,7 @@ static void unpopulated_written_test(const char *name, char *mem, long size, · 1084 unmodified lines
1085 memset(mem, 1, size);1085 memset(mem, 1, size);
1086 if (use_thp &&1086 if (use_thp &&
1087 (madvise(mem, size, MADV_COLLAPSE) ||1087 (madvise(mem, size, MADV_COLLAPSE) ||
1088 !check_huge_anon(mem, size / hpage_size, hpage_size))) {1088 !check_huge_anon(mem, size, size / hpage_size, hpage_size))) {
1089 ksft_test_result_skip("%s could not form a THP\n", name);1089 ksft_test_result_skip("%s could not form a THP\n", name);
1090 goto out;1090 goto out;
1091 }1091 }
@@ -1332,12 +1332,6 @@ int mprotect_tests(void) · 240 unmodified lines
1332 int ret;1332 int ret;
1333 char *mem, *mem2;1333 char *mem, *mem2;
1334 struct page_region vec;1334 struct page_region vec;
1335 int pagemap_fd = open("/proc/self/pagemap", O_RDONLY);
1336
1337 if (pagemap_fd < 0) {
1338 fprintf(stderr, "open() failed\n");
1339 exit(1);
1340 }
1341 1335
1342 /* 1. Map two pages */1336 /* 1. Map two pages */
1343 mem = mmap(0, 2 * page_size, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);1337 mem = mmap(0, 2 * page_size, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
tools/testing/selftests/mm/prctl_thp_disable.c+1−1
@@ -67,7 +67,7 @@ static int test_mmap_thp(enum thp_collapse_type madvise_buf, size_t pmdsize) · 66 unmodified lines
67 /* HACK: make sure we have a separate VMA that we can check reliably. */67 /* HACK: make sure we have a separate VMA that we can check reliably. */
68 mprotect(mem, pmdsize, PROT_READ);68 mprotect(mem, pmdsize, PROT_READ);
69 69
70 ret = check_huge_anon(mem, 1, pmdsize);70 ret = check_huge_anon(mem, pmdsize, 1, pmdsize);
71 munmap(mmap_mem, mmap_size);71 munmap(mmap_mem, mmap_size);
72 return ret;72 return ret;
73}73}
tools/testing/selftests/mm/run_vmtests.sh+2−0
@@ -410,6 +410,8 @@ CATEGORY="thp" run_test ./khugepaged all:shmem · 409 unmodified lines
410 410
411CATEGORY="thp" run_test ./khugepaged -s 4 all:shmem411CATEGORY="thp" run_test ./khugepaged -s 4 all:shmem
412 412
413CATEGORY="thp" run_test ./khugepaged -c 4 mthp_khugepaged:anon
414
413# Try to create XFS if not provided415# Try to create XFS if not provided
414if [ -z "${SPLIT_HUGE_PAGE_TEST_XFS_PATH}" ]; then416if [ -z "${SPLIT_HUGE_PAGE_TEST_XFS_PATH}" ]; then
415 if test_selected "thp"; then417 if test_selected "thp"; then
tools/testing/selftests/mm/soft-dirty.c+3−2
@@ -103,7 +103,7 @@ static void test_hugepage(int pagemap_fd, int pagesize) · 102 unmodified lines
103 for (i = 0; i < hpage_len; i++)103 for (i = 0; i < hpage_len; i++)
104 map[i] = (char)i;104 map[i] = (char)i;
105 105
106 if (check_huge_anon(map, 1, hpage_len)) {106 if (check_huge_anon(map, hpage_len, 1, hpage_len)) {
107 ksft_test_result_pass("Test %s huge page allocation\n", __func__);107 ksft_test_result_pass("Test %s huge page allocation\n", __func__);
108 108
109 clear_softdirty();109 clear_softdirty();
@@ -152,7 +152,8 @@ static void test_mprotect(int pagemap_fd, int pagesize, bool anon) · 42 unmodified lines
152 return;152 return;
153 }153 }
154 unlink(fname);154 unlink(fname);
155 ftruncate(test_fd, pagesize);155 if (ftruncate(test_fd, pagesize) != 0)
156 ksft_exit_fail_msg("ftruncate failed\n");
156 map = mmap(NULL, pagesize, PROT_READ|PROT_WRITE,157 map = mmap(NULL, pagesize, PROT_READ|PROT_WRITE,
157 MAP_SHARED, test_fd, 0);158 MAP_SHARED, test_fd, 0);
158 if (map == MAP_FAILED)159 if (map == MAP_FAILED)
tools/testing/selftests/mm/split_huge_page_test.c+8−131
@@ -104,129 +104,6 @@ fail: · 103 unmodified lines
104 return false;104 return false;
105}105}
106 106
107static int vaddr_pageflags_get(char *vaddr, int pagemap_fd, int kpageflags_fd,
108 uint64_t *flags)
109{
110 unsigned long pfn;
111
112 pfn = pagemap_get_pfn(pagemap_fd, vaddr);
113
114 /* non-present PFN */
115 if (pfn == -1UL)
116 return 1;
117
118 if (pageflags_get(pfn, kpageflags_fd, flags))
119 return -1;
120
121 return 0;
122}
123
124/*
125 * gather_after_split_folio_orders - scan through [vaddr_start, len) and record
126 * folio orders
127 *
128 * @vaddr_start: start vaddr
129 * @len: range length
130 * @pagemap_fd: file descriptor to /proc/<pid>/pagemap
131 * @kpageflags_fd: file descriptor to /proc/kpageflags
132 * @orders: output folio order array
133 * @nr_orders: folio order array size
134 *
135 * gather_after_split_folio_orders() scan through [vaddr_start, len) and check
136 * all folios within the range and record their orders. All order-0 pages will
137 * be recorded. Non-present vaddr is skipped.
138 *
139 * NOTE: the function is used to check folio orders after a split is performed,
140 * so it assumes [vaddr_start, len) fully maps to after-split folios within that
141 * range.
142 *
143 * Return: 0 - no error, -1 - unhandled cases
144 */
145static int gather_after_split_folio_orders(char *vaddr_start, size_t len,
146 int pagemap_fd, int kpageflags_fd, int orders[], int nr_orders)
147{
148 uint64_t page_flags = 0;
149 int cur_order = -1;
150 char *vaddr;
151
152 if (pagemap_fd == -1 || kpageflags_fd == -1)
153 return -1;
154 if (!orders)
155 return -1;
156 if (nr_orders <= 0)
157 return -1;
158
159 for (vaddr = vaddr_start; vaddr < vaddr_start + len;) {
160 char *next_folio_vaddr;
161 int status;
162
163 status = vaddr_pageflags_get(vaddr, pagemap_fd, kpageflags_fd,
164 &page_flags);
165 if (status < 0)
166 return -1;
167
168 /* skip non present vaddr */
169 if (status == 1) {
170 vaddr += psize();
171 continue;
172 }
173
174 /* all order-0 pages with possible false postive (non folio) */
175 if (!(page_flags & (KPF_COMPOUND_HEAD | KPF_COMPOUND_TAIL))) {
176 orders[0]++;
177 vaddr += psize();
178 continue;
179 }
180
181 /* skip non thp compound pages */
182 if (!(page_flags & KPF_THP)) {
183 vaddr += psize();
184 continue;
185 }
186
187 /* vpn points to part of a THP at this point */
188 if (page_flags & KPF_COMPOUND_HEAD)
189 cur_order = 1;
190 else {
191 vaddr += psize();
192 continue;
193 }
194
195 next_folio_vaddr = vaddr + (1UL << (cur_order + pshift()));
196
197 if (next_folio_vaddr >= vaddr_start + len)
198 break;
199
200 while ((status = vaddr_pageflags_get(next_folio_vaddr,
201 pagemap_fd, kpageflags_fd,
202 &page_flags)) >= 0) {
203 /*
204 * non present vaddr, next compound head page, or
205 * order-0 page
206 */
207 if (status == 1 ||
208 (page_flags & KPF_COMPOUND_HEAD) ||
209 !(page_flags & (KPF_COMPOUND_HEAD | KPF_COMPOUND_TAIL))) {
210 if (cur_order < nr_orders) {
211 orders[cur_order]++;
212 cur_order = -1;
213 vaddr = next_folio_vaddr;
214 }
215 break;
216 }
217
218 cur_order++;
219 next_folio_vaddr = vaddr + (1UL << (cur_order + pshift()));
220 }
221
222 if (status < 0)
223 return status;
224 }
225 if (cur_order > 0 && cur_order < nr_orders)
226 orders[cur_order]++;
227 return 0;
228}
229
230static int check_after_split_folio_orders(char *vaddr_start, size_t len,107static int check_after_split_folio_orders(char *vaddr_start, size_t len,
231 int pagemap_fd, int kpageflags_fd, int orders[], int nr_orders)108 int pagemap_fd, int kpageflags_fd, int orders[], int nr_orders)
232{109{
@@ -240,7 +117,7 @@ static int check_after_split_folio_orders(char *vaddr_start, size_t len, · 7 unmodified lines
240 ksft_exit_fail_msg("Cannot allocate memory for vaddr_orders");117 ksft_exit_fail_msg("Cannot allocate memory for vaddr_orders");
241 118
242 memset(vaddr_orders, 0, sizeof(int) * nr_orders);119 memset(vaddr_orders, 0, sizeof(int) * nr_orders);
243 status = gather_after_split_folio_orders(vaddr_start, len, pagemap_fd,120 status = gather_folio_orders(vaddr_start, len, pagemap_fd,
244 kpageflags_fd, vaddr_orders, nr_orders);121 kpageflags_fd, vaddr_orders, nr_orders);
245 if (status)122 if (status)
246 ksft_exit_fail_msg("gather folio info failed\n");123 ksft_exit_fail_msg("gather folio info failed\n");
@@ -296,7 +173,7 @@ static void verify_rss_anon_split_huge_page_all_zeroes(char *one_page, int nr_hp · 49 unmodified lines
296 unsigned long rss_anon_before, rss_anon_after;173 unsigned long rss_anon_before, rss_anon_after;
297 size_t i;174 size_t i;
298 175
299 if (!check_huge_anon(one_page, nr_hpages, pmd_pagesize))176 if (!check_huge_anon(one_page, nr_hpages * pmd_pagesize, nr_hpages, pmd_pagesize))
300 ksft_exit_fail_msg("No THP is allocated\n");177 ksft_exit_fail_msg("No THP is allocated\n");
301 178
302 rss_anon_before = rss_anon();179 rss_anon_before = rss_anon();
@@ -311,7 +188,7 @@ static void verify_rss_anon_split_huge_page_all_zeroes(char *one_page, int nr_hp · 8 unmodified lines
311 if (one_page[i] != (char)0)188 if (one_page[i] != (char)0)
312 ksft_exit_fail_msg("%ld byte corrupted\n", i);189 ksft_exit_fail_msg("%ld byte corrupted\n", i);
313 190
314 if (!check_huge_anon(one_page, 0, pmd_pagesize))191 if (!check_huge_anon(one_page, nr_hpages * pmd_pagesize, 0, pmd_pagesize))
315 ksft_exit_fail_msg("Still AnonHugePages not split\n");192 ksft_exit_fail_msg("Still AnonHugePages not split\n");
316 193
317 rss_anon_after = rss_anon();194 rss_anon_after = rss_anon();
@@ -347,7 +224,7 @@ static void split_pmd_thp_to_order(int order) · 29 unmodified lines
347 for (i = 0; i < len; i++)224 for (i = 0; i < len; i++)
348 one_page[i] = (char)i;225 one_page[i] = (char)i;
349 226
350 if (!check_huge_anon(one_page, 4, pmd_pagesize))227 if (!check_huge_anon(one_page, 4 * pmd_pagesize, 4, pmd_pagesize))
351 ksft_exit_fail_msg("No THP is allocated\n");228 ksft_exit_fail_msg("No THP is allocated\n");
352 229
353 /* split all THPs */230 /* split all THPs */
@@ -366,7 +243,7 @@ static void split_pmd_thp_to_order(int order) · 12 unmodified lines
366 (pmd_order + 1)))243 (pmd_order + 1)))
367 ksft_exit_fail_msg("Unexpected THP split\n");244 ksft_exit_fail_msg("Unexpected THP split\n");
368 245
369 if (!check_huge_anon(one_page, 0, pmd_pagesize))246 if (!check_huge_anon(one_page, 4 * pmd_pagesize, 0, pmd_pagesize))
370 ksft_exit_fail_msg("Still AnonHugePages not split\n");247 ksft_exit_fail_msg("Still AnonHugePages not split\n");
371 248
372 ksft_test_result_pass("Split huge pages to order %d successful\n", order);249 ksft_test_result_pass("Split huge pages to order %d successful\n", order);
@@ -393,7 +270,7 @@ static void split_pte_mapped_thp(void) · 20 unmodified lines
393 for (i = 0; i < thp_area_size; i++)270 for (i = 0; i < thp_area_size; i++)
394 thp_area[i] = (char)i;271 thp_area[i] = (char)i;
395 272
396 if (!check_huge_anon(thp_area, nr_thps, pmd_pagesize)) {273 if (!check_huge_anon(thp_area, nr_thps * pmd_pagesize, nr_thps, pmd_pagesize)) {
397 ksft_test_result_skip("Not all THPs allocated\n");274 ksft_test_result_skip("Not all THPs allocated\n");
398 goto out;275 goto out;
399 }276 }
@@ -657,7 +534,7 @@ static int create_pagecache_thp_and_fd(const char *testfile, size_t fd_size, · 257 unmodified lines
657 534
658 force_read_pages(*addr, fd_size / pmd_pagesize, pmd_pagesize);535 force_read_pages(*addr, fd_size / pmd_pagesize, pmd_pagesize);
659 536
660 if (!check_huge_file(*addr, fd_size / pmd_pagesize, pmd_pagesize)) {537 if (!check_huge_file(*addr, fd_size, fd_size / pmd_pagesize, pmd_pagesize)) {
661 ksft_print_msg("No large pagecache folio generated, please provide a filesystem supporting large folio\n");538 ksft_print_msg("No large pagecache folio generated, please provide a filesystem supporting large folio\n");
662 munmap(*addr, fd_size);539 munmap(*addr, fd_size);
663 close(*fd);540 close(*fd);
@@ -735,7 +612,7 @@ static void split_thp_in_pagecache_to_order_at(size_t fd_size, · 71 unmodified lines
735 goto out;612 goto out;
736 }613 }
737 614
738 if (!check_huge_file(addr, 0, pmd_pagesize)) {615 if (!check_huge_file(addr, fd_size, 0, pmd_pagesize)) {
739 ksft_print_msg("Still FilePmdMapped not split\n");616 ksft_print_msg("Still FilePmdMapped not split\n");
740 err = EXIT_FAILURE;617 err = EXIT_FAILURE;
741 goto out;618 goto out;
tools/testing/selftests/mm/uffd-common.c+3−1
@@ -194,7 +194,9 @@ static void shmem_alias_mapping(uffd_global_test_opts_t *gopts, __u64 *start, · 193 unmodified lines
194 194
195static void shmem_check_pmd_mapping(uffd_global_test_opts_t *gopts, void *p, int expect_nr_hpages)195static void shmem_check_pmd_mapping(uffd_global_test_opts_t *gopts, void *p, int expect_nr_hpages)
196{196{
197 if (!check_huge_shmem(gopts->area_dst_alias, expect_nr_hpages,197 size_t len = expect_nr_hpages * read_pmd_pagesize();
198
199 if (!check_huge_shmem(gopts->area_dst_alias, len, expect_nr_hpages,
198 read_pmd_pagesize()))200 read_pmd_pagesize()))
199 err("Did not find expected %d number of hugepages",201 err("Did not find expected %d number of hugepages",
200 expect_nr_hpages);202 expect_nr_hpages);
tools/testing/selftests/mm/vm_util.c+197−10
@@ -15,6 +15,9 @@ · 14 unmodified lines
15#define SMAP_FILE_PATH "/proc/self/smaps"15#define SMAP_FILE_PATH "/proc/self/smaps"
16#define STATUS_FILE_PATH "/proc/self/status"16#define STATUS_FILE_PATH "/proc/self/status"
17#define MAX_LINE_LENGTH 50017#define MAX_LINE_LENGTH 500
18#define PAGEMAP_PATH "/proc/self/pagemap"
19#define KPAGEFLAGS_PATH "/proc/kpageflags"
20#define MAX_NR_ORDERS 20
18 21
19unsigned int __page_size;22unsigned int __page_size;
20unsigned int __page_shift;23unsigned int __page_shift;
@@ -31,7 +34,7 @@ uint64_t pagemap_get_entry(int fd, char *start) · 10 unmodified lines
31 return entry;34 return entry;
32}35}
33 36
34static uint64_t __pagemap_scan_get_categories(int fd, char *start, struct page_region *r)37static int __pagemap_scan_get_categories(int fd, char *start, struct page_region *r)
35{38{
36 struct pm_scan_arg arg;39 struct pm_scan_arg arg;
37 40
@@ -55,7 +58,7 @@ static uint64_t __pagemap_scan_get_categories(int fd, char *start, struct page_r · 17 unmodified lines
55static uint64_t pagemap_scan_get_categories(int fd, char *start)58static uint64_t pagemap_scan_get_categories(int fd, char *start)
56{59{
57 struct page_region r;60 struct page_region r;
58 long ret;61 int ret;
59 62
60 ret = __pagemap_scan_get_categories(fd, start, &r);63 ret = __pagemap_scan_get_categories(fd, start, &r);
61 if (ret < 0)64 if (ret < 0)
@@ -194,6 +197,125 @@ err_out: · 132 unmodified lines
194 return rss_anon;197 return rss_anon;
195}198}
196 199
200static int vaddr_pageflags_get(char *vaddr, int pagemap_fd, int kpageflags_fd,
201 uint64_t *flags)
202{
203 unsigned long pfn;
204
205 pfn = pagemap_get_pfn(pagemap_fd, vaddr);
206
207 /* non-present PFN */
208 if (pfn == -1UL)
209 return 1;
210
211 if (pageflags_get(pfn, kpageflags_fd, flags))
212 return -1;
213
214 return 0;
215}
216
217/*
218 * gather_folio_orders - scan through [vaddr_start, len) and record
219 * folio orders
220 *
221 * @vaddr_start: start vaddr
222 * @len: range length
223 * @pagemap_fd: file descriptor to /proc/<pid>/pagemap
224 * @kpageflags_fd: file descriptor to /proc/kpageflags
225 * @orders: output folio order array
226 * @nr_orders: folio order array size
227 *
228 * gather_folio_orders() scan through [vaddr_start, len) and check
229 * all folios within the range and record their orders. All order-0 pages will
230 * be recorded. Non-present vaddr is skipped.
231 *
232 * Return: 0 - no error, -1 - unhandled cases
233 */
234int gather_folio_orders(char *vaddr_start, size_t len,
235 int pagemap_fd, int kpageflags_fd, int orders[], int nr_orders)
236{
237 uint64_t page_flags = 0;
238 int cur_order = -1;
239 char *vaddr;
240
241 if (pagemap_fd == -1 || kpageflags_fd == -1)
242 return -1;
243 if (!orders)
244 return -1;
245 if (nr_orders <= 0)
246 return -1;
247
248 for (vaddr = vaddr_start; vaddr < vaddr_start + len;) {
249 char *next_folio_vaddr;
250 int status;
251
252 status = vaddr_pageflags_get(vaddr, pagemap_fd, kpageflags_fd,
253 &page_flags);
254 if (status < 0)
255 return -1;
256
257 /* skip non present vaddr */
258 if (status == 1) {
259 vaddr += psize();
260 continue;
261 }
262
263 /* all order-0 pages with possible false postive (non folio) */
264 if (!(page_flags & (KPF_COMPOUND_HEAD | KPF_COMPOUND_TAIL))) {
265 orders[0]++;
266 vaddr += psize();
267 continue;
268 }
269
270 /* skip non thp compound pages */
271 if (!(page_flags & KPF_THP)) {
272 vaddr += psize();
273 continue;
274 }
275
276 /* vpn points to part of a THP at this point */
277 if (page_flags & KPF_COMPOUND_HEAD)
278 cur_order = 1;
279 else {
280 vaddr += psize();
281 continue;
282 }
283
284 next_folio_vaddr = vaddr + (1UL << (cur_order + pshift()));
285
286 if (next_folio_vaddr >= vaddr_start + len)
287 break;
288
289 while ((status = vaddr_pageflags_get(next_folio_vaddr,
290 pagemap_fd, kpageflags_fd,
291 &page_flags)) >= 0) {
292 /*
293 * non present vaddr, next compound head page, or
294 * order-0 page
295 */
296 if (status == 1 ||
297 (page_flags & KPF_COMPOUND_HEAD) ||
298 !(page_flags & (KPF_COMPOUND_HEAD | KPF_COMPOUND_TAIL))) {
299 if (cur_order < nr_orders) {
300 orders[cur_order]++;
301 cur_order = -1;
302 vaddr = next_folio_vaddr;
303 }
304 break;
305 }
306
307 cur_order++;
308 next_folio_vaddr = vaddr + (1UL << (cur_order + pshift()));
309 }
310
311 if (status < 0)
312 return status;
313 }
314 if (cur_order > 0 && cur_order < nr_orders)
315 orders[cur_order]++;
316 return 0;
317}
318
197char *__get_smap_entry(void *addr, const char *pattern, char *buf, size_t len)319char *__get_smap_entry(void *addr, const char *pattern, char *buf, size_t len)
198{320{
199 int ret;321 int ret;
@@ -229,7 +351,7 @@ err_out: · 29 unmodified lines
229 return entry;351 return entry;
230}352}
231 353
232bool __check_huge(void *addr, char *pattern, int nr_hpages,354static bool __check_pmd_huge(void *addr, char *pattern, int nr_hpages,
233 uint64_t hpage_size)355 uint64_t hpage_size)
234{356{
235 char buffer[MAX_LINE_LENGTH];357 char buffer[MAX_LINE_LENGTH];
@@ -247,19 +369,84 @@ err_out: · 11 unmodified lines
247 return thp == (nr_hpages * (hpage_size >> 10));369 return thp == (nr_hpages * (hpage_size >> 10));
248}370}
249 371
250bool check_huge_anon(void *addr, int nr_hpages, uint64_t hpage_size)372static bool check_large_folios(void *addr, size_t len, int nr_hpages,
373 uint64_t hpage_size)
251{374{
252 return __check_huge(addr, "AnonHugePages: ", nr_hpages, hpage_size);375 int order = 0, pagesize = getpagesize();
376 unsigned int nr_pages = hpage_size / pagesize;
377 int orders[MAX_NR_ORDERS], status;
378 int pagemap_fd, kpageflags_fd;
379 bool ret = false;
380
381 if (!nr_pages)
382 ksft_exit_fail_msg("invalid hugepage size\n");
383
384 order = 31 - __builtin_clz(nr_pages);
385 if (!order || order >= MAX_NR_ORDERS)
386 ksft_exit_fail_msg("invalid order\n");
387
388 memset(orders, 0, sizeof(int) * MAX_NR_ORDERS);
389 pagemap_fd = open(PAGEMAP_PATH, O_RDONLY);
390 if (pagemap_fd == -1)
391 ksft_exit_fail_msg("read pagemap fail\n");
392
393 kpageflags_fd = open(KPAGEFLAGS_PATH, O_RDONLY);
394 if (kpageflags_fd == -1) {
395 close(pagemap_fd);
396 ksft_exit_fail_msg("read kpageflags fail\n");
397 }
398
399 status = gather_folio_orders(addr, len, pagemap_fd,
400 kpageflags_fd, orders, MAX_NR_ORDERS);
401 if (status)
402 goto out;
403
404 if (orders[order] == nr_hpages)
405 ret = true;
406
407out:
408 close(pagemap_fd);
409 close(kpageflags_fd);
410 return ret;
253}411}
254 412
255bool check_huge_file(void *addr, int nr_hpages, uint64_t hpage_size)413bool check_huge_anon(void *addr, size_t len, int nr_hpages, uint64_t hpage_size)
256{414{
257 return __check_huge(addr, "FilePmdMapped:", nr_hpages, hpage_size);415 uint64_t pmd_pagesize = read_pmd_pagesize();
416
417 if (!pmd_pagesize)
418 ksft_exit_fail_msg("reading PMD pagesize failed\n");
419
420 if (hpage_size == pmd_pagesize)
421 return __check_pmd_huge(addr, "AnonHugePages: ", nr_hpages, hpage_size);
422
423 return check_large_folios(addr, len, nr_hpages, hpage_size);
258}424}
259 425
260bool check_huge_shmem(void *addr, int nr_hpages, uint64_t hpage_size)426bool check_huge_file(void *addr, size_t len, int nr_hpages, uint64_t hpage_size)
261{427{
262 return __check_huge(addr, "ShmemPmdMapped:", nr_hpages, hpage_size);428 uint64_t pmd_pagesize = read_pmd_pagesize();
429
430 if (!pmd_pagesize)
431 ksft_exit_fail_msg("reading PMD pagesize failed\n");
432
433 if (hpage_size == pmd_pagesize)
434 return __check_pmd_huge(addr, "FilePmdMapped:", nr_hpages, hpage_size);
435
436 return check_large_folios(addr, len, nr_hpages, hpage_size);
437}
438
439bool check_huge_shmem(void *addr, size_t len, int nr_hpages, uint64_t hpage_size)
440{
441 uint64_t pmd_pagesize = read_pmd_pagesize();
442
443 if (!pmd_pagesize)
444 ksft_exit_fail_msg("reading PMD pagesize failed\n");
445
446 if (hpage_size == pmd_pagesize)
447 return __check_pmd_huge(addr, "ShmemPmdMapped:", nr_hpages, hpage_size);
448
449 return check_large_folios(addr, len, nr_hpages, hpage_size);
263}450}
264 451
265int64_t allocate_transhuge(void *ptr, int pagemap_fd)452int64_t allocate_transhuge(void *ptr, int pagemap_fd)
@@ -755,7 +942,7 @@ unsigned long read_num(const char *path) · 489 unmodified lines
755{942{
756 char buf[21];943 char buf[21];
757 944
758 if (read_file(path, buf, sizeof(buf)) < 0)945 if (!read_file(path, buf, sizeof(buf)))
759 ksft_exit_fail_perror("read_file()");946 ksft_exit_fail_perror("read_file()");
760 947
761 return strtoul(buf, NULL, 10);948 return strtoul(buf, NULL, 10);
tools/testing/selftests/mm/vm_util.h+5−3
@@ -90,11 +90,13 @@ void clear_softdirty(void); · 89 unmodified lines
90bool check_for_pattern(FILE *fp, const char *pattern, char *buf, size_t len);90bool check_for_pattern(FILE *fp, const char *pattern, char *buf, size_t len);
91uint64_t read_pmd_pagesize(void);91uint64_t read_pmd_pagesize(void);
92unsigned long rss_anon(void);92unsigned long rss_anon(void);
93bool check_huge_anon(void *addr, int nr_hpages, uint64_t hpage_size);93bool check_huge_anon(void *addr, size_t len, int nr_hpages, uint64_t hpage_size);
94bool check_huge_file(void *addr, int nr_hpages, uint64_t hpage_size);94bool check_huge_file(void *addr, size_t len, int nr_hpages, uint64_t hpage_size);
95bool check_huge_shmem(void *addr, int nr_hpages, uint64_t hpage_size);95bool check_huge_shmem(void *addr, size_t len, int nr_hpages, uint64_t hpage_size);
96int64_t allocate_transhuge(void *ptr, int pagemap_fd);96int64_t allocate_transhuge(void *ptr, int pagemap_fd);
97int pageflags_get(unsigned long pfn, int kpageflags_fd, uint64_t *flags);97int pageflags_get(unsigned long pfn, int kpageflags_fd, uint64_t *flags);
98int gather_folio_orders(char *vaddr_start, size_t len,
99 int pagemap_fd, int kpageflags_fd, int orders[], int nr_orders);
98 100
99int uffd_register(int uffd, void *addr, uint64_t len,101int uffd_register(int uffd, void *addr, uint64_t len,
100 bool miss, bool wp, bool minor);102 bool miss, bool wp, bool minor);
tools/testing/selftests/proc/proc-maps-race.c+2−1
@@ -490,7 +490,8 @@ static bool query_addr_at(int maps_fd, void *addr, · 489 unmodified lines
490 490
491static inline bool split_vma(FIXTURE_DATA(proc_maps_race) *self)491static inline bool split_vma(FIXTURE_DATA(proc_maps_race) *self)
492{492{
493 return mmap(self->mod_info->addr, self->page_size, self->mod_info->prot | PROT_EXEC,493 /* PROT_NONE differs from both readable neighbors. */
494 return mmap(self->mod_info->addr, self->page_size, PROT_NONE,
494 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) != MAP_FAILED;495 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) != MAP_FAILED;
495}496}
496 497
tools/testing/vma/include/dup.h+62−2
@@ -243,7 +243,7 @@ enum { · 242 unmodified lines
243#define VM_NOHUGEPAGE INIT_VM_FLAG(NOHUGEPAGE)243#define VM_NOHUGEPAGE INIT_VM_FLAG(NOHUGEPAGE)
244#define VM_MERGEABLE INIT_VM_FLAG(MERGEABLE)244#define VM_MERGEABLE INIT_VM_FLAG(MERGEABLE)
245#define VM_STACK INIT_VM_FLAG(STACK)245#define VM_STACK INIT_VM_FLAG(STACK)
246#ifdef CONFIG_STACK_GROWS_UP246#ifdef CONFIG_STACK_GROWSUP
247#define VM_STACK_EARLY INIT_VM_FLAG(STACK_EARLY)247#define VM_STACK_EARLY INIT_VM_FLAG(STACK_EARLY)
248#define VMA_STACK_EARLY mk_vma_flags(VMA_STACK_EARLY_BIT)248#define VMA_STACK_EARLY mk_vma_flags(VMA_STACK_EARLY_BIT)
249#else249#else
@@ -577,6 +577,7 @@ struct vm_area_struct { · 327 unmodified lines
577 */577 */
578 unsigned int vm_lock_seq;578 unsigned int vm_lock_seq;
579#endif579#endif
580 unsigned int __vm_anon_pgoff_lo;
580 581
581 /*582 /*
582 * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma583 * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma
@@ -612,6 +613,9 @@ struct vm_area_struct { · 29 unmodified lines
612#ifdef CONFIG_PER_VMA_LOCK613#ifdef CONFIG_PER_VMA_LOCK
613 /* Unstable RCU readers are allowed to read this. */614 /* Unstable RCU readers are allowed to read this. */
614 refcount_t vm_refcnt;615 refcount_t vm_refcnt;
616#endif
617#ifdef CONFIG_64BIT
618 unsigned int __vm_anon_pgoff_hi;
615#endif619#endif
616 /*620 /*
617 * For areas with an address space and backing store,621 * For areas with an address space and backing store,
@@ -1158,6 +1162,17 @@ static inline bool vma_is_shared_maywrite(struct vm_area_struct *vma) · 540 unmodified lines
1158 return is_shared_maywrite(&vma->flags);1162 return is_shared_maywrite(&vma->flags);
1159}1163}
1160 1164
1165static inline bool vma_flags_is_cow_mapping(const vma_flags_t *flags)
1166{
1167 return vma_flags_test(flags, VMA_MAYWRITE_BIT) &&
1168 !vma_flags_test(flags, VMA_SHARED_BIT);
1169}
1170
1171static inline bool vma_is_cow_mapping(const struct vm_area_struct *vma)
1172{
1173 return vma_flags_is_cow_mapping(&vma->flags);
1174}
1175
1161static inline struct vm_area_struct *vma_next(struct vma_iterator *vmi)1176static inline struct vm_area_struct *vma_next(struct vma_iterator *vmi)
1162{1177{
1163 /*1178 /*
@@ -1320,6 +1335,28 @@ static inline pgoff_t vma_end_pgoff(const struct vm_area_struct *vma) · 156 unmodified lines
1320 return vma_start_pgoff(vma) + vma_pages(vma);1335 return vma_start_pgoff(vma) + vma_pages(vma);
1321}1336}
1322 1337
1338static inline pgoff_t vma_start_anon_pgoff(const struct vm_area_struct *vma)
1339{
1340 pgoff_t pgoff = 0;
1341
1342#ifdef CONFIG_64BIT
1343 pgoff += vma->__vm_anon_pgoff_hi;
1344 pgoff <<= 32;
1345#endif
1346 pgoff += vma->__vm_anon_pgoff_lo;
1347 return pgoff;
1348}
1349
1350static inline pgoff_t vma_end_anon_pgoff(const struct vm_area_struct *vma)
1351{
1352 return vma_start_anon_pgoff(vma) + vma_pages(vma);
1353}
1354
1355static inline pgoff_t vma_last_anon_pgoff(const struct vm_area_struct *vma)
1356{
1357 return vma_end_anon_pgoff(vma) - 1;
1358}
1359
1323static inline int vfs_mmap_prepare(struct file *file, struct vm_area_desc *desc)1360static inline int vfs_mmap_prepare(struct file *file, struct vm_area_desc *desc)
1324{1361{
1325 return file->f_op->mmap_prepare(desc);1362 return file->f_op->mmap_prepare(desc);
@@ -1391,7 +1428,7 @@ static inline void vma_iter_set(struct vma_iterator *vmi, unsigned long addr) · 65 unmodified lines
1391 mas_set(&vmi->mas, addr);1428 mas_set(&vmi->mas, addr);
1392}1429}
1393 1430
1394static inline bool vma_is_anonymous(struct vm_area_struct *vma)1431static inline bool vma_is_anonymous(const struct vm_area_struct *vma)
1395{1432{
1396 return !vma->vm_ops;1433 return !vma->vm_ops;
1397}1434}
@@ -1584,3 +1621,26 @@ static inline pgprot_t vma_get_page_prot(const struct vm_area_struct *vma) · 186 unmodified lines
1584{1621{
1585 return vma_flags_to_page_prot(vma->flags);1622 return vma_flags_to_page_prot(vma->flags);
1586}1623}
1624
1625static inline pgoff_t __linear_anon_page_index(const struct vm_area_struct *vma,
1626 const unsigned long address)
1627{
1628 pgoff_t pgoff;
1629
1630 pgoff = linear_page_delta(vma, address);
1631 pgoff += vma_start_anon_pgoff(vma);
1632 return pgoff;
1633}
1634
1635static inline pgoff_t linear_anon_page_index(const struct vm_area_struct *vma,
1636 const unsigned long address)
1637{
1638 const pgoff_t pgoff = __linear_anon_page_index(vma, address);
1639
1640 VM_WARN_ON_ONCE(!vma_is_cow_mapping(vma));
1641 /* Account for MAP_PRIVATE-/dev/zero which is only semi-anonymous. */
1642 if (vma_is_anonymous(vma) && !vma->vm_file)
1643 VM_WARN_ON_ONCE(pgoff != linear_page_index(vma, address));
1644
1645 return pgoff;
1646}
tools/testing/vma/shared.c+2−1
@@ -23,7 +23,8 @@ struct vm_area_struct *alloc_vma(struct mm_struct *mm, · 22 unmodified lines
23 23
24 vma->vm_start = start;24 vma->vm_start = start;
25 vma->vm_end = end;25 vma->vm_end = end;
26 vma->vm_pgoff = pgoff;26 vma_set_pgoff(vma, pgoff);
27 vma_set_anon_pgoff(vma, start >> PAGE_SHIFT);
27 vma->flags = vma_flags;28 vma->flags = vma_flags;
28 vma_assert_detached(vma);29 vma_assert_detached(vma);
29 30
tools/testing/vma/tests/merge.c+39−10
@@ -45,6 +45,7 @@ void vmg_set_range(struct vma_merge_struct *vmg, unsigned long start, · 44 unmodified lines
45 vmg->start = start;45 vmg->start = start;
46 vmg->end = end;46 vmg->end = end;
47 vmg->pgoff = pgoff;47 vmg->pgoff = pgoff;
48 vmg->anon_pgoff = start >> PAGE_SHIFT;
48 vmg->vma_flags = vma_flags;49 vmg->vma_flags = vma_flags;
49 50
50 vmg->just_expand = false;51 vmg->just_expand = false;
@@ -108,6 +109,7 @@ static bool test_simple_merge(void) · 57 unmodified lines
108 .end = 0x2000,109 .end = 0x2000,
109 .vma_flags = vma_flags,110 .vma_flags = vma_flags,
110 .pgoff = 1,111 .pgoff = 1,
112 .anon_pgoff = 1,
111 };113 };
112 114
113 ASSERT_FALSE(attach_vma(&mm, vma_left));115 ASSERT_FALSE(attach_vma(&mm, vma_left));
@@ -119,6 +121,7 @@ static bool test_simple_merge(void) · 5 unmodified lines
119 ASSERT_EQ(vma->vm_start, 0);121 ASSERT_EQ(vma->vm_start, 0);
120 ASSERT_EQ(vma->vm_end, 0x3000);122 ASSERT_EQ(vma->vm_end, 0x3000);
121 ASSERT_EQ(vma_start_pgoff(vma), 0);123 ASSERT_EQ(vma_start_pgoff(vma), 0);
124 ASSERT_EQ(vma_start_anon_pgoff(vma), 0);
122 ASSERT_FLAGS_SAME_MASK(&vma->flags, vma_flags);125 ASSERT_FLAGS_SAME_MASK(&vma->flags, vma_flags);
123 126
124 detach_free_vma(vma);127 detach_free_vma(vma);
@@ -151,6 +154,7 @@ static bool test_simple_modify(void) · 26 unmodified lines
151 ASSERT_EQ(vma->vm_start, 0x1000);154 ASSERT_EQ(vma->vm_start, 0x1000);
152 ASSERT_EQ(vma->vm_end, 0x2000);155 ASSERT_EQ(vma->vm_end, 0x2000);
153 ASSERT_EQ(vma_start_pgoff(vma), 1);156 ASSERT_EQ(vma_start_pgoff(vma), 1);
157 ASSERT_EQ(vma_start_anon_pgoff(vma), 1);
154 158
155 /*159 /*
156 * Now walk through the three split VMAs and make sure they are as160 * Now walk through the three split VMAs and make sure they are as
@@ -163,6 +167,7 @@ static bool test_simple_modify(void) · 6 unmodified lines
163 ASSERT_EQ(vma->vm_start, 0);167 ASSERT_EQ(vma->vm_start, 0);
164 ASSERT_EQ(vma->vm_end, 0x1000);168 ASSERT_EQ(vma->vm_end, 0x1000);
165 ASSERT_EQ(vma_start_pgoff(vma), 0);169 ASSERT_EQ(vma_start_pgoff(vma), 0);
170 ASSERT_EQ(vma_start_anon_pgoff(vma), 0);
166 171
167 detach_free_vma(vma);172 detach_free_vma(vma);
168 vma_iter_clear(&vmi);173 vma_iter_clear(&vmi);
@@ -172,6 +177,7 @@ static bool test_simple_modify(void) · 3 unmodified lines
172 ASSERT_EQ(vma->vm_start, 0x1000);177 ASSERT_EQ(vma->vm_start, 0x1000);
173 ASSERT_EQ(vma->vm_end, 0x2000);178 ASSERT_EQ(vma->vm_end, 0x2000);
174 ASSERT_EQ(vma_start_pgoff(vma), 1);179 ASSERT_EQ(vma_start_pgoff(vma), 1);
180 ASSERT_EQ(vma_start_anon_pgoff(vma), 1);
175 181
176 detach_free_vma(vma);182 detach_free_vma(vma);
177 vma_iter_clear(&vmi);183 vma_iter_clear(&vmi);
@@ -181,6 +187,7 @@ static bool test_simple_modify(void) · 3 unmodified lines
181 ASSERT_EQ(vma->vm_start, 0x2000);187 ASSERT_EQ(vma->vm_start, 0x2000);
182 ASSERT_EQ(vma->vm_end, 0x3000);188 ASSERT_EQ(vma->vm_end, 0x3000);
183 ASSERT_EQ(vma_start_pgoff(vma), 2);189 ASSERT_EQ(vma_start_pgoff(vma), 2);
190 ASSERT_EQ(vma_start_anon_pgoff(vma), 2);
184 191
185 detach_free_vma(vma);192 detach_free_vma(vma);
186 mtree_destroy(&mm.mm_mt);193 mtree_destroy(&mm.mm_mt);
@@ -210,6 +217,7 @@ static bool test_simple_expand(void) · 23 unmodified lines
210 ASSERT_EQ(vma->vm_start, 0);217 ASSERT_EQ(vma->vm_start, 0);
211 ASSERT_EQ(vma->vm_end, 0x3000);218 ASSERT_EQ(vma->vm_end, 0x3000);
212 ASSERT_EQ(vma_start_pgoff(vma), 0);219 ASSERT_EQ(vma_start_pgoff(vma), 0);
220 ASSERT_EQ(vma_start_anon_pgoff(vma), 0);
213 221
214 detach_free_vma(vma);222 detach_free_vma(vma);
215 mtree_destroy(&mm.mm_mt);223 mtree_destroy(&mm.mm_mt);
@@ -232,6 +240,7 @@ static bool test_simple_shrink(void) · 16 unmodified lines
232 ASSERT_EQ(vma->vm_start, 0);240 ASSERT_EQ(vma->vm_start, 0);
233 ASSERT_EQ(vma->vm_end, 0x1000);241 ASSERT_EQ(vma->vm_end, 0x1000);
234 ASSERT_EQ(vma_start_pgoff(vma), 0);242 ASSERT_EQ(vma_start_pgoff(vma), 0);
243 ASSERT_EQ(vma_start_anon_pgoff(vma), 0);
235 244
236 detach_free_vma(vma);245 detach_free_vma(vma);
237 mtree_destroy(&mm.mm_mt);246 mtree_destroy(&mm.mm_mt);
@@ -344,6 +353,7 @@ static bool __test_merge_new(bool is_sticky, bool a_is_sticky, bool b_is_sticky, · 106 unmodified lines
344 ASSERT_EQ(vma->vm_start, 0);353 ASSERT_EQ(vma->vm_start, 0);
345 ASSERT_EQ(vma->vm_end, 0x5000);354 ASSERT_EQ(vma->vm_end, 0x5000);
346 ASSERT_EQ(vma_start_pgoff(vma), 0);355 ASSERT_EQ(vma_start_pgoff(vma), 0);
356 ASSERT_EQ(vma_start_anon_pgoff(vma), 0);
347 ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);357 ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);
348 ASSERT_TRUE(vma_write_started(vma));358 ASSERT_TRUE(vma_write_started(vma));
349 ASSERT_EQ(mm.map_count, 3);359 ASSERT_EQ(mm.map_count, 3);
@@ -365,6 +375,7 @@ static bool __test_merge_new(bool is_sticky, bool a_is_sticky, bool b_is_sticky, · 15 unmodified lines
365 ASSERT_EQ(vma->vm_start, 0x6000);375 ASSERT_EQ(vma->vm_start, 0x6000);
366 ASSERT_EQ(vma->vm_end, 0x9000);376 ASSERT_EQ(vma->vm_end, 0x9000);
367 ASSERT_EQ(vma_start_pgoff(vma), 6);377 ASSERT_EQ(vma_start_pgoff(vma), 6);
378 ASSERT_EQ(vma_start_anon_pgoff(vma), 6);
368 ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);379 ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);
369 ASSERT_TRUE(vma_write_started(vma));380 ASSERT_TRUE(vma_write_started(vma));
370 ASSERT_EQ(mm.map_count, 3);381 ASSERT_EQ(mm.map_count, 3);
@@ -385,6 +396,7 @@ static bool __test_merge_new(bool is_sticky, bool a_is_sticky, bool b_is_sticky, · 14 unmodified lines
385 ASSERT_EQ(vma->vm_start, 0);396 ASSERT_EQ(vma->vm_start, 0);
386 ASSERT_EQ(vma->vm_end, 0x9000);397 ASSERT_EQ(vma->vm_end, 0x9000);
387 ASSERT_EQ(vma_start_pgoff(vma), 0);398 ASSERT_EQ(vma_start_pgoff(vma), 0);
399 ASSERT_EQ(vma_start_anon_pgoff(vma), 0);
388 ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);400 ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);
389 ASSERT_TRUE(vma_write_started(vma));401 ASSERT_TRUE(vma_write_started(vma));
390 ASSERT_EQ(mm.map_count, 2);402 ASSERT_EQ(mm.map_count, 2);
@@ -405,6 +417,7 @@ static bool __test_merge_new(bool is_sticky, bool a_is_sticky, bool b_is_sticky, · 14 unmodified lines
405 ASSERT_EQ(vma->vm_start, 0xa000);417 ASSERT_EQ(vma->vm_start, 0xa000);
406 ASSERT_EQ(vma->vm_end, 0xc000);418 ASSERT_EQ(vma->vm_end, 0xc000);
407 ASSERT_EQ(vma_start_pgoff(vma), 0xa);419 ASSERT_EQ(vma_start_pgoff(vma), 0xa);
420 ASSERT_EQ(vma_start_anon_pgoff(vma), 0xa);
408 ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);421 ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);
409 ASSERT_TRUE(vma_write_started(vma));422 ASSERT_TRUE(vma_write_started(vma));
410 ASSERT_EQ(mm.map_count, 2);423 ASSERT_EQ(mm.map_count, 2);
@@ -424,6 +437,7 @@ static bool __test_merge_new(bool is_sticky, bool a_is_sticky, bool b_is_sticky, · 13 unmodified lines
424 ASSERT_EQ(vma->vm_start, 0);437 ASSERT_EQ(vma->vm_start, 0);
425 ASSERT_EQ(vma->vm_end, 0xc000);438 ASSERT_EQ(vma->vm_end, 0xc000);
426 ASSERT_EQ(vma_start_pgoff(vma), 0);439 ASSERT_EQ(vma_start_pgoff(vma), 0);
440 ASSERT_EQ(vma_start_anon_pgoff(vma), 0);
427 ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);441 ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);
428 ASSERT_TRUE(vma_write_started(vma));442 ASSERT_TRUE(vma_write_started(vma));
429 ASSERT_EQ(mm.map_count, 1);443 ASSERT_EQ(mm.map_count, 1);
@@ -444,6 +458,7 @@ static bool __test_merge_new(bool is_sticky, bool a_is_sticky, bool b_is_sticky, · 14 unmodified lines
444 ASSERT_EQ(vma->vm_start, 0);458 ASSERT_EQ(vma->vm_start, 0);
445 ASSERT_EQ(vma->vm_end, 0xc000);459 ASSERT_EQ(vma->vm_end, 0xc000);
446 ASSERT_EQ(vma_start_pgoff(vma), 0);460 ASSERT_EQ(vma_start_pgoff(vma), 0);
461 ASSERT_EQ(vma_start_anon_pgoff(vma), 0);
447 ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);462 ASSERT_EQ(vma->anon_vma, &dummy_anon_vma);
448 463
449 detach_free_vma(vma);464 detach_free_vma(vma);
@@ -640,7 +655,8 @@ static bool test_vma_merge_with_close(void) · 190 unmodified lines
640 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);655 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
641 ASSERT_EQ(vma_prev->vm_start, 0);656 ASSERT_EQ(vma_prev->vm_start, 0);
642 ASSERT_EQ(vma_prev->vm_end, 0x5000);657 ASSERT_EQ(vma_prev->vm_end, 0x5000);
643 ASSERT_EQ(vma_prev->vm_pgoff, 0);658 ASSERT_EQ(vma_start_pgoff(vma_prev), 0);
659 ASSERT_EQ(vma_start_anon_pgoff(vma_prev), 0);
644 660
645 ASSERT_EQ(cleanup_mm(&mm, &vmi), 2);661 ASSERT_EQ(cleanup_mm(&mm, &vmi), 2);
646 662
@@ -751,7 +767,8 @@ static bool test_vma_merge_with_close(void) · 104 unmodified lines
751 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);767 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
752 ASSERT_EQ(vma_prev->vm_start, 0);768 ASSERT_EQ(vma_prev->vm_start, 0);
753 ASSERT_EQ(vma_prev->vm_end, 0x5000);769 ASSERT_EQ(vma_prev->vm_end, 0x5000);
754 ASSERT_EQ(vma_prev->vm_pgoff, 0);770 ASSERT_EQ(vma_start_pgoff(vma_prev), 0);
771 ASSERT_EQ(vma_start_anon_pgoff(vma_prev), 0);
755 772
756 ASSERT_EQ(cleanup_mm(&mm, &vmi), 2);773 ASSERT_EQ(cleanup_mm(&mm, &vmi), 2);
757 774
@@ -806,6 +823,7 @@ static bool test_vma_merge_new_with_close(void) · 48 unmodified lines
806 ASSERT_EQ(vma->vm_start, 0);823 ASSERT_EQ(vma->vm_start, 0);
807 ASSERT_EQ(vma->vm_end, 0x5000);824 ASSERT_EQ(vma->vm_end, 0x5000);
808 ASSERT_EQ(vma_start_pgoff(vma), 0);825 ASSERT_EQ(vma_start_pgoff(vma), 0);
826 ASSERT_EQ(vma_start_anon_pgoff(vma), 0);
809 ASSERT_EQ(vma->vm_ops, &vm_ops);827 ASSERT_EQ(vma->vm_ops, &vm_ops);
810 ASSERT_TRUE(vma_write_started(vma));828 ASSERT_TRUE(vma_write_started(vma));
811 ASSERT_EQ(mm.map_count, 2);829 ASSERT_EQ(mm.map_count, 2);
@@ -861,11 +879,13 @@ static bool __test_merge_existing(bool prev_is_sticky, bool middle_is_sticky, bo · 49 unmodified lines
861 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);879 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
862 ASSERT_EQ(vma_next->vm_start, 0x3000);880 ASSERT_EQ(vma_next->vm_start, 0x3000);
863 ASSERT_EQ(vma_next->vm_end, 0x9000);881 ASSERT_EQ(vma_next->vm_end, 0x9000);
864 ASSERT_EQ(vma_next->vm_pgoff, 3);882 ASSERT_EQ(vma_start_pgoff(vma_next), 3);
883 ASSERT_EQ(vma_start_anon_pgoff(vma_next), 3);
865 ASSERT_EQ(vma_next->anon_vma, &dummy_anon_vma);884 ASSERT_EQ(vma_next->anon_vma, &dummy_anon_vma);
866 ASSERT_EQ(vma->vm_start, 0x2000);885 ASSERT_EQ(vma->vm_start, 0x2000);
867 ASSERT_EQ(vma->vm_end, 0x3000);886 ASSERT_EQ(vma->vm_end, 0x3000);
868 ASSERT_EQ(vma_start_pgoff(vma), 2);887 ASSERT_EQ(vma_start_pgoff(vma), 2);
888 ASSERT_EQ(vma_start_anon_pgoff(vma), 2);
869 ASSERT_TRUE(vma_write_started(vma));889 ASSERT_TRUE(vma_write_started(vma));
870 ASSERT_TRUE(vma_write_started(vma_next));890 ASSERT_TRUE(vma_write_started(vma_next));
871 ASSERT_EQ(mm.map_count, 2);891 ASSERT_EQ(mm.map_count, 2);
@@ -895,7 +915,8 @@ static bool __test_merge_existing(bool prev_is_sticky, bool middle_is_sticky, bo · 23 unmodified lines
895 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);915 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
896 ASSERT_EQ(vma_next->vm_start, 0x2000);916 ASSERT_EQ(vma_next->vm_start, 0x2000);
897 ASSERT_EQ(vma_next->vm_end, 0x9000);917 ASSERT_EQ(vma_next->vm_end, 0x9000);
898 ASSERT_EQ(vma_next->vm_pgoff, 2);918 ASSERT_EQ(vma_start_pgoff(vma_next), 2);
919 ASSERT_EQ(vma_start_anon_pgoff(vma_next), 2);
899 ASSERT_EQ(vma_next->anon_vma, &dummy_anon_vma);920 ASSERT_EQ(vma_next->anon_vma, &dummy_anon_vma);
900 ASSERT_TRUE(vma_write_started(vma_next));921 ASSERT_TRUE(vma_write_started(vma_next));
901 ASSERT_EQ(mm.map_count, 1);922 ASSERT_EQ(mm.map_count, 1);
@@ -927,11 +948,13 @@ static bool __test_merge_existing(bool prev_is_sticky, bool middle_is_sticky, bo · 25 unmodified lines
927 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);948 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
928 ASSERT_EQ(vma_prev->vm_start, 0);949 ASSERT_EQ(vma_prev->vm_start, 0);
929 ASSERT_EQ(vma_prev->vm_end, 0x6000);950 ASSERT_EQ(vma_prev->vm_end, 0x6000);
930 ASSERT_EQ(vma_prev->vm_pgoff, 0);951 ASSERT_EQ(vma_start_pgoff(vma_prev), 0);
952 ASSERT_EQ(vma_start_anon_pgoff(vma_prev), 0);
931 ASSERT_EQ(vma_prev->anon_vma, &dummy_anon_vma);953 ASSERT_EQ(vma_prev->anon_vma, &dummy_anon_vma);
932 ASSERT_EQ(vma->vm_start, 0x6000);954 ASSERT_EQ(vma->vm_start, 0x6000);
933 ASSERT_EQ(vma->vm_end, 0x7000);955 ASSERT_EQ(vma->vm_end, 0x7000);
934 ASSERT_EQ(vma_start_pgoff(vma), 6);956 ASSERT_EQ(vma_start_pgoff(vma), 6);
957 ASSERT_EQ(vma_start_anon_pgoff(vma), 6);
935 ASSERT_TRUE(vma_write_started(vma_prev));958 ASSERT_TRUE(vma_write_started(vma_prev));
936 ASSERT_TRUE(vma_write_started(vma));959 ASSERT_TRUE(vma_write_started(vma));
937 ASSERT_EQ(mm.map_count, 2);960 ASSERT_EQ(mm.map_count, 2);
@@ -962,7 +985,8 @@ static bool __test_merge_existing(bool prev_is_sticky, bool middle_is_sticky, bo · 24 unmodified lines
962 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);985 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
963 ASSERT_EQ(vma_prev->vm_start, 0);986 ASSERT_EQ(vma_prev->vm_start, 0);
964 ASSERT_EQ(vma_prev->vm_end, 0x7000);987 ASSERT_EQ(vma_prev->vm_end, 0x7000);
965 ASSERT_EQ(vma_prev->vm_pgoff, 0);988 ASSERT_EQ(vma_start_pgoff(vma_prev), 0);
989 ASSERT_EQ(vma_start_anon_pgoff(vma_prev), 0);
966 ASSERT_EQ(vma_prev->anon_vma, &dummy_anon_vma);990 ASSERT_EQ(vma_prev->anon_vma, &dummy_anon_vma);
967 ASSERT_TRUE(vma_write_started(vma_prev));991 ASSERT_TRUE(vma_write_started(vma_prev));
968 ASSERT_EQ(mm.map_count, 1);992 ASSERT_EQ(mm.map_count, 1);
@@ -994,7 +1018,8 @@ static bool __test_merge_existing(bool prev_is_sticky, bool middle_is_sticky, bo · 25 unmodified lines
994 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);1018 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
995 ASSERT_EQ(vma_prev->vm_start, 0);1019 ASSERT_EQ(vma_prev->vm_start, 0);
996 ASSERT_EQ(vma_prev->vm_end, 0x9000);1020 ASSERT_EQ(vma_prev->vm_end, 0x9000);
997 ASSERT_EQ(vma_prev->vm_pgoff, 0);1021 ASSERT_EQ(vma_start_pgoff(vma_prev), 0);
1022 ASSERT_EQ(vma_start_anon_pgoff(vma_prev), 0);
998 ASSERT_EQ(vma_prev->anon_vma, &dummy_anon_vma);1023 ASSERT_EQ(vma_prev->anon_vma, &dummy_anon_vma);
999 ASSERT_TRUE(vma_write_started(vma_prev));1024 ASSERT_TRUE(vma_write_started(vma_prev));
1000 ASSERT_EQ(mm.map_count, 1);1025 ASSERT_EQ(mm.map_count, 1);
@@ -1124,7 +1149,8 @@ static bool test_anon_vma_non_mergeable(void) · 123 unmodified lines
1124 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);1149 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
1125 ASSERT_EQ(vma_prev->vm_start, 0);1150 ASSERT_EQ(vma_prev->vm_start, 0);
1126 ASSERT_EQ(vma_prev->vm_end, 0x7000);1151 ASSERT_EQ(vma_prev->vm_end, 0x7000);
1127 ASSERT_EQ(vma_prev->vm_pgoff, 0);1152 ASSERT_EQ(vma_start_pgoff(vma_prev), 0);
1153 ASSERT_EQ(vma_start_anon_pgoff(vma_prev), 0);
1128 ASSERT_TRUE(vma_write_started(vma_prev));1154 ASSERT_TRUE(vma_write_started(vma_prev));
1129 ASSERT_FALSE(vma_write_started(vma_next));1155 ASSERT_FALSE(vma_write_started(vma_next));
1130 1156
@@ -1155,7 +1181,8 @@ static bool test_anon_vma_non_mergeable(void) · 24 unmodified lines
1155 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);1181 ASSERT_EQ(vmg.state, VMA_MERGE_SUCCESS);
1156 ASSERT_EQ(vma_prev->vm_start, 0);1182 ASSERT_EQ(vma_prev->vm_start, 0);
1157 ASSERT_EQ(vma_prev->vm_end, 0x7000);1183 ASSERT_EQ(vma_prev->vm_end, 0x7000);
1158 ASSERT_EQ(vma_prev->vm_pgoff, 0);1184 ASSERT_EQ(vma_start_pgoff(vma_prev), 0);
1185 ASSERT_EQ(vma_start_anon_pgoff(vma_prev), 0);
1159 ASSERT_TRUE(vma_write_started(vma_prev));1186 ASSERT_TRUE(vma_write_started(vma_prev));
1160 ASSERT_FALSE(vma_write_started(vma_next));1187 ASSERT_FALSE(vma_write_started(vma_next));
1161 1188
@@ -1417,6 +1444,7 @@ static bool test_merge_extend(void) · 255 unmodified lines
1417 ASSERT_EQ(vma->vm_start, 0);1444 ASSERT_EQ(vma->vm_start, 0);
1418 ASSERT_EQ(vma->vm_end, 0x4000);1445 ASSERT_EQ(vma->vm_end, 0x4000);
1419 ASSERT_EQ(vma_start_pgoff(vma), 0);1446 ASSERT_EQ(vma_start_pgoff(vma), 0);
1447 ASSERT_EQ(vma_start_anon_pgoff(vma), 0);
1420 ASSERT_TRUE(vma_write_started(vma));1448 ASSERT_TRUE(vma_write_started(vma));
1421 ASSERT_EQ(mm.map_count, 1);1449 ASSERT_EQ(mm.map_count, 1);
1422 1450
@@ -1431,7 +1459,7 @@ static bool test_expand_only_mode(void) · 8 unmodified lines
1431 struct mm_struct mm = {};1459 struct mm_struct mm = {};
1432 VMA_ITERATOR(vmi, &mm, 0);1460 VMA_ITERATOR(vmi, &mm, 0);
1433 struct vm_area_struct *vma_prev, *vma;1461 struct vm_area_struct *vma_prev, *vma;
1434 VMG_STATE(vmg, &mm, &vmi, 0x5000, 0x9000, vma_flags, 5);1462 VMG_STATE(vmg, &mm, &vmi, 0x5000, 0x9000, vma_flags, 5, 5);
1435 1463
1436 /*1464 /*
1437 * Place a VMA prior to the one we're expanding so we assert that we do1465 * Place a VMA prior to the one we're expanding so we assert that we do
@@ -1457,6 +1485,7 @@ static bool test_expand_only_mode(void) · 19 unmodified lines
1457 ASSERT_EQ(vma->vm_start, 0x3000);1485 ASSERT_EQ(vma->vm_start, 0x3000);
1458 ASSERT_EQ(vma->vm_end, 0x9000);1486 ASSERT_EQ(vma->vm_end, 0x9000);
1459 ASSERT_EQ(vma_start_pgoff(vma), 3);1487 ASSERT_EQ(vma_start_pgoff(vma), 3);
1488 ASSERT_EQ(vma_start_anon_pgoff(vma), 3);
1460 ASSERT_TRUE(vma_write_started(vma));1489 ASSERT_TRUE(vma_write_started(vma));
1461 ASSERT_EQ(vma_iter_addr(&vmi), 0x3000);1490 ASSERT_EQ(vma_iter_addr(&vmi), 0x3000);
1462 vma_assert_attached(vma);1491 vma_assert_attached(vma);
tools/testing/vma/tests/vma.c+47−3
@@ -33,12 +33,56 @@ static bool test_copy_vma(void) · 32 unmodified lines
33 struct mm_struct mm = {};33 struct mm_struct mm = {};
34 bool need_locks = false;34 bool need_locks = false;
35 VMA_ITERATOR(vmi, &mm, 0);35 VMA_ITERATOR(vmi, &mm, 0);
36 struct vm_area_struct *vma, *vma_new, *vma_next;36 struct vm_area_struct *vma, *vma_prev, *vma_new, *vma_next, *vma_orig;
37
38 /* Move forwards, adjacent to old self - self-merge. */
39
40 vma = alloc_and_link_vma(&mm, 0x1000, 0x2000, 1, vma_flags);
41 vma_set_anonymous(vma);
42 vma_orig = vma;
43 vma_new = copy_vma(&vma, 0x2000, 0x1000, 1, 1, &need_locks);
44 ASSERT_EQ(vma_new, vma_orig);
45 ASSERT_EQ(vma, vma_orig);
46 ASSERT_EQ(vma_new->vm_start, 0x1000);
47 ASSERT_EQ(vma_new->vm_end, 0x3000);
48
49 cleanup_mm(&mm, &vmi);
50
51 /* Move backwards, adjacent to old self - self-merge. */
52
53 vma = alloc_and_link_vma(&mm, 0x2000, 0x3000, 2, vma_flags);
54 vma_set_anonymous(vma);
55 vma_orig = vma;
56 vma_new = copy_vma(&vma, 0x1000, 0x1000, 2, 2, &need_locks);
57 ASSERT_EQ(vma_new, vma_orig);
58 ASSERT_EQ(vma, vma_orig);
59 ASSERT_EQ(vma_new->vm_start, 0x1000);
60 ASSERT_EQ(vma_new->vm_end, 0x3000);
61
62 cleanup_mm(&mm, &vmi);
63
64 /*
65 * Move backwards between prior VMA and old self - self-merge and vma
66 * updated to a new VMA.
67 */
68
69 vma_prev = alloc_and_link_vma(&mm, 0x1000, 0x2000, 1, vma_flags);
70 vma_set_anonymous(vma_prev);
71 vma = alloc_and_link_vma(&mm, 0x3000, 0x4000, 3, vma_flags);
72 vma_set_anonymous(vma);
73 vma_orig = vma;
74 vma_new = copy_vma(&vma, 0x2000, 0x1000, 3, 3, &need_locks);
75 ASSERT_NE(vma_new, vma_orig);
76 ASSERT_EQ(vma_new, vma);
77 ASSERT_EQ(vma_new->vm_start, 0x1000);
78 ASSERT_EQ(vma_new->vm_end, 0x4000);
79
80 cleanup_mm(&mm, &vmi);
37 81
38 /* Move backwards and do not merge. */82 /* Move backwards and do not merge. */
39 83
40 vma = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, vma_flags);84 vma = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, vma_flags);
41 vma_new = copy_vma(&vma, 0, 0x2000, 0, &need_locks);85 vma_new = copy_vma(&vma, 0, 0x2000, 0, 3, &need_locks);
42 ASSERT_NE(vma_new, vma);86 ASSERT_NE(vma_new, vma);
43 ASSERT_EQ(vma_new->vm_start, 0);87 ASSERT_EQ(vma_new->vm_start, 0);
44 ASSERT_EQ(vma_new->vm_end, 0x2000);88 ASSERT_EQ(vma_new->vm_end, 0x2000);
@@ -51,7 +95,7 @@ static bool test_copy_vma(void) · 6 unmodified lines
51 95
52 vma = alloc_and_link_vma(&mm, 0, 0x2000, 0, vma_flags);96 vma = alloc_and_link_vma(&mm, 0, 0x2000, 0, vma_flags);
53 vma_next = alloc_and_link_vma(&mm, 0x6000, 0x8000, 6, vma_flags);97 vma_next = alloc_and_link_vma(&mm, 0x6000, 0x8000, 6, vma_flags);
54 vma_new = copy_vma(&vma, 0x4000, 0x2000, 4, &need_locks);98 vma_new = copy_vma(&vma, 0x4000, 0x2000, 4, 4, &need_locks);
55 vma_assert_attached(vma_new);99 vma_assert_attached(vma_new);
56 100
57 ASSERT_EQ(vma_new, vma_next);101 ASSERT_EQ(vma_new, vma_next);
tools/testing/vma/vma_internal.h+1−0
@@ -53,6 +53,7 @@ typedef __bitwise unsigned int vm_fault_t; · 52 unmodified lines
53 53
54#define VM_WARN_ON(_expr) (WARN_ON(_expr))54#define VM_WARN_ON(_expr) (WARN_ON(_expr))
55#define VM_WARN_ON_ONCE(_expr) (WARN_ON_ONCE(_expr))55#define VM_WARN_ON_ONCE(_expr) (WARN_ON_ONCE(_expr))
56#define VM_WARN_ON_ONCE_VMA(_expr, _vma) (WARN_ON_ONCE(_expr))
56#define VM_WARN_ON_VMG(_expr, _vmg) (WARN_ON(_expr))57#define VM_WARN_ON_VMG(_expr, _vmg) (WARN_ON(_expr))
57#define VM_BUG_ON(_expr) (BUG_ON(_expr))58#define VM_BUG_ON(_expr) (BUG_ON(_expr))
58#define VM_BUG_ON_VMA(_expr, _vma) (BUG_ON(_expr))59#define VM_BUG_ON_VMA(_expr, _vma) (BUG_ON(_expr))