History

Merge tag 'mm-stable-2022-10-08' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull MM updates from Andrew Morton: - Yu Zhao's Multi-Gen LRU patches are here. They've been under test in linux-next for a couple of months without, to my knowledge, any negative reports (or any positive ones, come to that). - Also the Maple Tree from Liam Howlett. An overlapping range-based tree for vmas. It it apparently slightly more efficient in its own right, but is mainly targeted at enabling work to reduce mmap_lock contention. Liam has identified a number of other tree users in the kernel which could be beneficially onverted to mapletrees. Yu Zhao has identified a hard-to-hit but "easy to fix" lockdep splat at [1]. This has yet to be addressed due to Liam's unfortunately timed vacation. He is now back and we'll get this fixed up. - Dmitry Vyukov introduces KMSAN: the Kernel Memory Sanitizer. It uses clang-generated instrumentation to detect used-unintialized bugs down to the single bit level. KMSAN keeps finding bugs. New ones, as well as the legacy ones. - Yang Shi adds a userspace mechanism (madvise) to induce a collapse of memory into THPs. - Zach O'Keefe has expanded Yang Shi's madvise(MADV_COLLAPSE) to support file/shmem-backed pages. - userfaultfd updates from Axel Rasmussen - zsmalloc cleanups from Alexey Romanov - cleanups from Miaohe Lin: vmscan, hugetlb_cgroup, hugetlb and memory-failure - Huang Ying adds enhancements to NUMA balancing memory tiering mode's page promotion, with a new way of detecting hot pages. - memcg updates from Shakeel Butt: charging optimizations and reduced memory consumption. - memcg cleanups from Kairui Song. - memcg fixes and cleanups from Johannes Weiner. - Vishal Moola provides more folio conversions - Zhang Yi removed ll_rw_block() :( - migration enhancements from Peter Xu - migration error-path bugfixes from Huang Ying - Aneesh Kumar added ability for a device driver to alter the memory tiering promotion paths. For optimizations by PMEM drivers, DRM drivers, etc. - vma merging improvements from Jakub Matěn. - NUMA hinting cleanups from David Hildenbrand. - xu xin added aditional userspace visibility into KSM merging activity. - THP & KSM code consolidation from Qi Zheng. - more folio work from Matthew Wilcox. - KASAN updates from Andrey Konovalov. - DAMON cleanups from Kaixu Xia. - DAMON work from SeongJae Park: fixes, cleanups. - hugetlb sysfs cleanups from Muchun Song. - Mike Kravetz fixes locking issues in hugetlbfs and in hugetlb core. Link: https://lkml.kernel.org/r/CAOUHufZabH85CeUN-MEMgL8gJGzJEWUrkiM58JkTbBhh-jew0Q@mail.gmail.com [1] * tag 'mm-stable-2022-10-08' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (555 commits) hugetlb: allocate vma lock for all sharable vmas hugetlb: take hugetlb vma_lock when clearing vma_lock->vma pointer hugetlb: fix vma lock handling during split vma and range unmapping mglru: mm/vmscan.c: fix imprecise comments mm/mglru: don't sync disk for each aging cycle mm: memcontrol: drop dead CONFIG_MEMCG_SWAP config symbol mm: memcontrol: use do_memsw_account() in a few more places mm: memcontrol: deprecate swapaccounting=0 mode mm: memcontrol: don't allocate cgroup swap arrays when memcg is disabled mm/secretmem: remove reduntant return value mm/hugetlb: add available_huge_pages() func mm: remove unused inline functions from include/linux/mm_inline.h selftests/vm: add selftest for MADV_COLLAPSE of uffd-minor memory selftests/vm: add file/shmem MADV_COLLAPSE selftest for cleared pmd selftests/vm: add thp collapse shmem testing selftests/vm: add thp collapse file and tmpfs testing selftests/vm: modularize thp collapse memory operations selftests/vm: dedup THP helpers mm/khugepaged: add tracepoint to hpage_collapse_scan_file() mm/madvise: add file and shmem support to MADV_COLLAPSE ...

Linus Torvalds committed 4 years ago

Commit 27bc50f2 parents 70442fc bbff39c409 files · +65792 −8034Browse files

Unified · Split

409 files
  1. Documentation/ABI/testing/sysfs-kernel-mm-memory-tiers +25 −0
  2. Documentation/accounting/delay-accounting.rst +1 −1
  3. Documentation/admin-guide/cgroup-v1/memory.rst +1 −3
  4. Documentation/admin-guide/kernel-parameters.txt +8 −6
  5. Documentation/admin-guide/mm/cma_debugfs.rst +5 −5
  6. Documentation/admin-guide/mm/damon/index.rst +3 −3
  7. Documentation/admin-guide/mm/damon/start.rst +3 −10
  8. Documentation/admin-guide/mm/damon/usage.rst +5 −0
  9. Documentation/admin-guide/mm/index.rst +1 −0
  10. Documentation/admin-guide/mm/ksm.rst +36 −0
  11. Documentation/admin-guide/mm/multigen_lru.rst +162 −0
  12. Documentation/admin-guide/mm/transhuge.rst +11 −5
  13. Documentation/admin-guide/mm/userfaultfd.rst +38 −3
  14. Documentation/admin-guide/sysctl/kernel.rst +11 −0
  15. Documentation/admin-guide/sysctl/vm.rst +3 −0
  16. Documentation/core-api/index.rst +1 −0
  17. Documentation/core-api/maple_tree.rst +217 −0
  18. Documentation/core-api/mm-api.rst +0 −3
  19. Documentation/dev-tools/index.rst +1 −0
  20. Documentation/dev-tools/kasan.rst +11 −6
  21. Documentation/dev-tools/kmsan.rst +427 −0
  22. Documentation/mm/index.rst +1 −0
  23. Documentation/mm/ksm.rst +1 −1
  24. Documentation/mm/multigen_lru.rst +159 −0
  25. Documentation/mm/page_owner.rst +5 −0
  26. MAINTAINERS +26 −1
  27. Makefile +1 −0
  28. arch/Kconfig +8 −0
  29. arch/alpha/include/uapi/asm/mman.h +2 −0
  30. arch/arc/Kconfig +1 −1
  31. arch/arm/Kconfig +1 −1
  32. arch/arm/configs/imx_v6_v7_defconfig +1 −1
  33. arch/arm/configs/milbeaut_m10v_defconfig +1 −1
  34. arch/arm/configs/oxnas_v6_defconfig +1 −1
  35. arch/arm/configs/pxa_defconfig +1 −1
  36. arch/arm/configs/sama7_defconfig +1 −1
  37. arch/arm/configs/sp7021_defconfig +1 −1
  38. arch/arm64/Kconfig +1 −1
  39. arch/arm64/include/asm/pgtable.h +2 −13
  40. arch/arm64/kernel/elfcore.c +10 −6
  41. arch/arm64/kernel/vdso.c +2 −1
  42. arch/arm64/mm/hugetlbpage.c +1 −1
  43. arch/csky/Kconfig +1 −1
  44. arch/ia64/Kconfig +1 −1
  45. arch/ia64/include/asm/sparsemem.h +3 −3
  46. arch/loongarch/Kconfig +1 −1
  47. arch/m68k/Kconfig.cpu +1 −1
  48. arch/mips/Kconfig +1 −1
  49. arch/mips/configs/db1xxx_defconfig +0 −1
  50. arch/mips/configs/generic_defconfig +0 −1
  51. arch/mips/include/uapi/asm/mman.h +2 −0
  52. arch/nios2/Kconfig +1 −1
  53. arch/parisc/include/uapi/asm/mman.h +2 −0
  54. arch/parisc/kernel/cache.c +7 −2
  55. arch/powerpc/Kconfig +1 −1
  56. arch/powerpc/configs/85xx/ge_imp3a_defconfig +1 −1
  57. arch/powerpc/configs/fsl-emb-nonhw.config +1 −1
  58. arch/powerpc/configs/powernv_defconfig +0 −1
  59. arch/powerpc/configs/pseries_defconfig +0 −1
  60. arch/powerpc/kernel/vdso.c +3 −3
  61. arch/powerpc/mm/book3s32/tlb.c +6 −5
  62. arch/powerpc/mm/book3s64/subpage_prot.c +2 −11
  63. arch/riscv/kernel/vdso.c +2 −1
  64. arch/s390/kernel/vdso.c +2 −1
  65. arch/s390/lib/uaccess.c +2 −1
  66. arch/s390/mm/gmap.c +4 −2
  67. arch/s390/mm/hugetlbpage.c +0 −10
  68. arch/sh/configs/ecovec24_defconfig +1 −1
  69. arch/sh/configs/sdk7786_defconfig +0 −1
  70. arch/sh/configs/urquell_defconfig +0 −1
  71. arch/sh/mm/Kconfig +1 −1
  72. arch/sparc/Kconfig +1 −1
  73. arch/um/kernel/tlb.c +6 −8
  74. arch/x86/Kconfig +9 −1
  75. arch/x86/boot/Makefile +1 −0
  76. arch/x86/boot/compressed/Makefile +1 −0
  77. arch/x86/entry/vdso/Makefile +3 −0
  78. arch/x86/entry/vdso/vma.c +5 −4
  79. arch/x86/include/asm/checksum.h +10 −6
  80. arch/x86/include/asm/kmsan.h +87 −0
  81. arch/x86/include/asm/page_64.h +7 −0
  82. arch/x86/include/asm/pgtable-3level.h +4 −4
  83. arch/x86/include/asm/pgtable.h +5 −4
  84. arch/x86/include/asm/pgtable_64_types.h +46 −1
  85. arch/x86/include/asm/sparsemem.h +2 −0
  86. arch/x86/include/asm/string_64.h +21 −2
  87. arch/x86/include/asm/uaccess.h +15 −7
  88. arch/x86/kernel/Makefile +2 −0
  89. arch/x86/kernel/cpu/Makefile +1 −0
  90. arch/x86/kernel/dumpstack.c +6 −0
  91. arch/x86/kernel/process_64.c +1 −0
  92. arch/x86/kernel/tboot.c +1 −1
  93. arch/x86/kernel/unwind_frame.c +11 −0
  94. arch/x86/lib/Makefile +2 −0
  95. arch/x86/lib/iomem.c +5 −0
  96. arch/x86/mm/Makefile +5 −0
  97. arch/x86/mm/fault.c +22 −1
  98. arch/x86/mm/init.c +1 −1
  99. arch/x86/mm/init_64.c +1 −1
  100. arch/x86/mm/ioremap.c +3 −0
  101. arch/x86/mm/kmsan_shadow.c +20 −0
  102. arch/x86/mm/pgtable.c +4 −1
  103. arch/x86/realmode/rm/Makefile +1 −0
  104. arch/xtensa/Kconfig +1 −1
  105. arch/xtensa/include/uapi/asm/mman.h +2 −0
  106. arch/xtensa/kernel/syscall.c +12 −6
  107. block/bio.c +2 −0
  108. block/blk.h +7 −0
  109. crypto/Kconfig +2 −0
  110. drivers/base/memory.c +0 −6
  111. drivers/base/node.c +6 −135
  112. drivers/block/zram/zram_drv.c +24 −14
  113. drivers/block/zram/zram_drv.h +7 −8
  114. drivers/dax/kmem.c +39 −3
  115. drivers/firmware/efi/efi.c +1 −1
  116. drivers/firmware/efi/libstub/Makefile +1 −0
  117. drivers/gpu/drm/i915/gem/i915_gem_userptr.c +5 −9
  118. drivers/input/serio/libps2.c +4 −1
  119. drivers/misc/cxl/fault.c +15 −30
  120. drivers/net/Kconfig +1 −0
  121. drivers/nvdimm/nd.h +1 −1
  122. drivers/nvdimm/pfn_devs.c +1 −1
  123. drivers/tee/optee/call.c +10 −8
  124. drivers/usb/core/urb.c +2 −0
  125. drivers/virtio/virtio_ring.c +9 −1
  126. drivers/xen/privcmd.c +1 −1
  127. fs/Kconfig +1 −0
  128. fs/btrfs/compression.c +15 −16
  129. fs/btrfs/extent_io.c +15 −18
  130. fs/btrfs/subpage.c +1 −1
  131. fs/btrfs/tests/extent-io-tests.c +17 −15
  132. fs/buffer.c +65 −93
  133. fs/coredump.c +12 −22
  134. fs/exec.c +8 −6
  135. fs/ext2/balloc.c +4 −3
  136. fs/fuse/dev.c +2 −1
  137. fs/gfs2/meta_io.c +2 −5
  138. fs/gfs2/quota.c +2 −6
  139. fs/hugetlbfs/inode.c +214 −86
  140. fs/isofs/compress.c +1 −1
  141. fs/jbd2/journal.c +6 −9
  142. fs/jbd2/recovery.c +10 −6
  143. fs/namei.c +1 −1
  144. fs/nilfs2/page.c +18 −27
  145. fs/ntfs3/inode.c +2 −5
  146. fs/ocfs2/aops.c +1 −1
  147. fs/ocfs2/super.c +1 −3
  148. fs/posix_acl.c +3 −0
  149. fs/proc/base.c +19 −1
  150. fs/proc/internal.h +1 −1
  151. fs/proc/task_mmu.c +59 −37
  152. fs/proc/task_nommu.c +21 −24
  153. fs/ramfs/file-nommu.c +29 −21
  154. fs/reiserfs/journal.c +6 −5
  155. fs/reiserfs/stree.c +2 −2
  156. fs/reiserfs/super.c +1 −3
  157. fs/udf/dir.c +1 −1
  158. fs/udf/directory.c +1 −1
  159. fs/udf/inode.c +1 −7
  160. fs/ufs/balloc.c +4 −8
  161. fs/userfaultfd.c +97 −36
  162. include/asm-generic/cacheflush.h +12 −2
  163. include/linux/buffer_head.h +38 −10
  164. include/linux/cache.h +13 −0
  165. include/linux/cgroup.h +14 −1
  166. include/linux/compiler-clang.h +23 −0
  167. include/linux/compiler-gcc.h +6 −0
  168. include/linux/compiler_types.h +2 −1
  169. include/linux/damon.h +54 −32
  170. include/linux/delayacct.h +8 −8
  171. include/linux/fortify-string.h +2 −0
  172. include/linux/gfp.h +3 −23
  173. include/linux/highmem.h +3 −0
  174. include/linux/huge_mm.h +21 −7
  175. include/linux/hugetlb.h +56 −7
  176. include/linux/hugetlb_cgroup.h +8 −11
  177. include/linux/instrumented.h +56 −3
  178. include/linux/kasan.h +22 −33
  179. include/linux/khugepaged.h +8 −5
  180. include/linux/kmsan-checks.h +83 −0
  181. include/linux/kmsan.h +330 −0
  182. include/linux/kmsan_types.h +35 −0
  183. include/linux/ksm.h +0 −3
  184. include/linux/maple_tree.h +685 −0
  185. include/linux/memcontrol.h +49 −50
  186. include/linux/memory-tiers.h +102 −0
  187. include/linux/memory_hotplug.h +20 −10
  188. include/linux/mempolicy.h +1 −12
  189. include/linux/migrate.h +0 −15
  190. include/linux/mm.h +121 −40
  191. include/linux/mm_inline.h +230 −12
  192. include/linux/mm_types.h +152 −26
  193. include/linux/mm_types_task.h +0 −12
  194. include/linux/mmzone.h +246 −35
  195. include/linux/node.h +4 −25
  196. include/linux/nodemask.h +12 −2
  197. include/linux/oom.h +0 −11
  198. include/linux/page-flags-layout.h +11 −5
  199. include/linux/page-flags.h +2 −2
  200. include/linux/page_counter.h +14 −12
  201. include/linux/page_ext.h +20 −4
  202. include/linux/page_idle.h +24 −10
  203. include/linux/pageblock-flags.h +4 −0
  204. include/linux/pagemap.h +5 −9
  205. include/linux/pagewalk.h +5 −5
  206. include/linux/pgtable.h +17 −9
  207. include/linux/rmap.h +62 −11
  208. include/linux/sched.h +13 −1
  209. include/linux/sched/coredump.h +3 −4
  210. include/linux/sched/sysctl.h +1 −0
  211. include/linux/shmem_fs.h +9 −7
  212. include/linux/slab.h +7 −1
  213. include/linux/stackdepot.h +8 −0
  214. include/linux/swap.h +25 −16
  215. include/linux/swap_cgroup.h +2 −2
  216. include/linux/swapfile.h +6 −1
  217. include/linux/swapops.h +131 −19
  218. include/linux/uaccess.h +14 −5
  219. include/linux/userfaultfd_k.h +3 −4
  220. include/linux/vm_event_item.h +0 −4
  221. include/linux/vmacache.h +0 −28
  222. include/linux/vmstat.h +0 −6
  223. include/linux/writeback.h +0 −8
  224. include/trace/events/huge_memory.h +37 −0
  225. include/trace/events/maple_tree.h +123 −0
  226. include/trace/events/mmap.h +73 −0
  227. include/uapi/asm-generic/hugetlb_encode.h +13 −13
  228. include/uapi/asm-generic/mman-common.h +2 −0
  229. include/uapi/linux/userfaultfd.h +4 −0
  230. init/Kconfig +0 −5
  231. init/main.c +10 −1
  232. ipc/shm.c +10 −11
  233. kernel/Makefile +1 −0
  234. kernel/acct.c +5 −6
  235. kernel/bounds.c +7 −0
  236. kernel/bpf/core.c +1 −1
  237. kernel/bpf/task_iter.c +5 −5
  238. kernel/cgroup/cgroup-internal.h +0 −1
  239. kernel/debug/debug_core.c +0 −12
  240. kernel/delayacct.c +11 −2
  241. kernel/dma/mapping.c +7 −3
  242. kernel/entry/common.c +5 −0
  243. kernel/events/core.c +2 −1
  244. kernel/events/uprobes.c +22 −17
  245. kernel/exit.c +3 −0
  246. kernel/fork.c +43 −36
  247. kernel/kcov.c +7 −0
  248. kernel/locking/Makefile +2 −1
  249. kernel/sched/core.c +15 −0
  250. kernel/sched/debug.c +1 −0
  251. kernel/sched/fair.c +172 −3
  252. kernel/sched/sched.h +1 −0
  253. kernel/sysctl.c +8 −0
  254. lib/Kconfig.debug +13 −5
  255. lib/Kconfig.kasan +0 −8
  256. lib/Kconfig.kmsan +62 −0
  257. lib/Makefile +4 −6
  258. lib/iomap.c +44 −0
  259. lib/iov_iter.c +6 −3
  260. lib/maple_tree.c +7130 −0
  261. lib/show_mem.c +2 −2
  262. lib/stackdepot.c +24 −5
  263. lib/string.c +8 −0
  264. lib/test_hmm.c +10 −3
  265. lib/test_maple_tree.c +38307 −0
  266. lib/usercopy.c +2 −1
  267. mm/Kconfig +27 −7
  268. mm/Makefile +6 −2
  269. mm/backing-dev.c +1 −5
  270. mm/cma_debug.c +1 −4
  271. mm/compaction.c +17 −7
  272. mm/damon/Kconfig +3 −0
  273. mm/damon/core-test.h +26 −3
  274. mm/damon/core.c +184 −97
  275. mm/damon/dbgfs.c +30 −22
  276. mm/damon/lru_sort.c +87 −293
  277. mm/damon/modules-common.h +46 −0
  278. mm/damon/ops-common.c +8 −42
  279. mm/damon/ops-common.h +1 −1
  280. mm/damon/paddr.c +21 −22
  281. mm/damon/reclaim.c +57 −232
  282. mm/damon/sysfs.c +63 −80
  283. mm/damon/vaddr-test.h +12 −24
  284. mm/damon/vaddr.c +58 −44
  285. mm/debug.c +6 −8
  286. mm/filemap.c +66 −58
  287. mm/folio-compat.c +6 −0
  288. mm/gup.c +141 −107
  289. mm/hmm.c +1 −1
  290. mm/huge_memory.c +117 −88
  291. mm/hugetlb.c +499 −293
  292. mm/hugetlb_cgroup.c +12 −15
  293. mm/hugetlb_vmemmap.c +7 −3
  294. mm/hwpoison-inject.c +2 −2
  295. mm/init-mm.c +2 −2
  296. mm/internal.h +11 −37
  297. mm/kasan/Makefile +8 −0
  298. mm/kasan/common.c +16 −161
  299. mm/kasan/generic.c +143 −11
  300. mm/kasan/hw_tags.c +1 −38
  301. mm/kasan/kasan.h +117 −54
  302. mm/kasan/kasan_test.c +25 −1
  303. mm/kasan/kasan_test_module.c +1 −1
  304. mm/kasan/report.c +69 −69
  305. mm/kasan/report_generic.c +45 −1
  306. mm/kasan/report_tags.c +94 −29
  307. mm/kasan/sw_tags.c +4 −1
  308. mm/kasan/tags.c +114 −29
  309. mm/kfence/core.c +9 −13
  310. mm/khugepaged.c +739 −429
  311. mm/kmemleak.c +9 −12
  312. mm/kmsan/Makefile +28 −0
  313. mm/kmsan/core.c +450 −0
  314. mm/kmsan/hooks.c +384 −0
  315. mm/kmsan/init.c +235 −0
  316. mm/kmsan/instrumentation.c +307 −0
  317. mm/kmsan/kmsan.h +209 −0
  318. mm/kmsan/kmsan_test.c +581 −0
  319. mm/kmsan/report.c +219 −0
  320. mm/kmsan/shadow.c +298 −0
  321. mm/ksm.c +190 −185
  322. mm/madvise.c +33 −27
  323. mm/memblock.c +3 −3
  324. mm/memcontrol.c +184 −97
  325. mm/memory-failure.c +57 −69
  326. mm/memory-tiers.c +732 −0
  327. mm/memory.c +160 −114
  328. mm/memory_hotplug.c +4 −7
  329. mm/mempolicy.c +38 −28
  330. mm/memremap.c +1 −1
  331. mm/migrate.c +116 −535
  332. mm/migrate_device.c +16 −3
  333. mm/mlock.c +19 −18
  334. mm/mm_init.c +4 −2
  335. mm/mm_slot.h +55 −0
  336. mm/mmap.c +1135 −1124
  337. mm/mmzone.c +2 −0
  338. mm/mprotect.c +13 −4
  339. mm/mremap.c +30 −11
  340. mm/msync.c +1 −1
  341. mm/nommu.c +141 −119
  342. mm/oom_kill.c +5 −6
  343. mm/page_alloc.c +105 −91
  344. mm/page_counter.c +7 −8
  345. mm/page_ext.c +108 −9
  346. mm/page_io.c +24 −19
  347. mm/page_isolation.c +8 −9
  348. mm/page_owner.c +76 −27
  349. mm/page_table_check.c +9 −5
  350. mm/page_vma_mapped.c +3 −3
  351. mm/pagewalk.c +10 −2
  352. mm/rmap.c +106 −78
  353. mm/rodata_test.c +3 −5
  354. mm/secretmem.c +3 −5
  355. mm/shmem.c +224 −205
  356. mm/shuffle.c +10 −11
  357. mm/slab.h +1 −0
  358. mm/slab_common.c +2 −0
  359. mm/slub.c +41 −0
  360. mm/swap.c +58 −15
  361. mm/swap.h +7 −11
  362. mm/swap_cgroup.c +6 −0
  363. mm/swap_slots.c +1 −1
  364. mm/swap_state.c +57 −54
  365. mm/swapfile.c +90 −88
  366. mm/truncate.c +1 −1
  367. mm/userfaultfd.c +15 −13
  368. mm/util.c +3 −33
  369. mm/vmacache.c +0 −117
  370. mm/vmalloc.c +26 −9
  371. mm/vmscan.c +3184 −372
  372. mm/vmstat.c +1 −8
  373. mm/workingset.c +108 −2
  374. mm/zsmalloc.c +11 −11
  375. mm/zswap.c +1 −1
  376. scripts/Makefile.kmsan +8 −0
  377. scripts/Makefile.lib +9 −0
  378. security/Kconfig.hardening +4 −0
  379. tools/include/asm-generic/hugetlb_encode.h +13 −13
  380. tools/include/linux/slab.h +4 −0
  381. tools/include/uapi/asm-generic/mman-common.h +2 −0
  382. tools/objtool/check.c +20 −0
  383. tools/testing/memblock/linux/mmzone.h +2 −0
  384. tools/testing/radix-tree/.gitignore +2 −0
  385. tools/testing/radix-tree/Makefile +7 −2
  386. tools/testing/radix-tree/generated/autoconf.h +1 −0
  387. tools/testing/radix-tree/linux.c +156 −4
  388. tools/testing/radix-tree/linux/kernel.h +1 −0
  389. tools/testing/radix-tree/linux/lockdep.h +2 −0
  390. tools/testing/radix-tree/linux/maple_tree.h +7 −0
  391. tools/testing/radix-tree/maple.c +59 −0
  392. tools/testing/radix-tree/trace/events/maple_tree.h +5 −0
  393. tools/testing/selftests/cgroup/config +0 −1
  394. tools/testing/selftests/damon/Makefile +1 −0
  395. tools/testing/selftests/damon/debugfs_duplicate_context_creation.sh +27 −0
  396. tools/testing/selftests/vm/.gitignore +0 −1
  397. tools/testing/selftests/vm/Makefile +3 −20
  398. tools/testing/selftests/vm/check_config.sh +0 −31
  399. tools/testing/selftests/vm/hmm-tests.c +73 −35
  400. tools/testing/selftests/vm/khugepaged.c +861 −334
  401. tools/testing/selftests/vm/mremap_test.c +48 −1
  402. tools/testing/selftests/vm/run_vmtests.sh +10 −5
  403. tools/testing/selftests/vm/soft-dirty.c +1 −1
  404. tools/testing/selftests/vm/split_huge_page_test.c +4 −8
  405. tools/testing/selftests/vm/test_hmm.sh +0 −10
  406. tools/testing/selftests/vm/userfaultfd.c +199 −48
  407. tools/testing/selftests/vm/vm_util.c +27 −9
  408. tools/testing/selftests/vm/vm_util.h +4 −1
  409. tools/vm/page_owner_sort.c +6 −1
Documentation/ABI/testing/sysfs-kernel-mm-memory-tiers+25−0
@@ -0,0 +1,25 @@
1What: /sys/devices/virtual/memory_tiering/
2Date: August 2022
3Contact: Linux memory management mailing list <linux-mm@kvack.org>
4Description: A collection of all the memory tiers allocated.
5
6 Individual memory tier details are contained in subdirectories
7 named by the abstract distance of the memory tier.
8
9 /sys/devices/virtual/memory_tiering/memory_tierN/
10
11
12What: /sys/devices/virtual/memory_tiering/memory_tierN/
13 /sys/devices/virtual/memory_tiering/memory_tierN/nodes
14Date: August 2022
15Contact: Linux memory management mailing list <linux-mm@kvack.org>
16Description: Directory with details of a specific memory tier
17
18 This is the directory containing information about a particular
19 memory tier, memtierN, where N is derived based on abstract distance.
20
21 A smaller value of N implies a higher (faster) memory tier in the
22 hierarchy.
23
24 nodes: NUMA nodes that are part of this memory tier.
25
Documentation/accounting/delay-accounting.rst+1−1
@@ -13,7 +13,7 @@ a) waiting for a CPU (while being runnable) · 12 unmodified lines
13b) completion of synchronous block I/O initiated by the task13b) completion of synchronous block I/O initiated by the task
14c) swapping in pages14c) swapping in pages
15d) memory reclaim15d) memory reclaim
16e) thrashing page cache16e) thrashing
17f) direct compact17f) direct compact
18g) write-protect copy18g) write-protect copy
19 19
Documentation/admin-guide/cgroup-v1/memory.rst+1−3
@@ -299,7 +299,7 @@ Per-node-per-memcgroup LRU (cgroup's private LRU) is guarded by · 298 unmodified lines
299lruvec->lru_lock; PG_lru bit of page->flags is cleared before299lruvec->lru_lock; PG_lru bit of page->flags is cleared before
300isolating a page from its LRU under lruvec->lru_lock.300isolating a page from its LRU under lruvec->lru_lock.
301 301
3022.7 Kernel Memory Extension (CONFIG_MEMCG_KMEM)3022.7 Kernel Memory Extension
303-----------------------------------------------303-----------------------------------------------
304 304
305With the Kernel memory extension, the Memory Controller is able to limit305With the Kernel memory extension, the Memory Controller is able to limit
@@ -386,8 +386,6 @@ U != 0, K >= U: · 80 unmodified lines
386 386
387a. Enable CONFIG_CGROUPS387a. Enable CONFIG_CGROUPS
388b. Enable CONFIG_MEMCG388b. Enable CONFIG_MEMCG
389c. Enable CONFIG_MEMCG_SWAP (to use swap extension)
390d. Enable CONFIG_MEMCG_KMEM (to use kmem extension)
391 389
3923.1. Prepare the cgroups (see cgroups.txt, Why are cgroups needed?)3903.1. Prepare the cgroups (see cgroups.txt, Why are cgroups needed?)
393-------------------------------------------------------------------391-------------------------------------------------------------------
Documentation/admin-guide/kernel-parameters.txt+8−6
@@ -1469,6 +1469,14 @@ · 1468 unmodified lines
1469 Permit 'security.evm' to be updated regardless of1469 Permit 'security.evm' to be updated regardless of
1470 current integrity status.1470 current integrity status.
1471 1471
1472 early_page_ext [KNL] Enforces page_ext initialization to earlier
1473 stages so cover more early boot allocations.
1474 Please note that as side effect some optimizations
1475 might be disabled to achieve that (e.g. parallelized
1476 memory initialization is disabled) so the boot process
1477 might take longer, especially on systems with a lot of
1478 memory. Available with CONFIG_PAGE_EXTENSION=y.
1479
1472 failslab=1480 failslab=
1473 fail_usercopy=1481 fail_usercopy=
1474 fail_page_alloc=1482 fail_page_alloc=
@@ -6041,12 +6049,6 @@ · 4566 unmodified lines
6041 This parameter controls use of the Protected6049 This parameter controls use of the Protected
6042 Execution Facility on pSeries.6050 Execution Facility on pSeries.
6043 6051
6044 swapaccount= [KNL]
6045 Format: [0|1]
6046 Enable accounting of swap in memory resource
6047 controller if no parameter or 1 is given or disable
6048 it if 0 is given (See Documentation/admin-guide/cgroup-v1/memory.rst)
6049
6050 swiotlb= [ARM,IA-64,PPC,MIPS,X86]6052 swiotlb= [ARM,IA-64,PPC,MIPS,X86]
6051 Format: { <int> [,<int>] | force | noforce }6053 Format: { <int> [,<int>] | force | noforce }
6052 <int> -- Number of I/O TLB slabs6054 <int> -- Number of I/O TLB slabs
Documentation/admin-guide/mm/cma_debugfs.rst+5−5
@@ -5,10 +5,10 @@ CMA Debugfs Interface · 4 unmodified lines
5The CMA debugfs interface is useful to retrieve basic information out of the5The CMA debugfs interface is useful to retrieve basic information out of the
6different CMA areas and to test allocation/release in each of the areas.6different CMA areas and to test allocation/release in each of the areas.
7 7
8Each CMA zone represents a directory under <debugfs>/cma/, indexed by the8Each CMA area represents a directory under <debugfs>/cma/, represented by
9kernel's CMA index. So the first CMA zone would be:9its CMA name like below:
10 10
11 <debugfs>/cma/cma-011 <debugfs>/cma/<cma_name>
12 12
13The structure of the files created under that directory is as follows:13The structure of the files created under that directory is as follows:
14 14
@@ -18,8 +18,8 @@ The structure of the files created under that directory is as follows: · 3 unmodified lines
18 - [RO] bitmap: The bitmap of page states in the zone.18 - [RO] bitmap: The bitmap of page states in the zone.
19 - [WO] alloc: Allocate N pages from that CMA area. For example::19 - [WO] alloc: Allocate N pages from that CMA area. For example::
20 20
21 echo 5 > <debugfs>/cma/cma-2/alloc21 echo 5 > <debugfs>/cma/<cma_name>/alloc
22 22
23would try to allocate 5 pages from the cma-2 area.23would try to allocate 5 pages from the 'cma_name' area.
24 24
25 - [WO] free: Free N pages from that CMA area, similar to the above.25 - [WO] free: Free N pages from that CMA area, similar to the above.
Documentation/admin-guide/mm/damon/index.rst+3−3
@@ -1,8 +1,8 @@
1.. SPDX-License-Identifier: GPL-2.01.. SPDX-License-Identifier: GPL-2.0
2 2
3========================3==========================
4Monitoring Data Accesses4DAMON: Data Access MONitor
5========================5==========================
6 6
7:doc:`DAMON </mm/damon/index>` allows light-weight data access monitoring.7:doc:`DAMON </mm/damon/index>` allows light-weight data access monitoring.
8Using DAMON, users can analyze the memory access patterns of their systems and8Using DAMON, users can analyze the memory access patterns of their systems and
Documentation/admin-guide/mm/damon/start.rst+3−10
@@ -29,16 +29,9 @@ called DAMON Operator (DAMO). It is available at · 28 unmodified lines
29https://github.com/awslabs/damo. The examples below assume that ``damo`` is on29https://github.com/awslabs/damo. The examples below assume that ``damo`` is on
30your ``$PATH``. It's not mandatory, though.30your ``$PATH``. It's not mandatory, though.
31 31
32Because DAMO is using the debugfs interface (refer to :doc:`usage` for the32Because DAMO is using the sysfs interface (refer to :doc:`usage` for the
33detail) of DAMON, you should ensure debugfs is mounted. Mount it manually as33detail) of DAMON, you should ensure :doc:`sysfs </filesystems/sysfs>` is
34below::34mounted.
35
36 # mount -t debugfs none /sys/kernel/debug/
37
38or append the following line to your ``/etc/fstab`` file so that your system
39can automatically mount debugfs upon booting::
40
41 debugfs /sys/kernel/debug debugfs defaults 0 0
42 35
43 36
44Recording Data Access Patterns37Recording Data Access Patterns
Documentation/admin-guide/mm/damon/usage.rst+5−0
@@ -393,6 +393,11 @@ the files as above. Above is only for an example. · 392 unmodified lines
393debugfs Interface393debugfs Interface
394=================394=================
395 395
396.. note::
397
398 DAMON debugfs interface will be removed after next LTS kernel is released, so
399 users should move to the :ref:`sysfs interface <sysfs_interface>`.
400
396DAMON exports eight files, ``attrs``, ``target_ids``, ``init_regions``,401DAMON exports eight files, ``attrs``, ``target_ids``, ``init_regions``,
397``schemes``, ``monitor_on``, ``kdamond_pid``, ``mk_contexts`` and402``schemes``, ``monitor_on``, ``kdamond_pid``, ``mk_contexts`` and
398``rm_contexts`` under its debugfs directory, ``<debugfs>/damon/``.403``rm_contexts`` under its debugfs directory, ``<debugfs>/damon/``.
Documentation/admin-guide/mm/index.rst+1−0
@@ -32,6 +32,7 @@ the Linux memory management. · 31 unmodified lines
32 idle_page_tracking32 idle_page_tracking
33 ksm33 ksm
34 memory-hotplug34 memory-hotplug
35 multigen_lru
35 nommu-mmap36 nommu-mmap
36 numa_memory_policy37 numa_memory_policy
37 numaperf38 numaperf
Documentation/admin-guide/mm/ksm.rst+36−0
@@ -184,6 +184,42 @@ The maximum possible ``pages_sharing/pages_shared`` ratio is limited by the · 183 unmodified lines
184``max_page_sharing`` tunable. To increase the ratio ``max_page_sharing`` must184``max_page_sharing`` tunable. To increase the ratio ``max_page_sharing`` must
185be increased accordingly.185be increased accordingly.
186 186
187Monitoring KSM profit
188=====================
189
190KSM can save memory by merging identical pages, but also can consume
191additional memory, because it needs to generate a number of rmap_items to
192save each scanned page's brief rmap information. Some of these pages may
193be merged, but some may not be abled to be merged after being checked
194several times, which are unprofitable memory consumed.
195
1961) How to determine whether KSM save memory or consume memory in system-wide
197 range? Here is a simple approximate calculation for reference::
198
199 general_profit =~ pages_sharing * sizeof(page) - (all_rmap_items) *
200 sizeof(rmap_item);
201
202 where all_rmap_items can be easily obtained by summing ``pages_sharing``,
203 ``pages_shared``, ``pages_unshared`` and ``pages_volatile``.
204
2052) The KSM profit inner a single process can be similarly obtained by the
206 following approximate calculation::
207
208 process_profit =~ ksm_merging_pages * sizeof(page) -
209 ksm_rmap_items * sizeof(rmap_item).
210
211 where ksm_merging_pages is shown under the directory ``/proc/<pid>/``,
212 and ksm_rmap_items is shown in ``/proc/<pid>/ksm_stat``.
213
214From the perspective of application, a high ratio of ``ksm_rmap_items`` to
215``ksm_merging_pages`` means a bad madvise-applied policy, so developers or
216administrators have to rethink how to change madvise policy. Giving an example
217for reference, a page's size is usually 4K, and the rmap_item's size is
218separately 32B on 32-bit CPU architecture and 64B on 64-bit CPU architecture.
219so if the ``ksm_rmap_items/ksm_merging_pages`` ratio exceeds 64 on 64-bit CPU
220or exceeds 128 on 32-bit CPU, then the app's madvise policy should be dropped,
221because the ksm profit is approximately zero or negative.
222
187Monitoring KSM events223Monitoring KSM events
188=====================224=====================
189 225
Documentation/admin-guide/mm/multigen_lru.rst+162−0
@@ -0,0 +1,162 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3=============
4Multi-Gen LRU
5=============
6The multi-gen LRU is an alternative LRU implementation that optimizes
7page reclaim and improves performance under memory pressure. Page
8reclaim decides the kernel's caching policy and ability to overcommit
9memory. It directly impacts the kswapd CPU usage and RAM efficiency.
10
11Quick start
12===========
13Build the kernel with the following configurations.
14
15* ``CONFIG_LRU_GEN=y``
16* ``CONFIG_LRU_GEN_ENABLED=y``
17
18All set!
19
20Runtime options
21===============
22``/sys/kernel/mm/lru_gen/`` contains stable ABIs described in the
23following subsections.
24
25Kill switch
26-----------
27``enabled`` accepts different values to enable or disable the
28following components. Its default value depends on
29``CONFIG_LRU_GEN_ENABLED``. All the components should be enabled
30unless some of them have unforeseen side effects. Writing to
31``enabled`` has no effect when a component is not supported by the
32hardware, and valid values will be accepted even when the main switch
33is off.
34
35====== ===============================================================
36Values Components
37====== ===============================================================
380x0001 The main switch for the multi-gen LRU.
390x0002 Clearing the accessed bit in leaf page table entries in large
40 batches, when MMU sets it (e.g., on x86). This behavior can
41 theoretically worsen lock contention (mmap_lock). If it is
42 disabled, the multi-gen LRU will suffer a minor performance
43 degradation for workloads that contiguously map hot pages,
44 whose accessed bits can be otherwise cleared by fewer larger
45 batches.
460x0004 Clearing the accessed bit in non-leaf page table entries as
47 well, when MMU sets it (e.g., on x86). This behavior was not
48 verified on x86 varieties other than Intel and AMD. If it is
49 disabled, the multi-gen LRU will suffer a negligible
50 performance degradation.
51[yYnN] Apply to all the components above.
52====== ===============================================================
53
54E.g.,
55::
56
57 echo y >/sys/kernel/mm/lru_gen/enabled
58 cat /sys/kernel/mm/lru_gen/enabled
59 0x0007
60 echo 5 >/sys/kernel/mm/lru_gen/enabled
61 cat /sys/kernel/mm/lru_gen/enabled
62 0x0005
63
64Thrashing prevention
65--------------------
66Personal computers are more sensitive to thrashing because it can
67cause janks (lags when rendering UI) and negatively impact user
68experience. The multi-gen LRU offers thrashing prevention to the
69majority of laptop and desktop users who do not have ``oomd``.
70
71Users can write ``N`` to ``min_ttl_ms`` to prevent the working set of
72``N`` milliseconds from getting evicted. The OOM killer is triggered
73if this working set cannot be kept in memory. In other words, this
74option works as an adjustable pressure relief valve, and when open, it
75terminates applications that are hopefully not being used.
76
77Based on the average human detectable lag (~100ms), ``N=1000`` usually
78eliminates intolerable janks due to thrashing. Larger values like
79``N=3000`` make janks less noticeable at the risk of premature OOM
80kills.
81
82The default value ``0`` means disabled.
83
84Experimental features
85=====================
86``/sys/kernel/debug/lru_gen`` accepts commands described in the
87following subsections. Multiple command lines are supported, so does
88concatenation with delimiters ``,`` and ``;``.
89
90``/sys/kernel/debug/lru_gen_full`` provides additional stats for
91debugging. ``CONFIG_LRU_GEN_STATS=y`` keeps historical stats from
92evicted generations in this file.
93
94Working set estimation
95----------------------
96Working set estimation measures how much memory an application needs
97in a given time interval, and it is usually done with little impact on
98the performance of the application. E.g., data centers want to
99optimize job scheduling (bin packing) to improve memory utilizations.
100When a new job comes in, the job scheduler needs to find out whether
101each server it manages can allocate a certain amount of memory for
102this new job before it can pick a candidate. To do so, the job
103scheduler needs to estimate the working sets of the existing jobs.
104
105When it is read, ``lru_gen`` returns a histogram of numbers of pages
106accessed over different time intervals for each memcg and node.
107``MAX_NR_GENS`` decides the number of bins for each histogram. The
108histograms are noncumulative.
109::
110
111 memcg memcg_id memcg_path
112 node node_id
113 min_gen_nr age_in_ms nr_anon_pages nr_file_pages
114 ...
115 max_gen_nr age_in_ms nr_anon_pages nr_file_pages
116
117Each bin contains an estimated number of pages that have been accessed
118within ``age_in_ms``. E.g., ``min_gen_nr`` contains the coldest pages
119and ``max_gen_nr`` contains the hottest pages, since ``age_in_ms`` of
120the former is the largest and that of the latter is the smallest.
121
122Users can write the following command to ``lru_gen`` to create a new
123generation ``max_gen_nr+1``:
124
125 ``+ memcg_id node_id max_gen_nr [can_swap [force_scan]]``
126
127``can_swap`` defaults to the swap setting and, if it is set to ``1``,
128it forces the scan of anon pages when swap is off, and vice versa.
129``force_scan`` defaults to ``1`` and, if it is set to ``0``, it
130employs heuristics to reduce the overhead, which is likely to reduce
131the coverage as well.
132
133A typical use case is that a job scheduler runs this command at a
134certain time interval to create new generations, and it ranks the
135servers it manages based on the sizes of their cold pages defined by
136this time interval.
137
138Proactive reclaim
139-----------------
140Proactive reclaim induces page reclaim when there is no memory
141pressure. It usually targets cold pages only. E.g., when a new job
142comes in, the job scheduler wants to proactively reclaim cold pages on
143the server it selected, to improve the chance of successfully landing
144this new job.
145
146Users can write the following command to ``lru_gen`` to evict
147generations less than or equal to ``min_gen_nr``.
148
149 ``- memcg_id node_id min_gen_nr [swappiness [nr_to_reclaim]]``
150
151``min_gen_nr`` should be less than ``max_gen_nr-1``, since
152``max_gen_nr`` and ``max_gen_nr-1`` are not fully aged (equivalent to
153the active list) and therefore cannot be evicted. ``swappiness``
154overrides the default value in ``/proc/sys/vm/swappiness``.
155``nr_to_reclaim`` limits the number of pages to evict.
156
157A typical use case is that a job scheduler runs this command before it
158tries to land a new job on a server. If it fails to materialize enough
159cold pages because of the overestimation, it retries on the next
160server according to the ranking result obtained from the working set
161estimation step. This less forceful approach limits the impacts on the
162existing jobs.
Documentation/admin-guide/mm/transhuge.rst+11−5
@@ -191,7 +191,14 @@ allocation failure to throttle the next allocation attempt:: · 190 unmodified lines
191 191
192 /sys/kernel/mm/transparent_hugepage/khugepaged/alloc_sleep_millisecs192 /sys/kernel/mm/transparent_hugepage/khugepaged/alloc_sleep_millisecs
193 193
194The khugepaged progress can be seen in the number of pages collapsed::194The khugepaged progress can be seen in the number of pages collapsed (note
195that this counter may not be an exact count of the number of pages
196collapsed, since "collapsed" could mean multiple things: (1) A PTE mapping
197being replaced by a PMD mapping, or (2) All 4K physical pages replaced by
198one 2M hugepage. Each may happen independently, or together, depending on
199the type of memory and the failures that occur. As such, this value should
200be interpreted roughly as a sign of progress, and counters in /proc/vmstat
201consulted for more accurate accounting)::
195 202
196 /sys/kernel/mm/transparent_hugepage/khugepaged/pages_collapsed203 /sys/kernel/mm/transparent_hugepage/khugepaged/pages_collapsed
197 204
@@ -366,10 +373,9 @@ thp_split_pmd · 168 unmodified lines
366 page table entry.373 page table entry.
367 374
368thp_zero_page_alloc375thp_zero_page_alloc
369 is incremented every time a huge zero page is376 is incremented every time a huge zero page used for thp is
370 successfully allocated. It includes allocations which where377 successfully allocated. Note, it doesn't count every map of
371 dropped due race with other allocation. Note, it doesn't count378 the huge zero page, only its allocation.
372 every map of the huge zero page, only its allocation.
373 379
374thp_zero_page_alloc_failed380thp_zero_page_alloc_failed
375 is incremented if kernel fails to allocate381 is incremented if kernel fails to allocate
Documentation/admin-guide/mm/userfaultfd.rst+38−3
@@ -17,7 +17,10 @@ of the ``PROT_NONE+SIGSEGV`` trick. · 16 unmodified lines
17Design17Design
18======18======
19 19
20Userfaults are delivered and resolved through the ``userfaultfd`` syscall.20Userspace creates a new userfaultfd, initializes it, and registers one or more
21regions of virtual memory with it. Then, any page faults which occur within the
22region(s) result in a message being delivered to the userfaultfd, notifying
23userspace of the fault.
21 24
22The ``userfaultfd`` (aside from registering and unregistering virtual25The ``userfaultfd`` (aside from registering and unregistering virtual
23memory ranges) provides two primary functionalities:26memory ranges) provides two primary functionalities:
@@ -34,12 +37,11 @@ The real advantage of userfaults if compared to regular virtual memory · 10 unmodified lines
34management of mremap/mprotect is that the userfaults in all their37management of mremap/mprotect is that the userfaults in all their
35operations never involve heavyweight structures like vmas (in fact the38operations never involve heavyweight structures like vmas (in fact the
36``userfaultfd`` runtime load never takes the mmap_lock for writing).39``userfaultfd`` runtime load never takes the mmap_lock for writing).
37
38Vmas are not suitable for page- (or hugepage) granular fault tracking40Vmas are not suitable for page- (or hugepage) granular fault tracking
39when dealing with virtual address spaces that could span41when dealing with virtual address spaces that could span
40Terabytes. Too many vmas would be needed for that.42Terabytes. Too many vmas would be needed for that.
41 43
42The ``userfaultfd`` once opened by invoking the syscall, can also be44The ``userfaultfd``, once created, can also be
43passed using unix domain sockets to a manager process, so the same45passed using unix domain sockets to a manager process, so the same
44manager process could handle the userfaults of a multitude of46manager process could handle the userfaults of a multitude of
45different processes without them being aware about what is going on47different processes without them being aware about what is going on
@@ -50,6 +52,39 @@ is a corner case that would currently return ``-EBUSY``). · 4 unmodified lines
50API52API
51===53===
52 54
55Creating a userfaultfd
56----------------------
57
58There are two ways to create a new userfaultfd, each of which provide ways to
59restrict access to this functionality (since historically userfaultfds which
60handle kernel page faults have been a useful tool for exploiting the kernel).
61
62The first way, supported since userfaultfd was introduced, is the
63userfaultfd(2) syscall. Access to this is controlled in several ways:
64
65- Any user can always create a userfaultfd which traps userspace page faults
66 only. Such a userfaultfd can be created using the userfaultfd(2) syscall
67 with the flag UFFD_USER_MODE_ONLY.
68
69- In order to also trap kernel page faults for the address space, either the
70 process needs the CAP_SYS_PTRACE capability, or the system must have
71 vm.unprivileged_userfaultfd set to 1. By default, vm.unprivileged_userfaultfd
72 is set to 0.
73
74The second way, added to the kernel more recently, is by opening
75/dev/userfaultfd and issuing a USERFAULTFD_IOC_NEW ioctl to it. This method
76yields equivalent userfaultfds to the userfaultfd(2) syscall.
77
78Unlike userfaultfd(2), access to /dev/userfaultfd is controlled via normal
79filesystem permissions (user/group/mode), which gives fine grained access to
80userfaultfd specifically, without also granting other unrelated privileges at
81the same time (as e.g. granting CAP_SYS_PTRACE would do). Users who have access
82to /dev/userfaultfd can always create userfaultfds that trap kernel page faults;
83vm.unprivileged_userfaultfd is not considered.
84
85Initializing a userfaultfd
86--------------------------
87
53When first opened the ``userfaultfd`` must be enabled invoking the88When first opened the ``userfaultfd`` must be enabled invoking the
54``UFFDIO_API`` ioctl specifying a ``uffdio_api.api`` value set to ``UFFD_API`` (or89``UFFDIO_API`` ioctl specifying a ``uffdio_api.api`` value set to ``UFFD_API`` (or
55a later API version) which will specify the ``read/POLLIN`` protocol90a later API version) which will specify the ``read/POLLIN`` protocol
Documentation/admin-guide/sysctl/kernel.rst+11−0
@@ -635,6 +635,17 @@ different types of memory (represented as different NUMA nodes) to · 634 unmodified lines
635place the hot pages in the fast memory. This is implemented based on635place the hot pages in the fast memory. This is implemented based on
636unmapping and page fault too.636unmapping and page fault too.
637 637
638numa_balancing_promote_rate_limit_MBps
639======================================
640
641Too high promotion/demotion throughput between different memory types
642may hurt application latency. This can be used to rate limit the
643promotion throughput. The per-node max promotion throughput in MB/s
644will be limited to be no more than the set value.
645
646A rule of thumb is to set this to less than 1/10 of the PMEM node
647write bandwidth.
648
638oops_all_cpu_backtrace649oops_all_cpu_backtrace
639======================650======================
640 651
Documentation/admin-guide/sysctl/vm.rst+3−0
@@ -926,6 +926,9 @@ calls without any restrictions. · 925 unmodified lines
926 926
927The default value is 0.927The default value is 0.
928 928
929Another way to control permissions for userfaultfd is to use
930/dev/userfaultfd instead of userfaultfd(2). See
931Documentation/admin-guide/mm/userfaultfd.rst.
929 932
930user_reserve_kbytes933user_reserve_kbytes
931===================934===================
Documentation/core-api/index.rst+1−0
@@ -37,6 +37,7 @@ Library functionality that is used throughout the kernel. · 36 unmodified lines
37 kref37 kref
38 assoc_array38 assoc_array
39 xarray39 xarray
40 maple_tree
40 idr41 idr
41 circular-buffers42 circular-buffers
42 rbtree43 rbtree
Documentation/core-api/maple_tree.rst+217−0
@@ -0,0 +1,217 @@
1.. SPDX-License-Identifier: GPL-2.0+
2
3
4==========
5Maple Tree
6==========
7
8:Author: Liam R. Howlett
9
10Overview
11========
12
13The Maple Tree is a B-Tree data type which is optimized for storing
14non-overlapping ranges, including ranges of size 1. The tree was designed to
15be simple to use and does not require a user written search method. It
16supports iterating over a range of entries and going to the previous or next
17entry 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 must
19synchronize on a lock, which can be the default spinlock, or the user can set
20the lock to an external lock of a different type.
21
22The Maple Tree maintains a small memory footprint and was designed to use
23modern processor cache efficiently. The majority of the users will be able to
24use the normal API. An :ref:`maple-tree-advanced-api` exists for more complex
25scenarios. The most important usage of the Maple Tree is the tracking of the
26virtual memory areas.
27
28The Maple Tree can store values between ``0`` and ``ULONG_MAX``. The Maple
29Tree reserves values with the bottom two bits set to '10' which are below 4096
30(ie 2, 6, 10 .. 4094) for internal use. If the entries may use reserved
31entries then the users can convert the entries using xa_mk_value() and convert
32them back by calling xa_to_value(). If the user needs to use a reserved
33value, then the user can convert the value when using the
34:ref:`maple-tree-advanced-api`, but are blocked by the normal API.
35
36The Maple Tree can also be configured to support searching for a gap of a given
37size (or larger).
38
39Pre-allocating of nodes is also supported using the
40:ref:`maple-tree-advanced-api`. This is useful for users who must guarantee a
41successful store operation within a given
42code segment when allocating cannot be done. Allocations of nodes are
43relatively small at around 256 bytes.
44
45.. _maple-tree-normal-api:
46
47Normal API
48==========
49
50Start by initialising a maple tree, either with DEFINE_MTREE() for statically
51allocated maple trees or mt_init() for dynamically allocated ones. A
52freshly-initialised maple tree contains a ``NULL`` pointer for the range ``0``
53- ``ULONG_MAX``. There are currently two types of maple trees supported: the
54allocation tree and the regular tree. The regular tree has a higher branching
55factor for internal nodes. The allocation tree has a lower branching factor
56but allows the user to search for a gap of a given size or larger from either
57``0`` upwards or ``ULONG_MAX`` down. An allocation tree can be used by
58passing in the ``MT_FLAGS_ALLOC_RANGE`` flag when initialising the tree.
59
60You can then set entries using mtree_store() or mtree_store_range().
61mtree_store() will overwrite any entry with the new entry and return 0 on
62success or an error code otherwise. mtree_store_range() works in the same way
63but 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 only
65knowing 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.
67
68If 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() which
70return -EEXIST if the range is not empty.
71
72You can search for an entry from an index upwards by using mt_find().
73
74You can walk each entry within a range by calling mt_for_each(). You must
75provide a temporary variable to store a cursor. If you want to walk each
76element of the tree then ``0`` and ``ULONG_MAX`` may be used as the range. If
77the caller is going to hold the lock for the duration of the walk then it is
78worth looking at the mas_for_each() API in the :ref:`maple-tree-advanced-api`
79section.
80
81Sometimes it is necessary to ensure the next call to store to a maple tree does
82not allocate memory, please see :ref:`maple-tree-advanced-api` for this use case.
83
84Finally, you can remove all entries from a maple tree by calling
85mtree_destroy(). If the maple tree entries are pointers, you may wish to free
86the entries first.
87
88Allocating Nodes
89----------------
90
91The allocations are handled by the internal tree code. See
92:ref:`maple-tree-advanced-alloc` for other options.
93
94Locking
95-------
96
97You do not have to worry about locking. See :ref:`maple-tree-advanced-locks`
98for other options.
99
100The Maple Tree uses RCU and an internal spinlock to synchronise access:
101
102Takes RCU read lock:
103 * mtree_load()
104 * mt_find()
105 * mt_for_each()
106 * mt_next()
107 * mt_prev()
108
109Takes ma_lock internally:
110 * mtree_store()
111 * mtree_store_range()
112 * mtree_insert()
113 * mtree_insert_range()
114 * mtree_erase()
115 * mtree_destroy()
116 * mt_set_in_rcu()
117 * mt_clear_in_rcu()
118
119If you want to take advantage of the internal lock to protect the data
120structures that you are storing in the Maple Tree, you can call mtree_lock()
121before calling mtree_load(), then take a reference count on the object you
122have found before calling mtree_unlock(). This will prevent stores from
123removing the object from the tree between looking up the object and
124incrementing the refcount. You can also use RCU to avoid dereferencing
125freed memory, but an explanation of that is beyond the scope of this
126document.
127
128.. _maple-tree-advanced-api:
129
130Advanced API
131============
132
133The advanced API offers more flexibility and better performance at the
134cost of an interface which can be harder to use and has fewer safeguards.
135You must take care of your own locking while using the advanced API.
136You can use the ma_lock, RCU or an external lock for protection.
137You can mix advanced and normal operations on the same array, as long
138as the locking is compatible. The :ref:`maple-tree-normal-api` is implemented
139in terms of the advanced API.
140
141The advanced API is based around the ma_state, this is where the 'mas'
142prefix originates. The ma_state struct keeps track of tree operations to make
143life easier for both internal and external tree users.
144
145Initialising the maple tree is the same as in the :ref:`maple-tree-normal-api`.
146Please see above.
147
148The maple state keeps track of the range start and end in mas->index and
149mas->last, respectively.
150
151mas_walk() will walk the tree to the location of mas->index and set the
152mas->index and mas->last according to the range for the entry.
153
154You can set entries using mas_store(). mas_store() will overwrite any entry
155with the new entry and return the first existing entry that is overwritten.
156The range is passed in as members of the maple state: index and last.
157
158You can use mas_erase() to erase an entire range by setting index and
159last of the maple state to the desired range to erase. This will erase
160the first range that is found in that range, set the maple state index
161and last as the range that was erased and return the entry that existed
162at that location.
163
164You can walk each entry within a range by using mas_for_each(). If you want
165to walk each element of the tree then ``0`` and ``ULONG_MAX`` may be used as
166the range. If the lock needs to be periodically dropped, see the locking
167section mas_pause().
168
169Using a maple state allows mas_next() and mas_prev() to function as if the
170tree was a linked list. With such a high branching factor the amortized
171performance penalty is outweighed by cache optimization. mas_next() will
172return the next entry which occurs after the entry at index. mas_prev()
173will return the previous entry which occurs before the entry at index.
174
175mas_find() will find the first entry which exists at or above index on
176the first call, and the next entry from every subsequent calls.
177
178mas_find_rev() will find the fist entry which exists at or below the last on
179the first call, and the previous entry from every subsequent calls.
180
181If the user needs to yield the lock during an operation, then the maple state
182must be paused using mas_pause().
183
184There are a few extra interfaces provided when using an allocation tree.
185If you wish to search for a gap within a range, then mas_empty_area()
186or mas_empty_area_rev() can be used. mas_empty_area() searches for a gap
187starting at the lowest index given up to the maximum of the range.
188mas_empty_area_rev() searches for a gap starting at the highest index given
189and continues downward to the lower bound of the range.
190
191.. _maple-tree-advanced-alloc:
192
193Advanced Allocating Nodes
194-------------------------
195
196Allocations are usually handled internally to the tree, however if allocations
197need to occur before a write occurs then calling mas_expected_entries() will
198allocate the worst-case number of needed nodes to insert the provided number of
199ranges. This also causes the tree to enter mass insertion mode. Once
200insertions are complete calling mas_destroy() on the maple state will free the
201unused allocations.
202
203.. _maple-tree-advanced-locks:
204
205Advanced Locking
206----------------
207
208The maple tree uses a spinlock by default, but external locks can be used for
209tree updates as well. To use an external lock, the tree must be initialized
210with the ``MT_FLAGS_LOCK_EXTERN flag``, this is usually done with the
211MTREE_INIT_EXT() #define, which takes an external lock as an argument.
212
213Functions and structures
214========================
215
216.. kernel-doc:: include/linux/maple_tree.h
217.. kernel-doc:: lib/maple_tree.c
Documentation/core-api/mm-api.rst+0−3
@@ -19,9 +19,6 @@ User Space Memory Access · 18 unmodified lines
19Memory Allocation Controls19Memory Allocation Controls
20==========================20==========================
21 21
22.. kernel-doc:: include/linux/gfp.h
23 :internal:
24
25.. kernel-doc:: include/linux/gfp_types.h22.. kernel-doc:: include/linux/gfp_types.h
26 :doc: Page mobility and placement hints23 :doc: Page mobility and placement hints
27 24
Documentation/dev-tools/index.rst+1−0
@@ -24,6 +24,7 @@ Documentation/dev-tools/testing-overview.rst · 23 unmodified lines
24 kcov24 kcov
25 gcov25 gcov
26 kasan26 kasan
27 kmsan
27 ubsan28 ubsan
28 kmemleak29 kmemleak
29 kcsan30 kcsan
Documentation/dev-tools/kasan.rst+11−6
@@ -111,9 +111,17 @@ parameter can be used to control panic and reporting behaviour: · 110 unmodified lines
111 report or also panic the kernel (default: ``report``). The panic happens even111 report or also panic the kernel (default: ``report``). The panic happens even
112 if ``kasan_multi_shot`` is enabled.112 if ``kasan_multi_shot`` is enabled.
113 113
114Hardware Tag-Based KASAN mode (see the section about various modes below) is114Software and Hardware Tag-Based KASAN modes (see the section about various
115intended for use in production as a security mitigation. Therefore, it supports115modes below) support altering stack trace collection behavior:
116additional boot parameters that allow disabling KASAN or controlling features:116
117- ``kasan.stacktrace=off`` or ``=on`` disables or enables alloc and free stack
118 traces collection (default: ``on``).
119- ``kasan.stack_ring_size=<number of entries>`` specifies the number of entries
120 in the stack ring (default: ``32768``).
121
122Hardware Tag-Based KASAN mode is intended for use in production as a security
123mitigation. Therefore, it supports additional boot parameters that allow
124disabling KASAN altogether or controlling its features:
117 125
118- ``kasan=off`` or ``=on`` controls whether KASAN is enabled (default: ``on``).126- ``kasan=off`` or ``=on`` controls whether KASAN is enabled (default: ``on``).
119 127
@@ -132,9 +140,6 @@ additional boot parameters that allow disabling KASAN or controlling features: · 12 unmodified lines
132- ``kasan.vmalloc=off`` or ``=on`` disables or enables tagging of vmalloc140- ``kasan.vmalloc=off`` or ``=on`` disables or enables tagging of vmalloc
133 allocations (default: ``on``).141 allocations (default: ``on``).
134 142
135- ``kasan.stacktrace=off`` or ``=on`` disables or enables alloc and free stack
136 traces collection (default: ``on``).
137
138Error reports143Error reports
139~~~~~~~~~~~~~144~~~~~~~~~~~~~
140 145
Documentation/dev-tools/kmsan.rst+427−0
@@ -0,0 +1,427 @@
1.. SPDX-License-Identifier: GPL-2.0
2.. Copyright (C) 2022, Google LLC.
3
4===================================
5The Kernel Memory Sanitizer (KMSAN)
6===================================
7
8KMSAN is a dynamic error detector aimed at finding uses of uninitialized
9values. It is based on compiler instrumentation, and is quite similar to the
10userspace `MemorySanitizer tool`_.
11
12An important note is that KMSAN is not intended for production use, because it
13drastically increases kernel memory footprint and slows the whole system down.
14
15Usage
16=====
17
18Building the kernel
19-------------------
20
21In order to build a kernel with KMSAN you will need a fresh Clang (14.0.6+).
22Please refer to `LLVM documentation`_ for the instructions on how to build Clang.
23
24Now configure and build the kernel with CONFIG_KMSAN enabled.
25
26Example report
27--------------
28
29Here is an example of a KMSAN report::
30
31 =====================================================
32 BUG: KMSAN: uninit-value in test_uninit_kmsan_check_memory+0x1be/0x380 [kmsan_test]
33 test_uninit_kmsan_check_memory+0x1be/0x380 mm/kmsan/kmsan_test.c:273
34 kunit_run_case_internal lib/kunit/test.c:333
35 kunit_try_run_case+0x206/0x420 lib/kunit/test.c:374
36 kunit_generic_run_threadfn_adapter+0x6d/0xc0 lib/kunit/try-catch.c:28
37 kthread+0x721/0x850 kernel/kthread.c:327
38 ret_from_fork+0x1f/0x30 ??:?
39
40 Uninit was stored to memory at:
41 do_uninit_local_array+0xfa/0x110 mm/kmsan/kmsan_test.c:260
42 test_uninit_kmsan_check_memory+0x1a2/0x380 mm/kmsan/kmsan_test.c:271
43 kunit_run_case_internal lib/kunit/test.c:333
44 kunit_try_run_case+0x206/0x420 lib/kunit/test.c:374
45 kunit_generic_run_threadfn_adapter+0x6d/0xc0 lib/kunit/try-catch.c:28
46 kthread+0x721/0x850 kernel/kthread.c:327
47 ret_from_fork+0x1f/0x30 ??:?
48
49 Local variable uninit created at:
50 do_uninit_local_array+0x4a/0x110 mm/kmsan/kmsan_test.c:256
51 test_uninit_kmsan_check_memory+0x1a2/0x380 mm/kmsan/kmsan_test.c:271
52
53 Bytes 4-7 of 8 are uninitialized
54 Memory access of size 8 starts at ffff888083fe3da0
55
56 CPU: 0 PID: 6731 Comm: kunit_try_catch Tainted: G B E 5.16.0-rc3+ #104
57 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014
58 =====================================================
59
60The report says that the local variable ``uninit`` was created uninitialized in
61``do_uninit_local_array()``. The third stack trace corresponds to the place
62where this variable was created.
63
64The first stack trace shows where the uninit value was used (in
65``test_uninit_kmsan_check_memory()``). The tool shows the bytes which were left
66uninitialized in the local variable, as well as the stack where the value was
67copied to another memory location before use.
68
69A use of uninitialized value ``v`` is reported by KMSAN in the following cases:
70 - in a condition, e.g. ``if (v) { ... }``;
71 - in an indexing or pointer dereferencing, e.g. ``array[v]`` or ``*v``;
72 - when it is copied to userspace or hardware, e.g. ``copy_to_user(..., &v, ...)``;
73 - when it is passed as an argument to a function, and
74 ``CONFIG_KMSAN_CHECK_PARAM_RETVAL`` is enabled (see below).
75
76The mentioned cases (apart from copying data to userspace or hardware, which is
77a security issue) are considered undefined behavior from the C11 Standard point
78of view.
79
80Disabling the instrumentation
81-----------------------------
82
83A function can be marked with ``__no_kmsan_checks``. Doing so makes KMSAN
84ignore uninitialized values in that function and mark its output as initialized.
85As a result, the user will not get KMSAN reports related to that function.
86
87Another function attribute supported by KMSAN is ``__no_sanitize_memory``.
88Applying this attribute to a function will result in KMSAN not instrumenting
89it, which can be helpful if we do not want the compiler to interfere with some
90low-level code (e.g. that marked with ``noinstr`` which implicitly adds
91``__no_sanitize_memory``).
92
93This however comes at a cost: stack allocations from such functions will have
94incorrect shadow/origin values, likely leading to false positives. Functions
95called from non-instrumented code may also receive incorrect metadata for their
96parameters.
97
98As a rule of thumb, avoid using ``__no_sanitize_memory`` explicitly.
99
100It is also possible to disable KMSAN for a single file (e.g. main.o)::
101
102 KMSAN_SANITIZE_main.o := n
103
104or for the whole directory::
105
106 KMSAN_SANITIZE := n
107
108in the Makefile. Think of this as applying ``__no_sanitize_memory`` to every
109function in the file or directory. Most users won't need KMSAN_SANITIZE, unless
110their code gets broken by KMSAN (e.g. runs at early boot time).
111
112Support
113=======
114
115In order for KMSAN to work the kernel must be built with Clang, which so far is
116the only compiler that has KMSAN support. The kernel instrumentation pass is
117based on the userspace `MemorySanitizer tool`_.
118
119The runtime library only supports x86_64 at the moment.
120
121How KMSAN works
122===============
123
124KMSAN shadow memory
125-------------------
126
127KMSAN associates a metadata byte (also called shadow byte) with every byte of
128kernel memory. A bit in the shadow byte is set iff the corresponding bit of the
129kernel memory byte is uninitialized. Marking the memory uninitialized (i.e.
130setting its shadow bytes to ``0xff``) is called poisoning, marking it
131initialized (setting the shadow bytes to ``0x00``) is called unpoisoning.
132
133When a new variable is allocated on the stack, it is poisoned by default by
134instrumentation code inserted by the compiler (unless it is a stack variable
135that is immediately initialized). Any new heap allocation done without
136``__GFP_ZERO`` is also poisoned.
137
138Compiler instrumentation also tracks the shadow values as they are used along
139the code. When needed, instrumentation code invokes the runtime library in
140``mm/kmsan/`` to persist shadow values.
141
142The shadow value of a basic or compound type is an array of bytes of the same
143length. When a constant value is written into memory, that memory is unpoisoned.
144When a value is read from memory, its shadow memory is also obtained and
145propagated into all the operations which use that value. For every instruction
146that takes one or more values the compiler generates code that calculates the
147shadow of the result depending on those values and their shadows.
148
149Example::
150
151 int a = 0xff; // i.e. 0x000000ff
152 int b;
153 int c = a | b;
154
155In this case the shadow of ``a`` is ``0``, shadow of ``b`` is ``0xffffffff``,
156shadow of ``c`` is ``0xffffff00``. This means that the upper three bytes of
157``c`` are uninitialized, while the lower byte is initialized.
158
159Origin tracking
160---------------
161
162Every four bytes of kernel memory also have a so-called origin mapped to them.
163This origin describes the point in program execution at which the uninitialized
164value was created. Every origin is associated with either the full allocation
165stack (for heap-allocated memory), or the function containing the uninitialized
166variable (for locals).
167
168When an uninitialized variable is allocated on stack or heap, a new origin
169value is created, and that variable's origin is filled with that value. When a
170value is read from memory, its origin is also read and kept together with the
171shadow. For every instruction that takes one or more values, the origin of the
172result is one of the origins corresponding to any of the uninitialized inputs.
173If a poisoned value is written into memory, its origin is written to the
174corresponding storage as well.
175
176Example 1::
177
178 int a = 42;
179 int b;
180 int c = a + b;
181
182In this case the origin of ``b`` is generated upon function entry, and is
183stored to the origin of ``c`` right before the addition result is written into
184memory.
185
186Several variables may share the same origin address, if they are stored in the
187same four-byte chunk. In this case every write to either variable updates the
188origin for all of them. We have to sacrifice precision in this case, because
189storing origins for individual bits (and even bytes) would be too costly.
190
191Example 2::
192
193 int combine(short a, short b) {
194 union ret_t {
195 int i;
196 short s[2];
197 } ret;
198 ret.s[0] = a;
199 ret.s[1] = b;
200 return ret.i;
201 }
202
203If ``a`` is initialized and ``b`` is not, the shadow of the result would be
2040xffff0000, and the origin of the result would be the origin of ``b``.
205``ret.s[0]`` would have the same origin, but it will never be used, because
206that variable is initialized.
207
208If both function arguments are uninitialized, only the origin of the second
209argument is preserved.
210
211Origin chaining
212~~~~~~~~~~~~~~~
213
214To ease debugging, KMSAN creates a new origin for every store of an
215uninitialized value to memory. The new origin references both its creation stack
216and the previous origin the value had. This may cause increased memory
217consumption, so we limit the length of origin chains in the runtime.
218
219Clang instrumentation API
220-------------------------
221
222Clang instrumentation pass inserts calls to functions defined in
223``mm/kmsan/nstrumentation.c`` into the kernel code.
224
225Shadow manipulation
226~~~~~~~~~~~~~~~~~~~
227
228For every memory access the compiler emits a call to a function that returns a
229pair of pointers to the shadow and origin addresses of the given memory::
230
231 typedef struct {
232 void *shadow, *origin;
233 } shadow_origin_ptr_t
234
235 shadow_origin_ptr_t __msan_metadata_ptr_for_load_{1,2,4,8}(void *addr)
236 shadow_origin_ptr_t __msan_metadata_ptr_for_store_{1,2,4,8}(void *addr)
237 shadow_origin_ptr_t __msan_metadata_ptr_for_load_n(void *addr, uintptr_t size)
238 shadow_origin_ptr_t __msan_metadata_ptr_for_store_n(void *addr, uintptr_t size)
239
240The function name depends on the memory access size.
241
242The compiler makes sure that for every loaded value its shadow and origin
243values are read from memory. When a value is stored to memory, its shadow and
244origin are also stored using the metadata pointers.
245
246Handling locals
247~~~~~~~~~~~~~~~
248
249A special function is used to create a new origin value for a local variable and
250set the origin of that variable to that value::
251
252 void __msan_poison_alloca(void *addr, uintptr_t size, char *descr)
253
254Access to per-task data
255~~~~~~~~~~~~~~~~~~~~~~~
256
257At the beginning of every instrumented function KMSAN inserts a call to
258``__msan_get_context_state()``::
259
260 kmsan_context_state *__msan_get_context_state(void)
261
262``kmsan_context_state`` is declared in ``include/linux/kmsan.h``::
263
264 struct kmsan_context_state {
265 char param_tls[KMSAN_PARAM_SIZE];
266 char retval_tls[KMSAN_RETVAL_SIZE];
267 char va_arg_tls[KMSAN_PARAM_SIZE];
268 char va_arg_origin_tls[KMSAN_PARAM_SIZE];
269 u64 va_arg_overflow_size_tls;
270 char param_origin_tls[KMSAN_PARAM_SIZE];
271 depot_stack_handle_t retval_origin_tls;
272 };
273
274This structure is used by KMSAN to pass parameter shadows and origins between
275instrumented functions (unless the parameters are checked immediately by
276``CONFIG_KMSAN_CHECK_PARAM_RETVAL``).
277
278Passing uninitialized values to functions
279~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
280
281Clang's MemorySanitizer instrumentation has an option,
282``-fsanitize-memory-param-retval``, which makes the compiler check function
283parameters passed by value, as well as function return values.
284
285The option is controlled by ``CONFIG_KMSAN_CHECK_PARAM_RETVAL``, which is
286enabled by default to let KMSAN report uninitialized values earlier.
287Please refer to the `LKML discussion`_ for more details.
288
289Because of the way the checks are implemented in LLVM (they are only applied to
290parameters marked as ``noundef``), not all parameters are guaranteed to be
291checked, so we cannot give up the metadata storage in ``kmsan_context_state``.
292
293String functions
294~~~~~~~~~~~~~~~~
295
296The compiler replaces calls to ``memcpy()``/``memmove()``/``memset()`` with the
297following functions. These functions are also called when data structures are
298initialized or copied, making sure shadow and origin values are copied alongside
299with the data::
300
301 void *__msan_memcpy(void *dst, void *src, uintptr_t n)
302 void *__msan_memmove(void *dst, void *src, uintptr_t n)
303 void *__msan_memset(void *dst, int c, uintptr_t n)
304
305Error reporting
306~~~~~~~~~~~~~~~
307
308For each use of a value the compiler emits a shadow check that calls
309``__msan_warning()`` in the case that value is poisoned::
310
311 void __msan_warning(u32 origin)
312
313``__msan_warning()`` causes KMSAN runtime to print an error report.
314
315Inline assembly instrumentation
316~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
317
318KMSAN instruments every inline assembly output with a call to::
319
320 void __msan_instrument_asm_store(void *addr, uintptr_t size)
321
322, which unpoisons the memory region.
323
324This approach may mask certain errors, but it also helps to avoid a lot of
325false positives in bitwise operations, atomics etc.
326
327Sometimes the pointers passed into inline assembly do not point to valid memory.
328In such cases they are ignored at runtime.
329
330
331Runtime library
332---------------
333
334The code is located in ``mm/kmsan/``.
335
336Per-task KMSAN state
337~~~~~~~~~~~~~~~~~~~~
338
339Every task_struct has an associated KMSAN task state that holds the KMSAN
340context (see above) and a per-task flag disallowing KMSAN reports::
341
342 struct kmsan_context {
343 ...
344 bool allow_reporting;
345 struct kmsan_context_state cstate;
346 ...
347 }
348
349 struct task_struct {
350 ...
351 struct kmsan_context kmsan;
352 ...
353 }
354
355KMSAN contexts
356~~~~~~~~~~~~~~
357
358When running in a kernel task context, KMSAN uses ``current->kmsan.cstate`` to
359hold the metadata for function parameters and return values.
360
361But in the case the kernel is running in the interrupt, softirq or NMI context,
362where ``current`` is unavailable, KMSAN switches to per-cpu interrupt state::
363
364 DEFINE_PER_CPU(struct kmsan_ctx, kmsan_percpu_ctx);
365
366Metadata allocation
367~~~~~~~~~~~~~~~~~~~
368
369There are several places in the kernel for which the metadata is stored.
370
3711. Each ``struct page`` instance contains two pointers to its shadow and
372origin pages::
373
374 struct page {
375 ...
376 struct page *shadow, *origin;
377 ...
378 };
379
380At boot-time, the kernel allocates shadow and origin pages for every available
381kernel page. This is done quite late, when the kernel address space is already
382fragmented, so normal data pages may arbitrarily interleave with the metadata
383pages.
384
385This means that in general for two contiguous memory pages their shadow/origin
386pages may not be contiguous. Consequently, if a memory access crosses the
387boundary of a memory block, accesses to shadow/origin memory may potentially
388corrupt other pages or read incorrect values from them.
389
390In practice, contiguous memory pages returned by the same ``alloc_pages()``
391call will have contiguous metadata, whereas if these pages belong to two
392different allocations their metadata pages can be fragmented.
393
394For the kernel data (``.data``, ``.bss`` etc.) and percpu memory regions
395there also are no guarantees on metadata contiguity.
396
397In the case ``__msan_metadata_ptr_for_XXX_YYY()`` hits the border between two
398pages with non-contiguous metadata, it returns pointers to fake shadow/origin regions::
399
400 char dummy_load_page[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
401 char dummy_store_page[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
402
403``dummy_load_page`` is zero-initialized, so reads from it always yield zeroes.
404All stores to ``dummy_store_page`` are ignored.
405
4062. For vmalloc memory and modules, there is a direct mapping between the memory
407range, its shadow and origin. KMSAN reduces the vmalloc area by 3/4, making only
408the first quarter available to ``vmalloc()``. The second quarter of the vmalloc
409area contains shadow memory for the first quarter, the third one holds the
410origins. A small part of the fourth quarter contains shadow and origins for the
411kernel modules. Please refer to ``arch/x86/include/asm/pgtable_64_types.h`` for
412more details.
413
414When an array of pages is mapped into a contiguous virtual memory space, their
415shadow and origin pages are similarly mapped into contiguous regions.
416
417References
418==========
419
420E. Stepanov, K. Serebryany. `MemorySanitizer: fast detector of uninitialized
421memory use in C++
422<https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43308.pdf>`_.
423In Proceedings of CGO 2015.
424
425.. _MemorySanitizer tool: https://clang.llvm.org/docs/MemorySanitizer.html
426.. _LLVM documentation: https://llvm.org/docs/GettingStarted.html
427.. _LKML discussion: https://lore.kernel.org/all/20220614144853.3693273-1-glider@google.com/
Documentation/mm/index.rst+1−0
@@ -51,6 +51,7 @@ above structured documentation, or deleted if it has served its purpose. · 50 unmodified lines
51 ksm51 ksm
52 memory-model52 memory-model
53 mmu_notifier53 mmu_notifier
54 multigen_lru
54 numa55 numa
55 overcommit-accounting56 overcommit-accounting
56 page_migration57 page_migration
Documentation/mm/ksm.rst+1−1
@@ -26,7 +26,7 @@ tree. · 25 unmodified lines
26 26
27If a KSM page is shared between less than ``max_page_sharing`` VMAs,27If a KSM page is shared between less than ``max_page_sharing`` VMAs,
28the node of the stable tree that represents such KSM page points to a28the node of the stable tree that represents such KSM page points to a
29list of struct rmap_item and the ``page->mapping`` of the29list of struct ksm_rmap_item and the ``page->mapping`` of the
30KSM page points to the stable tree node.30KSM page points to the stable tree node.
31 31
32When the sharing passes this threshold, KSM adds a second dimension to32When the sharing passes this threshold, KSM adds a second dimension to
Documentation/mm/multigen_lru.rst+159−0
@@ -0,0 +1,159 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3=============
4Multi-Gen LRU
5=============
6The multi-gen LRU is an alternative LRU implementation that optimizes
7page reclaim and improves performance under memory pressure. Page
8reclaim decides the kernel's caching policy and ability to overcommit
9memory. It directly impacts the kswapd CPU usage and RAM efficiency.
10
11Design overview
12===============
13Objectives
14----------
15The design objectives are:
16
17* Good representation of access recency
18* Try to profit from spatial locality
19* Fast paths to make obvious choices
20* Simple self-correcting heuristics
21
22The representation of access recency is at the core of all LRU
23implementations. In the multi-gen LRU, each generation represents a
24group of pages with similar access recency. Generations establish a
25(time-based) common frame of reference and therefore help make better
26choices, e.g., between different memcgs on a computer or different
27computers in a data center (for job scheduling).
28
29Exploiting spatial locality improves efficiency when gathering the
30accessed bit. A rmap walk targets a single page and does not try to
31profit from discovering a young PTE. A page table walk can sweep all
32the young PTEs in an address space, but the address space can be too
33sparse to make a profit. The key is to optimize both methods and use
34them in combination.
35
36Fast paths reduce code complexity and runtime overhead. Unmapped pages
37do not require TLB flushes; clean pages do not require writeback.
38These facts are only helpful when other conditions, e.g., access
39recency, are similar. With generations as a common frame of reference,
40additional factors stand out. But obvious choices might not be good
41choices; thus self-correction is necessary.
42
43The benefits of simple self-correcting heuristics are self-evident.
44Again, with generations as a common frame of reference, this becomes
45attainable. Specifically, pages in the same generation can be
46categorized based on additional factors, and a feedback loop can
47statistically compare the refault percentages across those categories
48and infer which of them are better choices.
49
50Assumptions
51-----------
52The protection of hot pages and the selection of cold pages are based
53on page access channels and patterns. There are two access channels:
54
55* Accesses through page tables
56* Accesses through file descriptors
57
58The protection of the former channel is by design stronger because:
59
601. The uncertainty in determining the access patterns of the former
61 channel is higher due to the approximation of the accessed bit.
622. The cost of evicting the former channel is higher due to the TLB
63 flushes required and the likelihood of encountering the dirty bit.
643. The penalty of underprotecting the former channel is higher because
65 applications usually do not prepare themselves for major page
66 faults like they do for blocked I/O. E.g., GUI applications
67 commonly use dedicated I/O threads to avoid blocking rendering
68 threads.
69
70There are also two access patterns:
71
72* Accesses exhibiting temporal locality
73* Accesses not exhibiting temporal locality
74
75For the reasons listed above, the former channel is assumed to follow
76the former pattern unless ``VM_SEQ_READ`` or ``VM_RAND_READ`` is
77present, and the latter channel is assumed to follow the latter
78pattern unless outlying refaults have been observed.
79
80Workflow overview
81=================
82Evictable pages are divided into multiple generations for each
83``lruvec``. The youngest generation number is stored in
84``lrugen->max_seq`` for both anon and file types as they are aged on
85an equal footing. The oldest generation numbers are stored in
86``lrugen->min_seq[]`` separately for anon and file types as clean file
87pages can be evicted regardless of swap constraints. These three
88variables are monotonically increasing.
89
90Generation numbers are truncated into ``order_base_2(MAX_NR_GENS+1)``
91bits in order to fit into the gen counter in ``folio->flags``. Each
92truncated generation number is an index to ``lrugen->lists[]``. The
93sliding window technique is used to track at least ``MIN_NR_GENS`` and
94at most ``MAX_NR_GENS`` generations. The gen counter stores a value
95within ``[1, MAX_NR_GENS]`` while a page is on one of
96``lrugen->lists[]``; otherwise it stores zero.
97
98Each generation is divided into multiple tiers. A page accessed ``N``
99times through file descriptors is in tier ``order_base_2(N)``. Unlike
100generations, tiers do not have dedicated ``lrugen->lists[]``. In
101contrast to moving across generations, which requires the LRU lock,
102moving across tiers only involves atomic operations on
103``folio->flags`` and therefore has a negligible cost. A feedback loop
104modeled after the PID controller monitors refaults over all the tiers
105from anon and file types and decides which tiers from which types to
106evict or protect.
107
108There are two conceptually independent procedures: the aging and the
109eviction. They form a closed-loop system, i.e., the page reclaim.
110
111Aging
112-----
113The aging produces young generations. Given an ``lruvec``, it
114increments ``max_seq`` when ``max_seq-min_seq+1`` approaches
115``MIN_NR_GENS``. The aging promotes hot pages to the youngest
116generation when it finds them accessed through page tables; the
117demotion of cold pages happens consequently when it increments
118``max_seq``. The aging uses page table walks and rmap walks to find
119young PTEs. For the former, it iterates ``lruvec_memcg()->mm_list``
120and calls ``walk_page_range()`` with each ``mm_struct`` on this list
121to scan PTEs, and after each iteration, it increments ``max_seq``. For
122the latter, when the eviction walks the rmap and finds a young PTE,
123the aging scans the adjacent PTEs. For both, on finding a young PTE,
124the aging clears the accessed bit and updates the gen counter of the
125page mapped by this PTE to ``(max_seq%MAX_NR_GENS)+1``.
126
127Eviction
128--------
129The eviction consumes old generations. Given an ``lruvec``, it
130increments ``min_seq`` when ``lrugen->lists[]`` indexed by
131``min_seq%MAX_NR_GENS`` becomes empty. To select a type and a tier to
132evict from, it first compares ``min_seq[]`` to select the older type.
133If both types are equally old, it selects the one whose first tier has
134a lower refault percentage. The first tier contains single-use
135unmapped clean pages, which are the best bet. The eviction sorts a
136page according to its gen counter if the aging has found this page
137accessed through page tables and updated its gen counter. It also
138moves a page to the next generation, i.e., ``min_seq+1``, if this page
139was accessed multiple times through file descriptors and the feedback
140loop has detected outlying refaults from the tier this page is in. To
141this end, the feedback loop uses the first tier as the baseline, for
142the reason stated earlier.
143
144Summary
145-------
146The multi-gen LRU can be disassembled into the following parts:
147
148* Generations
149* Rmap walks
150* Page table walks
151* Bloom filters
152* PID controller
153
154The aging and the eviction form a producer-consumer model;
155specifically, the latter drives the former by the sliding window over
156generations. Within the aging, rmap walks drive page table walks by
157inserting hot densely populated page tables to the Bloom filters.
158Within the eviction, the PID controller uses refaults as the feedback
159to select types to evict and tiers to protect.
Documentation/mm/page_owner.rst+5−0
@@ -94,6 +94,11 @@ Usage · 93 unmodified lines
94 Page allocated via order XXX, ...94 Page allocated via order XXX, ...
95 PFN XXX ...95 PFN XXX ...
96 // Detailed stack96 // Detailed stack
97 By default, it will do full pfn dump, to start with a given pfn,
98 page_owner supports fseek.
99
100 FILE *fp = fopen("/sys/kernel/debug/page_owner", "r");
101 fseek(fp, pfn_start, SEEK_SET);
97 102
98 The ``page_owner_sort`` tool ignores ``PFN`` rows, puts the remaining rows103 The ``page_owner_sort`` tool ignores ``PFN`` rows, puts the remaining rows
99 in buf, uses regexp to extract the page order value, counts the times104 in buf, uses regexp to extract the page order value, counts the times
MAINTAINERS+26−1
@@ -11004,7 +11004,6 @@ F: arch/*/include/asm/*kasan.h · 11003 unmodified lines
11004F: arch/*/mm/kasan_init*11004F: arch/*/mm/kasan_init*
11005F: include/linux/kasan*.h11005F: include/linux/kasan*.h
11006F: lib/Kconfig.kasan11006F: lib/Kconfig.kasan
11007F: lib/test_kasan*.c
11008F: mm/kasan/11007F: mm/kasan/
11009F: scripts/Makefile.kasan11008F: scripts/Makefile.kasan
11010 11009
@@ -11438,6 +11437,20 @@ F: kernel/kmod.c · 427 unmodified lines
11438F: lib/test_kmod.c11437F: lib/test_kmod.c
11439F: tools/testing/selftests/kmod/11438F: tools/testing/selftests/kmod/
11440 11439
11440KMSAN
11441M: Alexander Potapenko <glider@google.com>
11442R: Marco Elver <elver@google.com>
11443R: Dmitry Vyukov <dvyukov@google.com>
11444L: kasan-dev@googlegroups.com
11445S: Maintained
11446F: Documentation/dev-tools/kmsan.rst
11447F: arch/*/include/asm/kmsan.h
11448F: arch/*/mm/kmsan_*
11449F: include/linux/kmsan*.h
11450F: lib/Kconfig.kmsan
11451F: mm/kmsan/
11452F: scripts/Makefile.kmsan
11453
11441KPROBES11454KPROBES
11442M: Naveen N. Rao <naveen.n.rao@linux.ibm.com>11455M: Naveen N. Rao <naveen.n.rao@linux.ibm.com>
11443M: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>11456M: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
@@ -12168,6 +12181,18 @@ L: linux-man@vger.kernel.org · 724 unmodified lines
12168S: Maintained12181S: Maintained
12169W: http://www.kernel.org/doc/man-pages12182W: http://www.kernel.org/doc/man-pages
12170 12183
12184MAPLE TREE
12185M: Liam R. Howlett <Liam.Howlett@oracle.com>
12186L: linux-mm@kvack.org
12187S: Supported
12188F: Documentation/core-api/maple_tree.rst
12189F: include/linux/maple_tree.h
12190F: include/trace/events/maple_tree.h
12191F: lib/maple_tree.c
12192F: lib/test_maple_tree.c
12193F: tools/testing/radix-tree/linux/maple_tree.h
12194F: tools/testing/radix-tree/maple.c
12195
12171MARDUK (CREATOR CI40) DEVICE TREE SUPPORT12196MARDUK (CREATOR CI40) DEVICE TREE SUPPORT
12172M: Rahul Bedarkar <rahulbedarkar89@gmail.com>12197M: Rahul Bedarkar <rahulbedarkar89@gmail.com>
12173L: linux-mips@vger.kernel.org12198L: linux-mips@vger.kernel.org
Makefile+1−0
@@ -1081,6 +1081,7 @@ include-y := scripts/Makefile.extrawarn · 1080 unmodified lines
1081include-$(CONFIG_DEBUG_INFO) += scripts/Makefile.debug1081include-$(CONFIG_DEBUG_INFO) += scripts/Makefile.debug
1082include-$(CONFIG_KASAN) += scripts/Makefile.kasan1082include-$(CONFIG_KASAN) += scripts/Makefile.kasan
1083include-$(CONFIG_KCSAN) += scripts/Makefile.kcsan1083include-$(CONFIG_KCSAN) += scripts/Makefile.kcsan
1084include-$(CONFIG_KMSAN) += scripts/Makefile.kmsan
1084include-$(CONFIG_UBSAN) += scripts/Makefile.ubsan1085include-$(CONFIG_UBSAN) += scripts/Makefile.ubsan
1085include-$(CONFIG_KCOV) += scripts/Makefile.kcov1086include-$(CONFIG_KCOV) += scripts/Makefile.kcov
1086include-$(CONFIG_RANDSTRUCT) += scripts/Makefile.randstruct1087include-$(CONFIG_RANDSTRUCT) += scripts/Makefile.randstruct
arch/Kconfig+8−0
@@ -1416,6 +1416,14 @@ config DYNAMIC_SIGFRAME · 1415 unmodified lines
1416config HAVE_ARCH_NODE_DEV_GROUP1416config HAVE_ARCH_NODE_DEV_GROUP
1417 bool1417 bool
1418 1418
1419config ARCH_HAS_NONLEAF_PMD_YOUNG
1420 bool
1421 help
1422 Architectures that select this option are capable of setting the
1423 accessed bit in non-leaf PMD entries when using them as part of linear
1424 address translations. Page table walkers that clear the accessed bit
1425 may use this capability to reduce their search space.
1426
1419source "kernel/gcov/Kconfig"1427source "kernel/gcov/Kconfig"
1420 1428
1421source "scripts/gcc-plugins/Kconfig"1429source "scripts/gcc-plugins/Kconfig"
arch/alpha/include/uapi/asm/mman.h+2−0
@@ -76,6 +76,8 @@ · 75 unmodified lines
76 76
77#define MADV_DONTNEED_LOCKED 24 /* like DONTNEED, but drop locked pages too */77#define MADV_DONTNEED_LOCKED 24 /* like DONTNEED, but drop locked pages too */
78 78
79#define MADV_COLLAPSE 25 /* Synchronous hugepage collapse */
80
79/* compatibility flags */81/* compatibility flags */
80#define MAP_FILE 082#define MAP_FILE 0
81 83
arch/arc/Kconfig+1−1
@@ -554,7 +554,7 @@ config ARC_BUILTIN_DTB_NAME · 553 unmodified lines
554 554
555endmenu # "ARC Architecture Configuration"555endmenu # "ARC Architecture Configuration"
556 556
557config FORCE_MAX_ZONEORDER557config ARCH_FORCE_MAX_ORDER
558 int "Maximum zone order"558 int "Maximum zone order"
559 default "12" if ARC_HUGEPAGE_16M559 default "12" if ARC_HUGEPAGE_16M
560 default "11"560 default "11"
arch/arm/Kconfig+1−1
@@ -1362,7 +1362,7 @@ config ARM_MODULE_PLTS · 1361 unmodified lines
1362 Disabling this is usually safe for small single-platform1362 Disabling this is usually safe for small single-platform
1363 configurations. If unsure, say y.1363 configurations. If unsure, say y.
1364 1364
1365config FORCE_MAX_ZONEORDER1365config ARCH_FORCE_MAX_ORDER
1366 int "Maximum zone order"1366 int "Maximum zone order"
1367 default "12" if SOC_AM33XX1367 default "12" if SOC_AM33XX
1368 default "9" if SA11111368 default "9" if SA1111
arch/arm/configs/imx_v6_v7_defconfig+1−1
@@ -31,7 +31,7 @@ CONFIG_SOC_VF610=y · 30 unmodified lines
31CONFIG_SMP=y31CONFIG_SMP=y
32CONFIG_ARM_PSCI=y32CONFIG_ARM_PSCI=y
33CONFIG_HIGHMEM=y33CONFIG_HIGHMEM=y
34CONFIG_FORCE_MAX_ZONEORDER=1434CONFIG_ARCH_FORCE_MAX_ORDER=14
35CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"35CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
36CONFIG_KEXEC=y36CONFIG_KEXEC=y
37CONFIG_CPU_FREQ=y37CONFIG_CPU_FREQ=y
arch/arm/configs/milbeaut_m10v_defconfig+1−1
@@ -26,7 +26,7 @@ CONFIG_THUMB2_KERNEL=y · 25 unmodified lines
26# CONFIG_THUMB2_AVOID_R_ARM_THM_JUMP11 is not set26# CONFIG_THUMB2_AVOID_R_ARM_THM_JUMP11 is not set
27# CONFIG_ARM_PATCH_IDIV is not set27# CONFIG_ARM_PATCH_IDIV is not set
28CONFIG_HIGHMEM=y28CONFIG_HIGHMEM=y
29CONFIG_FORCE_MAX_ZONEORDER=1229CONFIG_ARCH_FORCE_MAX_ORDER=12
30CONFIG_SECCOMP=y30CONFIG_SECCOMP=y
31CONFIG_KEXEC=y31CONFIG_KEXEC=y
32CONFIG_EFI=y32CONFIG_EFI=y
arch/arm/configs/oxnas_v6_defconfig+1−1
@@ -12,7 +12,7 @@ CONFIG_ARCH_OXNAS=y · 11 unmodified lines
12CONFIG_MACH_OX820=y12CONFIG_MACH_OX820=y
13CONFIG_SMP=y13CONFIG_SMP=y
14CONFIG_NR_CPUS=1614CONFIG_NR_CPUS=16
15CONFIG_FORCE_MAX_ZONEORDER=1215CONFIG_ARCH_FORCE_MAX_ORDER=12
16CONFIG_SECCOMP=y16CONFIG_SECCOMP=y
17CONFIG_ARM_APPENDED_DTB=y17CONFIG_ARM_APPENDED_DTB=y
18CONFIG_ARM_ATAG_DTB_COMPAT=y18CONFIG_ARM_ATAG_DTB_COMPAT=y
arch/arm/configs/pxa_defconfig+1−1
@@ -21,7 +21,7 @@ CONFIG_MACH_AKITA=y · 20 unmodified lines
21CONFIG_MACH_BORZOI=y21CONFIG_MACH_BORZOI=y
22CONFIG_PXA_SYSTEMS_CPLDS=y22CONFIG_PXA_SYSTEMS_CPLDS=y
23CONFIG_AEABI=y23CONFIG_AEABI=y
24CONFIG_FORCE_MAX_ZONEORDER=924CONFIG_ARCH_FORCE_MAX_ORDER=9
25CONFIG_CMDLINE="root=/dev/ram0 ro"25CONFIG_CMDLINE="root=/dev/ram0 ro"
26CONFIG_KEXEC=y26CONFIG_KEXEC=y
27CONFIG_CPU_FREQ=y27CONFIG_CPU_FREQ=y
arch/arm/configs/sama7_defconfig+1−1
@@ -19,7 +19,7 @@ CONFIG_ATMEL_CLOCKSOURCE_TCB=y · 18 unmodified lines
19# CONFIG_CACHE_L2X0 is not set19# CONFIG_CACHE_L2X0 is not set
20# CONFIG_ARM_PATCH_IDIV is not set20# CONFIG_ARM_PATCH_IDIV is not set
21# CONFIG_CPU_SW_DOMAIN_PAN is not set21# CONFIG_CPU_SW_DOMAIN_PAN is not set
22CONFIG_FORCE_MAX_ZONEORDER=1522CONFIG_ARCH_FORCE_MAX_ORDER=15
23CONFIG_UACCESS_WITH_MEMCPY=y23CONFIG_UACCESS_WITH_MEMCPY=y
24# CONFIG_ATAGS is not set24# CONFIG_ATAGS is not set
25CONFIG_CMDLINE="console=ttyS0,115200 earlyprintk ignore_loglevel"25CONFIG_CMDLINE="console=ttyS0,115200 earlyprintk ignore_loglevel"
arch/arm/configs/sp7021_defconfig+1−1
@@ -17,7 +17,7 @@ CONFIG_ARCH_SUNPLUS=y · 16 unmodified lines
17# CONFIG_VDSO is not set17# CONFIG_VDSO is not set
18CONFIG_SMP=y18CONFIG_SMP=y
19CONFIG_THUMB2_KERNEL=y19CONFIG_THUMB2_KERNEL=y
20CONFIG_FORCE_MAX_ZONEORDER=1220CONFIG_ARCH_FORCE_MAX_ORDER=12
21CONFIG_VFP=y21CONFIG_VFP=y
22CONFIG_NEON=y22CONFIG_NEON=y
23CONFIG_MODULES=y23CONFIG_MODULES=y
arch/arm64/Kconfig+1−1
@@ -1431,7 +1431,7 @@ config XEN · 1430 unmodified lines
1431 help1431 help
1432 Say Y if you want to run Linux in a Virtual Machine on Xen on ARM64.1432 Say Y if you want to run Linux in a Virtual Machine on Xen on ARM64.
1433 1433
1434config FORCE_MAX_ZONEORDER1434config ARCH_FORCE_MAX_ORDER
1435 int1435 int
1436 default "14" if ARM64_64K_PAGES1436 default "14" if ARM64_64K_PAGES
1437 default "12" if ARM64_16K_PAGES1437 default "12" if ARM64_16K_PAGES
arch/arm64/include/asm/pgtable.h+2−13
@@ -1082,24 +1082,13 @@ static inline void update_mmu_cache(struct vm_area_struct *vma, · 1081 unmodified lines
1082 * page after fork() + CoW for pfn mappings. We don't always have a1082 * page after fork() + CoW for pfn mappings. We don't always have a
1083 * hardware-managed access flag on arm64.1083 * hardware-managed access flag on arm64.
1084 */1084 */
1085static inline bool arch_faults_on_old_pte(void)1085#define arch_has_hw_pte_young cpu_has_hw_af
1086{
1087 /* The register read below requires a stable CPU to make any sense */
1088 cant_migrate();
1089
1090 return !cpu_has_hw_af();
1091}
1092#define arch_faults_on_old_pte arch_faults_on_old_pte
1093 1086
1094/*1087/*
1095 * Experimentally, it's cheap to set the access flag in hardware and we1088 * Experimentally, it's cheap to set the access flag in hardware and we
1096 * benefit from prefaulting mappings as 'old' to start with.1089 * benefit from prefaulting mappings as 'old' to start with.
1097 */1090 */
1098static inline bool arch_wants_old_prefaulted_pte(void)1091#define arch_wants_old_prefaulted_pte cpu_has_hw_af
1099{
1100 return !arch_faults_on_old_pte();
1101}
1102#define arch_wants_old_prefaulted_pte arch_wants_old_prefaulted_pte
1103 1092
1104static inline bool pud_sect_supported(void)1093static inline bool pud_sect_supported(void)
1105{1094{
arch/arm64/kernel/elfcore.c+10−6
@@ -8,9 +8,9 @@ · 7 unmodified lines
8#include <asm/cpufeature.h>8#include <asm/cpufeature.h>
9#include <asm/mte.h>9#include <asm/mte.h>
10 10
11#define for_each_mte_vma(tsk, vma) \11#define for_each_mte_vma(vmi, vma) \
12 if (system_supports_mte()) \12 if (system_supports_mte()) \
13 for (vma = tsk->mm->mmap; vma; vma = vma->vm_next) \13 for_each_vma(vmi, vma) \
14 if (vma->vm_flags & VM_MTE)14 if (vma->vm_flags & VM_MTE)
15 15
16static unsigned long mte_vma_tag_dump_size(struct vm_area_struct *vma)16static unsigned long mte_vma_tag_dump_size(struct vm_area_struct *vma)
@@ -81,8 +81,9 @@ Elf_Half elf_core_extra_phdrs(void) · 64 unmodified lines
81{81{
82 struct vm_area_struct *vma;82 struct vm_area_struct *vma;
83 int vma_count = 0;83 int vma_count = 0;
84 VMA_ITERATOR(vmi, current->mm, 0);
84 85
85 for_each_mte_vma(current, vma)86 for_each_mte_vma(vmi, vma)
86 vma_count++;87 vma_count++;
87 88
88 return vma_count;89 return vma_count;
@@ -91,8 +92,9 @@ Elf_Half elf_core_extra_phdrs(void) · 2 unmodified lines
91int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset)92int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset)
92{93{
93 struct vm_area_struct *vma;94 struct vm_area_struct *vma;
95 VMA_ITERATOR(vmi, current->mm, 0);
94 96
95 for_each_mte_vma(current, vma) {97 for_each_mte_vma(vmi, vma) {
96 struct elf_phdr phdr;98 struct elf_phdr phdr;
97 99
98 phdr.p_type = PT_AARCH64_MEMTAG_MTE;100 phdr.p_type = PT_AARCH64_MEMTAG_MTE;
@@ -116,8 +118,9 @@ size_t elf_core_extra_data_size(void) · 17 unmodified lines
116{118{
117 struct vm_area_struct *vma;119 struct vm_area_struct *vma;
118 size_t data_size = 0;120 size_t data_size = 0;
121 VMA_ITERATOR(vmi, current->mm, 0);
119 122
120 for_each_mte_vma(current, vma)123 for_each_mte_vma(vmi, vma)
121 data_size += mte_vma_tag_dump_size(vma);124 data_size += mte_vma_tag_dump_size(vma);
122 125
123 return data_size;126 return data_size;
@@ -126,8 +129,9 @@ size_t elf_core_extra_data_size(void) · 2 unmodified lines
126int elf_core_write_extra_data(struct coredump_params *cprm)129int elf_core_write_extra_data(struct coredump_params *cprm)
127{130{
128 struct vm_area_struct *vma;131 struct vm_area_struct *vma;
132 VMA_ITERATOR(vmi, current->mm, 0);
129 133
130 for_each_mte_vma(current, vma) {134 for_each_mte_vma(vmi, vma) {
131 if (vma->vm_flags & VM_DONTDUMP)135 if (vma->vm_flags & VM_DONTDUMP)
132 continue;136 continue;
133 137
arch/arm64/kernel/vdso.c+2−1
@@ -133,10 +133,11 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns) · 132 unmodified lines
133{133{
134 struct mm_struct *mm = task->mm;134 struct mm_struct *mm = task->mm;
135 struct vm_area_struct *vma;135 struct vm_area_struct *vma;
136 VMA_ITERATOR(vmi, mm, 0);
136 137
137 mmap_read_lock(mm);138 mmap_read_lock(mm);
138 139
139 for (vma = mm->mmap; vma; vma = vma->vm_next) {140 for_each_vma(vmi, vma) {
140 unsigned long size = vma->vm_end - vma->vm_start;141 unsigned long size = vma->vm_end - vma->vm_start;
141 142
142 if (vma_is_special_mapping(vma, vdso_info[VDSO_ABI_AA64].dm))143 if (vma_is_special_mapping(vma, vdso_info[VDSO_ABI_AA64].dm))
arch/arm64/mm/hugetlbpage.c+1−1
@@ -245,7 +245,7 @@ static inline struct folio *hugetlb_swap_entry_to_folio(swp_entry_t entry) · 244 unmodified lines
245{245{
246 VM_BUG_ON(!is_migration_entry(entry) && !is_hwpoison_entry(entry));246 VM_BUG_ON(!is_migration_entry(entry) && !is_hwpoison_entry(entry));
247 247
248 return page_folio(pfn_to_page(swp_offset(entry)));248 return page_folio(pfn_to_page(swp_offset_pfn(entry)));
249}249}
250 250
251void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,251void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
arch/csky/Kconfig+1−1
@@ -332,7 +332,7 @@ config HIGHMEM · 331 unmodified lines
332 select KMAP_LOCAL332 select KMAP_LOCAL
333 default y333 default y
334 334
335config FORCE_MAX_ZONEORDER335config ARCH_FORCE_MAX_ORDER
336 int "Maximum zone order"336 int "Maximum zone order"
337 default "11"337 default "11"
338 338
arch/ia64/Kconfig+1−1
@@ -200,7 +200,7 @@ config IA64_CYCLONE · 199 unmodified lines
200 Say Y here to enable support for IBM EXA Cyclone time source.200 Say Y here to enable support for IBM EXA Cyclone time source.
201 If you're unsure, answer N.201 If you're unsure, answer N.
202 202
203config FORCE_MAX_ZONEORDER203config ARCH_FORCE_MAX_ORDER
204 int "MAX_ORDER (11 - 17)" if !HUGETLB_PAGE204 int "MAX_ORDER (11 - 17)" if !HUGETLB_PAGE
205 range 11 17 if !HUGETLB_PAGE205 range 11 17 if !HUGETLB_PAGE
206 default "17" if HUGETLB_PAGE206 default "17" if HUGETLB_PAGE
arch/ia64/include/asm/sparsemem.h+3−3
@@ -11,10 +11,10 @@ · 10 unmodified lines
11 11
12#define SECTION_SIZE_BITS (30)12#define SECTION_SIZE_BITS (30)
13#define MAX_PHYSMEM_BITS (50)13#define MAX_PHYSMEM_BITS (50)
14#ifdef CONFIG_FORCE_MAX_ZONEORDER14#ifdef CONFIG_ARCH_FORCE_MAX_ORDER
15#if ((CONFIG_FORCE_MAX_ZONEORDER - 1 + PAGE_SHIFT) > SECTION_SIZE_BITS)15#if ((CONFIG_ARCH_FORCE_MAX_ORDER - 1 + PAGE_SHIFT) > SECTION_SIZE_BITS)
16#undef SECTION_SIZE_BITS16#undef SECTION_SIZE_BITS
17#define SECTION_SIZE_BITS (CONFIG_FORCE_MAX_ZONEORDER - 1 + PAGE_SHIFT)17#define SECTION_SIZE_BITS (CONFIG_ARCH_FORCE_MAX_ORDER - 1 + PAGE_SHIFT)
18#endif18#endif
19#endif19#endif
20 20
arch/loongarch/Kconfig+1−1
@@ -377,7 +377,7 @@ config NODES_SHIFT · 376 unmodified lines
377 default "6"377 default "6"
378 depends on NUMA378 depends on NUMA
379 379
380config FORCE_MAX_ZONEORDER380config ARCH_FORCE_MAX_ORDER
381 int "Maximum zone order"381 int "Maximum zone order"
382 range 14 64 if PAGE_SIZE_64KB382 range 14 64 if PAGE_SIZE_64KB
383 default "14" if PAGE_SIZE_64KB383 default "14" if PAGE_SIZE_64KB
arch/m68k/Kconfig.cpu+1−1
@@ -397,7 +397,7 @@ config SINGLE_MEMORY_CHUNK · 396 unmodified lines
397 order" to save memory that could be wasted for unused memory map.397 order" to save memory that could be wasted for unused memory map.
398 Say N if not sure.398 Say N if not sure.
399 399
400config FORCE_MAX_ZONEORDER400config ARCH_FORCE_MAX_ORDER
401 int "Maximum zone order" if ADVANCED401 int "Maximum zone order" if ADVANCED
402 depends on !SINGLE_MEMORY_CHUNK402 depends on !SINGLE_MEMORY_CHUNK
403 default "11"403 default "11"
arch/mips/Kconfig+1−1
@@ -2140,7 +2140,7 @@ config PAGE_SIZE_64KB · 2139 unmodified lines
2140 2140
2141endchoice2141endchoice
2142 2142
2143config FORCE_MAX_ZONEORDER2143config ARCH_FORCE_MAX_ORDER
2144 int "Maximum zone order"2144 int "Maximum zone order"
2145 range 14 64 if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_64KB2145 range 14 64 if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_64KB
2146 default "14" if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_64KB2146 default "14" if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_64KB
arch/mips/configs/db1xxx_defconfig+0−1
@@ -9,7 +9,6 @@ CONFIG_HIGH_RES_TIMERS=y · 8 unmodified lines
9CONFIG_LOG_BUF_SHIFT=169CONFIG_LOG_BUF_SHIFT=16
10CONFIG_CGROUPS=y10CONFIG_CGROUPS=y
11CONFIG_MEMCG=y11CONFIG_MEMCG=y
12CONFIG_MEMCG_SWAP=y
13CONFIG_BLK_CGROUP=y12CONFIG_BLK_CGROUP=y
14CONFIG_CGROUP_SCHED=y13CONFIG_CGROUP_SCHED=y
15CONFIG_CFS_BANDWIDTH=y14CONFIG_CFS_BANDWIDTH=y
arch/mips/configs/generic_defconfig+0−1
@@ -3,7 +3,6 @@ CONFIG_NO_HZ_IDLE=y · 2 unmodified lines
3CONFIG_IKCONFIG=y3CONFIG_IKCONFIG=y
4CONFIG_IKCONFIG_PROC=y4CONFIG_IKCONFIG_PROC=y
5CONFIG_MEMCG=y5CONFIG_MEMCG=y
6CONFIG_MEMCG_SWAP=y
7CONFIG_BLK_CGROUP=y6CONFIG_BLK_CGROUP=y
8CONFIG_CFS_BANDWIDTH=y7CONFIG_CFS_BANDWIDTH=y
9CONFIG_RT_GROUP_SCHED=y8CONFIG_RT_GROUP_SCHED=y
arch/mips/include/uapi/asm/mman.h+2−0
@@ -103,6 +103,8 @@ · 102 unmodified lines
103 103
104#define MADV_DONTNEED_LOCKED 24 /* like DONTNEED, but drop locked pages too */104#define MADV_DONTNEED_LOCKED 24 /* like DONTNEED, but drop locked pages too */
105 105
106#define MADV_COLLAPSE 25 /* Synchronous hugepage collapse */
107
106/* compatibility flags */108/* compatibility flags */
107#define MAP_FILE 0109#define MAP_FILE 0
108 110
arch/nios2/Kconfig+1−1
@@ -44,7 +44,7 @@ menu "Kernel features" · 43 unmodified lines
44 44
45source "kernel/Kconfig.hz"45source "kernel/Kconfig.hz"
46 46
47config FORCE_MAX_ZONEORDER47config ARCH_FORCE_MAX_ORDER
48 int "Maximum zone order"48 int "Maximum zone order"
49 range 9 2049 range 9 20
50 default "11"50 default "11"
arch/parisc/include/uapi/asm/mman.h+2−0
@@ -70,6 +70,8 @@ · 69 unmodified lines
70#define MADV_WIPEONFORK 71 /* Zero memory on fork, child only */70#define MADV_WIPEONFORK 71 /* Zero memory on fork, child only */
71#define MADV_KEEPONFORK 72 /* Undo MADV_WIPEONFORK */71#define MADV_KEEPONFORK 72 /* Undo MADV_WIPEONFORK */
72 72
73#define MADV_COLLAPSE 73 /* Synchronous hugepage collapse */
74
73#define MADV_HWPOISON 100 /* poison a page for testing */75#define MADV_HWPOISON 100 /* poison a page for testing */
74#define MADV_SOFT_OFFLINE 101 /* soft offline page for testing */76#define MADV_SOFT_OFFLINE 101 /* soft offline page for testing */
75 77
arch/parisc/kernel/cache.c+7−2
@@ -657,15 +657,20 @@ static inline unsigned long mm_total_size(struct mm_struct *mm) · 656 unmodified lines
657{657{
658 struct vm_area_struct *vma;658 struct vm_area_struct *vma;
659 unsigned long usize = 0;659 unsigned long usize = 0;
660 VMA_ITERATOR(vmi, mm, 0);
660 661
661 for (vma = mm->mmap; vma && usize < parisc_cache_flush_threshold; vma = vma->vm_next)662 for_each_vma(vmi, vma) {
663 if (usize >= parisc_cache_flush_threshold)
664 break;
662 usize += vma->vm_end - vma->vm_start;665 usize += vma->vm_end - vma->vm_start;
666 }
663 return usize;667 return usize;
664}668}
665 669
666void flush_cache_mm(struct mm_struct *mm)670void flush_cache_mm(struct mm_struct *mm)
667{671{
668 struct vm_area_struct *vma;672 struct vm_area_struct *vma;
673 VMA_ITERATOR(vmi, mm, 0);
669 674
670 /*675 /*
671 * Flushing the whole cache on each cpu takes forever on676 * Flushing the whole cache on each cpu takes forever on
@@ -685,7 +690,7 @@ void flush_cache_mm(struct mm_struct *mm) · 13 unmodified lines
685 }690 }
686 691
687 /* Flush mm */692 /* Flush mm */
688 for (vma = mm->mmap; vma; vma = vma->vm_next)693 for_each_vma(vmi, vma)
689 flush_cache_pages(vma, vma->vm_start, vma->vm_end);694 flush_cache_pages(vma, vma->vm_start, vma->vm_end);
690}695}
691 696
arch/powerpc/Kconfig+1−1
@@ -846,7 +846,7 @@ config DATA_SHIFT · 845 unmodified lines
846 in that case. If PIN_TLB is selected, it must be aligned to 8M as846 in that case. If PIN_TLB is selected, it must be aligned to 8M as
847 8M pages will be pinned.847 8M pages will be pinned.
848 848
849config FORCE_MAX_ZONEORDER849config ARCH_FORCE_MAX_ORDER
850 int "Maximum zone order"850 int "Maximum zone order"
851 range 8 9 if PPC64 && PPC_64K_PAGES851 range 8 9 if PPC64 && PPC_64K_PAGES
852 default "9" if PPC64 && PPC_64K_PAGES852 default "9" if PPC64 && PPC_64K_PAGES
arch/powerpc/configs/85xx/ge_imp3a_defconfig+1−1
@@ -30,7 +30,7 @@ CONFIG_PREEMPT=y · 29 unmodified lines
30# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set30# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
31CONFIG_BINFMT_MISC=m31CONFIG_BINFMT_MISC=m
32CONFIG_MATH_EMULATION=y32CONFIG_MATH_EMULATION=y
33CONFIG_FORCE_MAX_ZONEORDER=1733CONFIG_ARCH_FORCE_MAX_ORDER=17
34CONFIG_PCI=y34CONFIG_PCI=y
35CONFIG_PCIEPORTBUS=y35CONFIG_PCIEPORTBUS=y
36CONFIG_PCI_MSI=y36CONFIG_PCI_MSI=y
arch/powerpc/configs/fsl-emb-nonhw.config+1−1
@@ -41,7 +41,7 @@ CONFIG_FIXED_PHY=y · 40 unmodified lines
41CONFIG_FONT_8x16=y41CONFIG_FONT_8x16=y
42CONFIG_FONT_8x8=y42CONFIG_FONT_8x8=y
43CONFIG_FONTS=y43CONFIG_FONTS=y
44CONFIG_FORCE_MAX_ZONEORDER=1344CONFIG_ARCH_FORCE_MAX_ORDER=13
45CONFIG_FRAMEBUFFER_CONSOLE=y45CONFIG_FRAMEBUFFER_CONSOLE=y
46CONFIG_FRAME_WARN=102446CONFIG_FRAME_WARN=1024
47CONFIG_FTL=y47CONFIG_FTL=y
arch/powerpc/configs/powernv_defconfig+0−1
@@ -17,7 +17,6 @@ CONFIG_LOG_CPU_MAX_BUF_SHIFT=13 · 16 unmodified lines
17CONFIG_NUMA_BALANCING=y17CONFIG_NUMA_BALANCING=y
18CONFIG_CGROUPS=y18CONFIG_CGROUPS=y
19CONFIG_MEMCG=y19CONFIG_MEMCG=y
20CONFIG_MEMCG_SWAP=y
21CONFIG_CGROUP_SCHED=y20CONFIG_CGROUP_SCHED=y
22CONFIG_CGROUP_FREEZER=y21CONFIG_CGROUP_FREEZER=y
23CONFIG_CPUSETS=y22CONFIG_CPUSETS=y
arch/powerpc/configs/pseries_defconfig+0−1
@@ -18,7 +18,6 @@ CONFIG_LOG_CPU_MAX_BUF_SHIFT=13 · 17 unmodified lines
18CONFIG_NUMA_BALANCING=y18CONFIG_NUMA_BALANCING=y
19CONFIG_CGROUPS=y19CONFIG_CGROUPS=y
20CONFIG_MEMCG=y20CONFIG_MEMCG=y
21CONFIG_MEMCG_SWAP=y
22CONFIG_CGROUP_SCHED=y21CONFIG_CGROUP_SCHED=y
23CONFIG_CGROUP_FREEZER=y22CONFIG_CGROUP_FREEZER=y
24CONFIG_CPUSETS=y23CONFIG_CPUSETS=y
arch/powerpc/kernel/vdso.c+3−3
@@ -115,18 +115,18 @@ struct vdso_data *arch_get_vdso_data(void *vvar_page) · 114 unmodified lines
115int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)115int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
116{116{
117 struct mm_struct *mm = task->mm;117 struct mm_struct *mm = task->mm;
118 VMA_ITERATOR(vmi, mm, 0);
118 struct vm_area_struct *vma;119 struct vm_area_struct *vma;
119 120
120 mmap_read_lock(mm);121 mmap_read_lock(mm);
121 122 for_each_vma(vmi, vma) {
122 for (vma = mm->mmap; vma; vma = vma->vm_next) {
123 unsigned long size = vma->vm_end - vma->vm_start;123 unsigned long size = vma->vm_end - vma->vm_start;
124 124
125 if (vma_is_special_mapping(vma, &vvar_spec))125 if (vma_is_special_mapping(vma, &vvar_spec))
126 zap_page_range(vma, vma->vm_start, size);126 zap_page_range(vma, vma->vm_start, size);
127 }127 }
128
129 mmap_read_unlock(mm);128 mmap_read_unlock(mm);
129
130 return 0;130 return 0;
131}131}
132 132
arch/powerpc/mm/book3s32/tlb.c+6−5
@@ -81,14 +81,15 @@ EXPORT_SYMBOL(hash__flush_range); · 80 unmodified lines
81void hash__flush_tlb_mm(struct mm_struct *mm)81void hash__flush_tlb_mm(struct mm_struct *mm)
82{82{
83 struct vm_area_struct *mp;83 struct vm_area_struct *mp;
84 VMA_ITERATOR(vmi, mm, 0);
84 85
85 /*86 /*
86 * It is safe to go down the mm's list of vmas when called87 * It is safe to iterate the vmas when called from dup_mmap,
87 * from dup_mmap, holding mmap_lock. It would also be safe from88 * holding mmap_lock. It would also be safe from unmap_region
88 * unmap_region or exit_mmap, but not from vmtruncate on SMP -89 * or exit_mmap, but not from vmtruncate on SMP - but it seems
89 * but it seems dup_mmap is the only SMP case which gets here.90 * dup_mmap is the only SMP case which gets here.
90 */91 */
91 for (mp = mm->mmap; mp != NULL; mp = mp->vm_next)92 for_each_vma(vmi, mp)
92 hash__flush_range(mp->vm_mm, mp->vm_start, mp->vm_end);93 hash__flush_range(mp->vm_mm, mp->vm_start, mp->vm_end);
93}94}
94EXPORT_SYMBOL(hash__flush_tlb_mm);95EXPORT_SYMBOL(hash__flush_tlb_mm);
arch/powerpc/mm/book3s64/subpage_prot.c+2−11
@@ -149,24 +149,15 @@ static void subpage_mark_vma_nohuge(struct mm_struct *mm, unsigned long addr, · 148 unmodified lines
149 unsigned long len)149 unsigned long len)
150{150{
151 struct vm_area_struct *vma;151 struct vm_area_struct *vma;
152 VMA_ITERATOR(vmi, mm, addr);
152 153
153 /*154 /*
154 * We don't try too hard, we just mark all the vma in that range155 * We don't try too hard, we just mark all the vma in that range
155 * VM_NOHUGEPAGE and split them.156 * VM_NOHUGEPAGE and split them.
156 */157 */
157 vma = find_vma(mm, addr);158 for_each_vma_range(vmi, vma, addr + len) {
158 /*
159 * If the range is in unmapped range, just return
160 */
161 if (vma && ((addr + len) <= vma->vm_start))
162 return;
163
164 while (vma) {
165 if (vma->vm_start >= (addr + len))
166 break;
167 vma->vm_flags |= VM_NOHUGEPAGE;159 vma->vm_flags |= VM_NOHUGEPAGE;
168 walk_page_vma(vma, &subpage_walk_ops, NULL);160 walk_page_vma(vma, &subpage_walk_ops, NULL);
169 vma = vma->vm_next;
170 }161 }
171}162}
172#else163#else
arch/riscv/kernel/vdso.c+2−1
@@ -114,11 +114,12 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns) · 113 unmodified lines
114{114{
115 struct mm_struct *mm = task->mm;115 struct mm_struct *mm = task->mm;
116 struct vm_area_struct *vma;116 struct vm_area_struct *vma;
117 VMA_ITERATOR(vmi, mm, 0);
117 struct __vdso_info *vdso_info = mm->context.vdso_info;118 struct __vdso_info *vdso_info = mm->context.vdso_info;
118 119
119 mmap_read_lock(mm);120 mmap_read_lock(mm);
120 121
121 for (vma = mm->mmap; vma; vma = vma->vm_next) {122 for_each_vma(vmi, vma) {
122 unsigned long size = vma->vm_end - vma->vm_start;123 unsigned long size = vma->vm_end - vma->vm_start;
123 124
124 if (vma_is_special_mapping(vma, vdso_info->dm))125 if (vma_is_special_mapping(vma, vdso_info->dm))
arch/s390/kernel/vdso.c+2−1
@@ -69,10 +69,11 @@ static struct page *find_timens_vvar_page(struct vm_area_struct *vma) · 68 unmodified lines
69int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)69int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
70{70{
71 struct mm_struct *mm = task->mm;71 struct mm_struct *mm = task->mm;
72 VMA_ITERATOR(vmi, mm, 0);
72 struct vm_area_struct *vma;73 struct vm_area_struct *vma;
73 74
74 mmap_read_lock(mm);75 mmap_read_lock(mm);
75 for (vma = mm->mmap; vma; vma = vma->vm_next) {76 for_each_vma(vmi, vma) {
76 unsigned long size = vma->vm_end - vma->vm_start;77 unsigned long size = vma->vm_end - vma->vm_start;
77 78
78 if (!vma_is_special_mapping(vma, &vvar_mapping))79 if (!vma_is_special_mapping(vma, &vvar_mapping))
arch/s390/lib/uaccess.c+2−1
@@ -81,8 +81,9 @@ unsigned long _copy_from_user_key(void *to, const void __user *from, · 80 unmodified lines
81 81
82 might_fault();82 might_fault();
83 if (!should_fail_usercopy()) {83 if (!should_fail_usercopy()) {
84 instrument_copy_from_user(to, from, n);84 instrument_copy_from_user_before(to, from, n);
85 res = raw_copy_from_user_key(to, from, n, key);85 res = raw_copy_from_user_key(to, from, n, key);
86 instrument_copy_from_user_after(to, from, n, res);
86 }87 }
87 if (unlikely(res))88 if (unlikely(res))
88 memset(to + (n - res), 0, res);89 memset(to + (n - res), 0, res);
arch/s390/mm/gmap.c+4−2
@@ -2515,8 +2515,9 @@ static const struct mm_walk_ops thp_split_walk_ops = { · 2514 unmodified lines
2515static inline void thp_split_mm(struct mm_struct *mm)2515static inline void thp_split_mm(struct mm_struct *mm)
2516{2516{
2517 struct vm_area_struct *vma;2517 struct vm_area_struct *vma;
2518 VMA_ITERATOR(vmi, mm, 0);
2518 2519
2519 for (vma = mm->mmap; vma != NULL; vma = vma->vm_next) {2520 for_each_vma(vmi, vma) {
2520 vma->vm_flags &= ~VM_HUGEPAGE;2521 vma->vm_flags &= ~VM_HUGEPAGE;
2521 vma->vm_flags |= VM_NOHUGEPAGE;2522 vma->vm_flags |= VM_NOHUGEPAGE;
2522 walk_page_vma(vma, &thp_split_walk_ops, NULL);2523 walk_page_vma(vma, &thp_split_walk_ops, NULL);
@@ -2584,8 +2585,9 @@ int gmap_mark_unmergeable(void) · 61 unmodified lines
2584 struct mm_struct *mm = current->mm;2585 struct mm_struct *mm = current->mm;
2585 struct vm_area_struct *vma;2586 struct vm_area_struct *vma;
2586 int ret;2587 int ret;
2588 VMA_ITERATOR(vmi, mm, 0);
2587 2589
2588 for (vma = mm->mmap; vma; vma = vma->vm_next) {2590 for_each_vma(vmi, vma) {
2589 ret = ksm_madvise(vma, vma->vm_start, vma->vm_end,2591 ret = ksm_madvise(vma, vma->vm_start, vma->vm_end,
2590 MADV_UNMERGEABLE, &vma->vm_flags);2592 MADV_UNMERGEABLE, &vma->vm_flags);
2591 if (ret)2593 if (ret)
arch/s390/mm/hugetlbpage.c+0−10
@@ -237,16 +237,6 @@ int pud_huge(pud_t pud) · 236 unmodified lines
237 return pud_large(pud);237 return pud_large(pud);
238}238}
239 239
240struct page *
241follow_huge_pud(struct mm_struct *mm, unsigned long address,
242 pud_t *pud, int flags)
243{
244 if (flags & FOLL_GET)
245 return NULL;
246
247 return pud_page(*pud) + ((address & ~PUD_MASK) >> PAGE_SHIFT);
248}
249
250bool __init arch_hugetlb_valid_size(unsigned long size)240bool __init arch_hugetlb_valid_size(unsigned long size)
251{241{
252 if (MACHINE_HAS_EDAT1 && size == PMD_SIZE)242 if (MACHINE_HAS_EDAT1 && size == PMD_SIZE)
arch/sh/configs/ecovec24_defconfig+1−1
@@ -8,7 +8,7 @@ CONFIG_MODULES=y · 7 unmodified lines
8CONFIG_MODULE_UNLOAD=y8CONFIG_MODULE_UNLOAD=y
9# CONFIG_BLK_DEV_BSG is not set9# CONFIG_BLK_DEV_BSG is not set
10CONFIG_CPU_SUBTYPE_SH7724=y10CONFIG_CPU_SUBTYPE_SH7724=y
11CONFIG_FORCE_MAX_ZONEORDER=1211CONFIG_ARCH_FORCE_MAX_ORDER=12
12CONFIG_MEMORY_SIZE=0x1000000012CONFIG_MEMORY_SIZE=0x10000000
13CONFIG_FLATMEM_MANUAL=y13CONFIG_FLATMEM_MANUAL=y
14CONFIG_SH_ECOVEC=y14CONFIG_SH_ECOVEC=y
arch/sh/configs/sdk7786_defconfig+0−1
@@ -16,7 +16,6 @@ CONFIG_CPUSETS=y · 15 unmodified lines
16# CONFIG_PROC_PID_CPUSET is not set16# CONFIG_PROC_PID_CPUSET is not set
17CONFIG_CGROUP_CPUACCT=y17CONFIG_CGROUP_CPUACCT=y
18CONFIG_CGROUP_MEMCG=y18CONFIG_CGROUP_MEMCG=y
19CONFIG_CGROUP_MEMCG_SWAP=y
20CONFIG_CGROUP_SCHED=y19CONFIG_CGROUP_SCHED=y
21CONFIG_RT_GROUP_SCHED=y20CONFIG_RT_GROUP_SCHED=y
22CONFIG_BLK_CGROUP=y21CONFIG_BLK_CGROUP=y
arch/sh/configs/urquell_defconfig+0−1
@@ -14,7 +14,6 @@ CONFIG_CPUSETS=y · 13 unmodified lines
14# CONFIG_PROC_PID_CPUSET is not set14# CONFIG_PROC_PID_CPUSET is not set
15CONFIG_CGROUP_CPUACCT=y15CONFIG_CGROUP_CPUACCT=y
16CONFIG_CGROUP_MEMCG=y16CONFIG_CGROUP_MEMCG=y
17CONFIG_CGROUP_MEMCG_SWAP=y
18CONFIG_CGROUP_SCHED=y17CONFIG_CGROUP_SCHED=y
19CONFIG_RT_GROUP_SCHED=y18CONFIG_RT_GROUP_SCHED=y
20CONFIG_BLK_DEV_INITRD=y19CONFIG_BLK_DEV_INITRD=y
arch/sh/mm/Kconfig+1−1
@@ -18,7 +18,7 @@ config PAGE_OFFSET · 17 unmodified lines
18 default "0x80000000" if MMU18 default "0x80000000" if MMU
19 default "0x00000000"19 default "0x00000000"
20 20
21config FORCE_MAX_ZONEORDER21config ARCH_FORCE_MAX_ORDER
22 int "Maximum zone order"22 int "Maximum zone order"
23 range 9 64 if PAGE_SIZE_16KB23 range 9 64 if PAGE_SIZE_16KB
24 default "9" if PAGE_SIZE_16KB24 default "9" if PAGE_SIZE_16KB
arch/sparc/Kconfig+1−1
@@ -269,7 +269,7 @@ config ARCH_SPARSEMEM_ENABLE · 268 unmodified lines
269config ARCH_SPARSEMEM_DEFAULT269config ARCH_SPARSEMEM_DEFAULT
270 def_bool y if SPARC64270 def_bool y if SPARC64
271 271
272config FORCE_MAX_ZONEORDER272config ARCH_FORCE_MAX_ORDER
273 int "Maximum zone order"273 int "Maximum zone order"
274 default "13"274 default "13"
275 help275 help
arch/um/kernel/tlb.c+6−8
@@ -584,21 +584,19 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, · 583 unmodified lines
584 584
585void flush_tlb_mm(struct mm_struct *mm)585void flush_tlb_mm(struct mm_struct *mm)
586{586{
587 struct vm_area_struct *vma = mm->mmap;587 struct vm_area_struct *vma;
588 VMA_ITERATOR(vmi, mm, 0);
588 589
589 while (vma != NULL) {590 for_each_vma(vmi, vma)
590 fix_range(mm, vma->vm_start, vma->vm_end, 0);591 fix_range(mm, vma->vm_start, vma->vm_end, 0);
591 vma = vma->vm_next;
592 }
593}592}
594 593
595void force_flush_all(void)594void force_flush_all(void)
596{595{
597 struct mm_struct *mm = current->mm;596 struct mm_struct *mm = current->mm;
598 struct vm_area_struct *vma = mm->mmap;597 struct vm_area_struct *vma;
598 VMA_ITERATOR(vmi, mm, 0);
599 599
600 while (vma != NULL) {600 for_each_vma(vmi, vma)
601 fix_range(mm, vma->vm_start, vma->vm_end, 1);601 fix_range(mm, vma->vm_start, vma->vm_end, 1);
602 vma = vma->vm_next;
603 }
604}602}
arch/x86/Kconfig+9−1
@@ -85,6 +85,7 @@ config X86 · 84 unmodified lines
85 select ARCH_HAS_PMEM_API if X86_6485 select ARCH_HAS_PMEM_API if X86_64
86 select ARCH_HAS_PTE_DEVMAP if X86_6486 select ARCH_HAS_PTE_DEVMAP if X86_64
87 select ARCH_HAS_PTE_SPECIAL87 select ARCH_HAS_PTE_SPECIAL
88 select ARCH_HAS_NONLEAF_PMD_YOUNG if PGTABLE_LEVELS > 2
88 select ARCH_HAS_UACCESS_FLUSHCACHE if X86_6489 select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64
89 select ARCH_HAS_COPY_MC if X86_6490 select ARCH_HAS_COPY_MC if X86_64
90 select ARCH_HAS_SET_MEMORY91 select ARCH_HAS_SET_MEMORY
@@ -130,7 +131,9 @@ config X86 · 39 unmodified lines
130 select CLKEVT_I8253131 select CLKEVT_I8253
131 select CLOCKSOURCE_VALIDATE_LAST_CYCLE132 select CLOCKSOURCE_VALIDATE_LAST_CYCLE
132 select CLOCKSOURCE_WATCHDOG133 select CLOCKSOURCE_WATCHDOG
133 select DCACHE_WORD_ACCESS134 # Word-size accesses may read uninitialized data past the trailing \0
135 # in strings and cause false KMSAN reports.
136 select DCACHE_WORD_ACCESS if !KMSAN
134 select DYNAMIC_SIGFRAME137 select DYNAMIC_SIGFRAME
135 select EDAC_ATOMIC_SCRUB138 select EDAC_ATOMIC_SCRUB
136 select EDAC_SUPPORT139 select EDAC_SUPPORT
@@ -168,6 +171,7 @@ config X86 · 31 unmodified lines
168 select HAVE_ARCH_KASAN if X86_64171 select HAVE_ARCH_KASAN if X86_64
169 select HAVE_ARCH_KASAN_VMALLOC if X86_64172 select HAVE_ARCH_KASAN_VMALLOC if X86_64
170 select HAVE_ARCH_KFENCE173 select HAVE_ARCH_KFENCE
174 select HAVE_ARCH_KMSAN if X86_64
171 select HAVE_ARCH_KGDB175 select HAVE_ARCH_KGDB
172 select HAVE_ARCH_MMAP_RND_BITS if MMU176 select HAVE_ARCH_MMAP_RND_BITS if MMU
173 select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT177 select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT
@@ -328,6 +332,10 @@ config GENERIC_ISA_DMA · 154 unmodified lines
328 def_bool y332 def_bool y
329 depends on ISA_DMA_API333 depends on ISA_DMA_API
330 334
335config GENERIC_CSUM
336 bool
337 default y if KMSAN || KASAN
338
331config GENERIC_BUG339config GENERIC_BUG
332 def_bool y340 def_bool y
333 depends on BUG341 depends on BUG
arch/x86/boot/Makefile+1−0
@@ -12,6 +12,7 @@ · 11 unmodified lines
12# Sanitizer runtimes are unavailable and cannot be linked for early boot code.12# Sanitizer runtimes are unavailable and cannot be linked for early boot code.
13KASAN_SANITIZE := n13KASAN_SANITIZE := n
14KCSAN_SANITIZE := n14KCSAN_SANITIZE := n
15KMSAN_SANITIZE := n
15OBJECT_FILES_NON_STANDARD := y16OBJECT_FILES_NON_STANDARD := y
16 17
17# Kernel does not boot with kcov instrumentation here.18# Kernel does not boot with kcov instrumentation here.
arch/x86/boot/compressed/Makefile+1−0
@@ -20,6 +20,7 @@ · 19 unmodified lines
20# Sanitizer runtimes are unavailable and cannot be linked for early boot code.20# Sanitizer runtimes are unavailable and cannot be linked for early boot code.
21KASAN_SANITIZE := n21KASAN_SANITIZE := n
22KCSAN_SANITIZE := n22KCSAN_SANITIZE := n
23KMSAN_SANITIZE := n
23OBJECT_FILES_NON_STANDARD := y24OBJECT_FILES_NON_STANDARD := y
24 25
25# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.26# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
arch/x86/entry/vdso/Makefile+3−0
@@ -11,6 +11,9 @@ include $(srctree)/lib/vdso/Makefile · 10 unmodified lines
11 11
12# Sanitizer runtimes are unavailable and cannot be linked here.12# Sanitizer runtimes are unavailable and cannot be linked here.
13KASAN_SANITIZE := n13KASAN_SANITIZE := n
14KMSAN_SANITIZE_vclock_gettime.o := n
15KMSAN_SANITIZE_vgetcpu.o := n
16
14UBSAN_SANITIZE := n17UBSAN_SANITIZE := n
15KCSAN_SANITIZE := n18KCSAN_SANITIZE := n
16OBJECT_FILES_NON_STANDARD := y19OBJECT_FILES_NON_STANDARD := y
arch/x86/entry/vdso/vma.c+5−4
@@ -127,17 +127,17 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns) · 126 unmodified lines
127{127{
128 struct mm_struct *mm = task->mm;128 struct mm_struct *mm = task->mm;
129 struct vm_area_struct *vma;129 struct vm_area_struct *vma;
130 VMA_ITERATOR(vmi, mm, 0);
130 131
131 mmap_read_lock(mm);132 mmap_read_lock(mm);
132 133 for_each_vma(vmi, vma) {
133 for (vma = mm->mmap; vma; vma = vma->vm_next) {
134 unsigned long size = vma->vm_end - vma->vm_start;134 unsigned long size = vma->vm_end - vma->vm_start;
135 135
136 if (vma_is_special_mapping(vma, &vvar_mapping))136 if (vma_is_special_mapping(vma, &vvar_mapping))
137 zap_page_range(vma, vma->vm_start, size);137 zap_page_range(vma, vma->vm_start, size);
138 }138 }
139
140 mmap_read_unlock(mm);139 mmap_read_unlock(mm);
140
141 return 0;141 return 0;
142}142}
143#else143#else
@@ -354,6 +354,7 @@ int map_vdso_once(const struct vdso_image *image, unsigned long addr) · 210 unmodified lines
354{354{
355 struct mm_struct *mm = current->mm;355 struct mm_struct *mm = current->mm;
356 struct vm_area_struct *vma;356 struct vm_area_struct *vma;
357 VMA_ITERATOR(vmi, mm, 0);
357 358
358 mmap_write_lock(mm);359 mmap_write_lock(mm);
359 /*360 /*
@@ -363,7 +364,7 @@ int map_vdso_once(const struct vdso_image *image, unsigned long addr) · 3 unmodified lines
363 * We could search vma near context.vdso, but it's a slowpath,364 * We could search vma near context.vdso, but it's a slowpath,
364 * so let's explicitly check all VMAs to be completely sure.365 * so let's explicitly check all VMAs to be completely sure.
365 */366 */
366 for (vma = mm->mmap; vma; vma = vma->vm_next) {367 for_each_vma(vmi, vma) {
367 if (vma_is_special_mapping(vma, &vdso_mapping) ||368 if (vma_is_special_mapping(vma, &vdso_mapping) ||
368 vma_is_special_mapping(vma, &vvar_mapping)) {369 vma_is_special_mapping(vma, &vvar_mapping)) {
369 mmap_write_unlock(mm);370 mmap_write_unlock(mm);
arch/x86/include/asm/checksum.h+10−6
@@ -1,9 +1,13 @@
1/* SPDX-License-Identifier: GPL-2.0 */1/* SPDX-License-Identifier: GPL-2.0 */
2#define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER 12#ifdef CONFIG_GENERIC_CSUM
3#define HAVE_CSUM_COPY_USER3# include <asm-generic/checksum.h>
4#define _HAVE_ARCH_CSUM_AND_COPY
5#ifdef CONFIG_X86_32
6# include <asm/checksum_32.h>
7#else4#else
8# include <asm/checksum_64.h>5# define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER 1
6# define HAVE_CSUM_COPY_USER
7# define _HAVE_ARCH_CSUM_AND_COPY
8# ifdef CONFIG_X86_32
9# include <asm/checksum_32.h>
10# else
11# include <asm/checksum_64.h>
12# endif
9#endif13#endif
arch/x86/include/asm/kmsan.h+87−0
@@ -0,0 +1,87 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * x86 KMSAN support.
4 *
5 * Copyright (C) 2022, Google LLC
6 * Author: Alexander Potapenko <glider@google.com>
7 */
8
9#ifndef _ASM_X86_KMSAN_H
10#define _ASM_X86_KMSAN_H
11
12#ifndef MODULE
13
14#include <asm/cpu_entry_area.h>
15#include <asm/processor.h>
16#include <linux/mmzone.h>
17
18DECLARE_PER_CPU(char[CPU_ENTRY_AREA_SIZE], cpu_entry_area_shadow);
19DECLARE_PER_CPU(char[CPU_ENTRY_AREA_SIZE], cpu_entry_area_origin);
20
21/*
22 * Functions below are declared in the header to make sure they are inlined.
23 * They all are called from kmsan_get_metadata() for every memory access in
24 * the kernel, so speed is important here.
25 */
26
27/*
28 * Compute metadata addresses for the CPU entry area on x86.
29 */
30static inline void *arch_kmsan_get_meta_or_null(void *addr, bool is_origin)
31{
32 unsigned long addr64 = (unsigned long)addr;
33 char *metadata_array;
34 unsigned long off;
35 int cpu;
36
37 if ((addr64 < CPU_ENTRY_AREA_BASE) ||
38 (addr64 >= (CPU_ENTRY_AREA_BASE + CPU_ENTRY_AREA_MAP_SIZE)))
39 return NULL;
40 cpu = (addr64 - CPU_ENTRY_AREA_BASE) / CPU_ENTRY_AREA_SIZE;
41 off = addr64 - (unsigned long)get_cpu_entry_area(cpu);
42 if ((off < 0) || (off >= CPU_ENTRY_AREA_SIZE))
43 return NULL;
44 metadata_array = is_origin ? cpu_entry_area_origin :
45 cpu_entry_area_shadow;
46 return &per_cpu(metadata_array[off], cpu);
47}
48
49/*
50 * Taken from arch/x86/mm/physaddr.h to avoid using an instrumented version.
51 */
52static inline bool kmsan_phys_addr_valid(unsigned long addr)
53{
54 if (IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT))
55 return !(addr >> boot_cpu_data.x86_phys_bits);
56 else
57 return true;
58}
59
60/*
61 * Taken from arch/x86/mm/physaddr.c to avoid using an instrumented version.
62 */
63static inline bool kmsan_virt_addr_valid(void *addr)
64{
65 unsigned long x = (unsigned long)addr;
66 unsigned long y = x - __START_KERNEL_map;
67
68 /* use the carry flag to determine if x was < __START_KERNEL_map */
69 if (unlikely(x > y)) {
70 x = y + phys_base;
71
72 if (y >= KERNEL_IMAGE_SIZE)
73 return false;
74 } else {
75 x = y + (__START_KERNEL_map - PAGE_OFFSET);
76
77 /* carry flag will be set if starting x was >= PAGE_OFFSET */
78 if ((x > y) || !kmsan_phys_addr_valid(x))
79 return false;
80 }
81
82 return pfn_valid(x >> PAGE_SHIFT);
83}
84
85#endif /* !MODULE */
86
87#endif /* _ASM_X86_KMSAN_H */
arch/x86/include/asm/page_64.h+7−0
@@ -8,6 +8,8 @@ · 7 unmodified lines
8#include <asm/cpufeatures.h>8#include <asm/cpufeatures.h>
9#include <asm/alternative.h>9#include <asm/alternative.h>
10 10
11#include <linux/kmsan-checks.h>
12
11/* duplicated to the one in bootmem.h */13/* duplicated to the one in bootmem.h */
12extern unsigned long max_pfn;14extern unsigned long max_pfn;
13extern unsigned long phys_base;15extern unsigned long phys_base;
@@ -47,6 +49,11 @@ void clear_page_erms(void *page); · 33 unmodified lines
47 49
48static inline void clear_page(void *page)50static inline void clear_page(void *page)
49{51{
52 /*
53 * Clean up KMSAN metadata for the page being cleared. The assembly call
54 * below clobbers @page, so we perform unpoisoning before it.
55 */
56 kmsan_unpoison_memory(page, PAGE_SIZE);
50 alternative_call_2(clear_page_orig,57 alternative_call_2(clear_page_orig,
51 clear_page_rep, X86_FEATURE_REP_GOOD,58 clear_page_rep, X86_FEATURE_REP_GOOD,
52 clear_page_erms, X86_FEATURE_ERMS,59 clear_page_erms, X86_FEATURE_ERMS,
arch/x86/include/asm/pgtable-3level.h+4−4
@@ -256,10 +256,10 @@ static inline pud_t native_pudp_get_and_clear(pud_t *pudp) · 255 unmodified lines
256/* We always extract/encode the offset by shifting it all the way up, and then down again */256/* We always extract/encode the offset by shifting it all the way up, and then down again */
257#define SWP_OFFSET_SHIFT (SWP_OFFSET_FIRST_BIT + SWP_TYPE_BITS)257#define SWP_OFFSET_SHIFT (SWP_OFFSET_FIRST_BIT + SWP_TYPE_BITS)
258 258
259#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > 5)259#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS)
260#define __swp_type(x) (((x).val) & 0x1f)260#define __swp_type(x) (((x).val) & ((1UL << SWP_TYPE_BITS) - 1))
261#define __swp_offset(x) ((x).val >> 5)261#define __swp_offset(x) ((x).val >> SWP_TYPE_BITS)
262#define __swp_entry(type, offset) ((swp_entry_t){(type) | (offset) << 5})262#define __swp_entry(type, offset) ((swp_entry_t){(type) | (offset) << SWP_TYPE_BITS})
263 263
264/*264/*
265 * Normally, __swp_entry() converts from arch-independent swp_entry_t to265 * Normally, __swp_entry() converts from arch-independent swp_entry_t to
arch/x86/include/asm/pgtable.h+5−4
@@ -815,7 +815,8 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd) · 814 unmodified lines
815 815
816static inline int pmd_bad(pmd_t pmd)816static inline int pmd_bad(pmd_t pmd)
817{817{
818 return (pmd_flags(pmd) & ~_PAGE_USER) != _KERNPG_TABLE;818 return (pmd_flags(pmd) & ~(_PAGE_USER | _PAGE_ACCESSED)) !=
819 (_KERNPG_TABLE & ~_PAGE_ACCESSED);
819}820}
820 821
821static inline unsigned long pages_to_mb(unsigned long npg)822static inline unsigned long pages_to_mb(unsigned long npg)
@@ -1431,10 +1432,10 @@ static inline bool arch_has_pfn_modify_check(void) · 609 unmodified lines
1431 return boot_cpu_has_bug(X86_BUG_L1TF);1432 return boot_cpu_has_bug(X86_BUG_L1TF);
1432}1433}
1433 1434
1434#define arch_faults_on_old_pte arch_faults_on_old_pte1435#define arch_has_hw_pte_young arch_has_hw_pte_young
1435static inline bool arch_faults_on_old_pte(void)1436static inline bool arch_has_hw_pte_young(void)
1436{1437{
1437 return false;1438 return true;
1438}1439}
1439 1440
1440#ifdef CONFIG_PAGE_TABLE_CHECK1441#ifdef CONFIG_PAGE_TABLE_CHECK
arch/x86/include/asm/pgtable_64_types.h+46−1
@@ -139,7 +139,52 @@ extern unsigned int ptrs_per_p4d; · 138 unmodified lines
139# define VMEMMAP_START __VMEMMAP_BASE_L4139# define VMEMMAP_START __VMEMMAP_BASE_L4
140#endif /* CONFIG_DYNAMIC_MEMORY_LAYOUT */140#endif /* CONFIG_DYNAMIC_MEMORY_LAYOUT */
141 141
142#define VMALLOC_END (VMALLOC_START + (VMALLOC_SIZE_TB << 40) - 1)142/*
143 * End of the region for which vmalloc page tables are pre-allocated.
144 * For non-KMSAN builds, this is the same as VMALLOC_END.
145 * For KMSAN builds, VMALLOC_START..VMEMORY_END is 4 times bigger than
146 * VMALLOC_START..VMALLOC_END (see below).
147 */
148#define VMEMORY_END (VMALLOC_START + (VMALLOC_SIZE_TB << 40) - 1)
149
150#ifndef CONFIG_KMSAN
151#define VMALLOC_END VMEMORY_END
152#else
153/*
154 * In KMSAN builds vmalloc area is four times smaller, and the remaining 3/4
155 * are used to keep the metadata for virtual pages. The memory formerly
156 * belonging to vmalloc area is now laid out as follows:
157 *
158 * 1st quarter: VMALLOC_START to VMALLOC_END - new vmalloc area
159 * 2nd quarter: KMSAN_VMALLOC_SHADOW_START to
160 * VMALLOC_END+KMSAN_VMALLOC_SHADOW_OFFSET - vmalloc area shadow
161 * 3rd quarter: KMSAN_VMALLOC_ORIGIN_START to
162 * VMALLOC_END+KMSAN_VMALLOC_ORIGIN_OFFSET - vmalloc area origins
163 * 4th quarter: KMSAN_MODULES_SHADOW_START to KMSAN_MODULES_ORIGIN_START
164 * - shadow for modules,
165 * KMSAN_MODULES_ORIGIN_START to
166 * KMSAN_MODULES_ORIGIN_START + MODULES_LEN - origins for modules.
167 */
168#define VMALLOC_QUARTER_SIZE ((VMALLOC_SIZE_TB << 40) >> 2)
169#define VMALLOC_END (VMALLOC_START + VMALLOC_QUARTER_SIZE - 1)
170
171/*
172 * vmalloc metadata addresses are calculated by adding shadow/origin offsets
173 * to vmalloc address.
174 */
175#define KMSAN_VMALLOC_SHADOW_OFFSET VMALLOC_QUARTER_SIZE
176#define KMSAN_VMALLOC_ORIGIN_OFFSET (VMALLOC_QUARTER_SIZE << 1)
177
178#define KMSAN_VMALLOC_SHADOW_START (VMALLOC_START + KMSAN_VMALLOC_SHADOW_OFFSET)
179#define KMSAN_VMALLOC_ORIGIN_START (VMALLOC_START + KMSAN_VMALLOC_ORIGIN_OFFSET)
180
181/*
182 * The shadow/origin for modules are placed one by one in the last 1/4 of
183 * vmalloc space.
184 */
185#define KMSAN_MODULES_SHADOW_START (VMALLOC_END + KMSAN_VMALLOC_ORIGIN_OFFSET + 1)
186#define KMSAN_MODULES_ORIGIN_START (KMSAN_MODULES_SHADOW_START + MODULES_LEN)
187#endif /* CONFIG_KMSAN */
143 188
144#define MODULES_VADDR (__START_KERNEL_map + KERNEL_IMAGE_SIZE)189#define MODULES_VADDR (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
145/* The module sections ends with the start of the fixmap */190/* The module sections ends with the start of the fixmap */
arch/x86/include/asm/sparsemem.h+2−0
@@ -2,6 +2,8 @@ · 1 unmodified line
2#ifndef _ASM_X86_SPARSEMEM_H2#ifndef _ASM_X86_SPARSEMEM_H
3#define _ASM_X86_SPARSEMEM_H3#define _ASM_X86_SPARSEMEM_H
4 4
5#include <linux/types.h>
6
5#ifdef CONFIG_SPARSEMEM7#ifdef CONFIG_SPARSEMEM
6/*8/*
7 * generic non-linear memory support:9 * generic non-linear memory support:
arch/x86/include/asm/string_64.h+21−2
@@ -11,11 +11,23 @@ · 10 unmodified lines
11 function. */11 function. */
12 12
13#define __HAVE_ARCH_MEMCPY 113#define __HAVE_ARCH_MEMCPY 1
14#if defined(__SANITIZE_MEMORY__)
15#undef memcpy
16void *__msan_memcpy(void *dst, const void *src, size_t size);
17#define memcpy __msan_memcpy
18#else
14extern void *memcpy(void *to, const void *from, size_t len);19extern void *memcpy(void *to, const void *from, size_t len);
20#endif
15extern void *__memcpy(void *to, const void *from, size_t len);21extern void *__memcpy(void *to, const void *from, size_t len);
16 22
17#define __HAVE_ARCH_MEMSET23#define __HAVE_ARCH_MEMSET
24#if defined(__SANITIZE_MEMORY__)
25extern void *__msan_memset(void *s, int c, size_t n);
26#undef memset
27#define memset __msan_memset
28#else
18void *memset(void *s, int c, size_t n);29void *memset(void *s, int c, size_t n);
30#endif
19void *__memset(void *s, int c, size_t n);31void *__memset(void *s, int c, size_t n);
20 32
21#define __HAVE_ARCH_MEMSET1633#define __HAVE_ARCH_MEMSET16
@@ -55,7 +67,13 @@ static inline void *memset64(uint64_t *s, uint64_t v, size_t n) · 33 unmodified lines
55}67}
56 68
57#define __HAVE_ARCH_MEMMOVE69#define __HAVE_ARCH_MEMMOVE
70#if defined(__SANITIZE_MEMORY__)
71#undef memmove
72void *__msan_memmove(void *dest, const void *src, size_t len);
73#define memmove __msan_memmove
74#else
58void *memmove(void *dest, const void *src, size_t count);75void *memmove(void *dest, const void *src, size_t count);
76#endif
59void *__memmove(void *dest, const void *src, size_t count);77void *__memmove(void *dest, const void *src, size_t count);
60 78
61int memcmp(const void *cs, const void *ct, size_t count);79int memcmp(const void *cs, const void *ct, size_t count);
@@ -64,8 +82,7 @@ char *strcpy(char *dest, const char *src); · 2 unmodified lines
64char *strcat(char *dest, const char *src);82char *strcat(char *dest, const char *src);
65int strcmp(const char *cs, const char *ct);83int strcmp(const char *cs, const char *ct);
66 84
67#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)85#if (defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__))
68
69/*86/*
70 * For files that not instrumented (e.g. mm/slub.c) we87 * For files that not instrumented (e.g. mm/slub.c) we
71 * should use not instrumented version of mem* functions.88 * should use not instrumented version of mem* functions.
@@ -73,7 +90,9 @@ int strcmp(const char *cs, const char *ct); · 1 unmodified line
73 90
74#undef memcpy91#undef memcpy
75#define memcpy(dst, src, len) __memcpy(dst, src, len)92#define memcpy(dst, src, len) __memcpy(dst, src, len)
93#undef memmove
76#define memmove(dst, src, len) __memmove(dst, src, len)94#define memmove(dst, src, len) __memmove(dst, src, len)
95#undef memset
77#define memset(s, c, n) __memset(s, c, n)96#define memset(s, c, n) __memset(s, c, n)
78 97
79#ifndef __NO_FORTIFY98#ifndef __NO_FORTIFY
arch/x86/include/asm/uaccess.h+15−7
@@ -5,6 +5,7 @@ · 4 unmodified lines
5 * User space memory access functions5 * User space memory access functions
6 */6 */
7#include <linux/compiler.h>7#include <linux/compiler.h>
8#include <linux/instrumented.h>
8#include <linux/kasan-checks.h>9#include <linux/kasan-checks.h>
9#include <linux/string.h>10#include <linux/string.h>
10#include <asm/asm.h>11#include <asm/asm.h>
@@ -103,6 +104,7 @@ extern int __get_user_bad(void); · 92 unmodified lines
103 : "=a" (__ret_gu), "=r" (__val_gu), \104 : "=a" (__ret_gu), "=r" (__val_gu), \
104 ASM_CALL_CONSTRAINT \105 ASM_CALL_CONSTRAINT \
105 : "0" (ptr), "i" (sizeof(*(ptr)))); \106 : "0" (ptr), "i" (sizeof(*(ptr)))); \
107 instrument_get_user(__val_gu); \
106 (x) = (__force __typeof__(*(ptr))) __val_gu; \108 (x) = (__force __typeof__(*(ptr))) __val_gu; \
107 __builtin_expect(__ret_gu, 0); \109 __builtin_expect(__ret_gu, 0); \
108})110})
@@ -192,9 +194,11 @@ extern void __put_user_nocheck_8(void); · 83 unmodified lines
192 int __ret_pu; \194 int __ret_pu; \
193 void __user *__ptr_pu; \195 void __user *__ptr_pu; \
194 register __typeof__(*(ptr)) __val_pu asm("%"_ASM_AX); \196 register __typeof__(*(ptr)) __val_pu asm("%"_ASM_AX); \
195 __chk_user_ptr(ptr); \197 __typeof__(*(ptr)) __x = (x); /* eval x once */ \
196 __ptr_pu = (ptr); \198 __typeof__(ptr) __ptr = (ptr); /* eval ptr once */ \
197 __val_pu = (x); \199 __chk_user_ptr(__ptr); \
200 __ptr_pu = __ptr; \
201 __val_pu = __x; \
198 asm volatile("call __" #fn "_%P[size]" \202 asm volatile("call __" #fn "_%P[size]" \
199 : "=c" (__ret_pu), \203 : "=c" (__ret_pu), \
200 ASM_CALL_CONSTRAINT \204 ASM_CALL_CONSTRAINT \
@@ -202,6 +206,7 @@ extern void __put_user_nocheck_8(void); · 1 unmodified line
202 "r" (__val_pu), \206 "r" (__val_pu), \
203 [size] "i" (sizeof(*(ptr))) \207 [size] "i" (sizeof(*(ptr))) \
204 :"ebx"); \208 :"ebx"); \
209 instrument_put_user(__x, __ptr, sizeof(*(ptr))); \
205 __builtin_expect(__ret_pu, 0); \210 __builtin_expect(__ret_pu, 0); \
206})211})
207 212
@@ -248,23 +253,25 @@ extern void __put_user_nocheck_8(void); · 40 unmodified lines
248 253
249#define __put_user_size(x, ptr, size, label) \254#define __put_user_size(x, ptr, size, label) \
250do { \255do { \
256 __typeof__(*(ptr)) __x = (x); /* eval x once */ \
251 __chk_user_ptr(ptr); \257 __chk_user_ptr(ptr); \
252 switch (size) { \258 switch (size) { \
253 case 1: \259 case 1: \
254 __put_user_goto(x, ptr, "b", "iq", label); \260 __put_user_goto(__x, ptr, "b", "iq", label); \
255 break; \261 break; \
256 case 2: \262 case 2: \
257 __put_user_goto(x, ptr, "w", "ir", label); \263 __put_user_goto(__x, ptr, "w", "ir", label); \
258 break; \264 break; \
259 case 4: \265 case 4: \
260 __put_user_goto(x, ptr, "l", "ir", label); \266 __put_user_goto(__x, ptr, "l", "ir", label); \
261 break; \267 break; \
262 case 8: \268 case 8: \
263 __put_user_goto_u64(x, ptr, label); \269 __put_user_goto_u64(__x, ptr, label); \
264 break; \270 break; \
265 default: \271 default: \
266 __put_user_bad(); \272 __put_user_bad(); \
267 } \273 } \
274 instrument_put_user(__x, ptr, size); \
268} while (0)275} while (0)
269 276
270#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT277#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
@@ -305,6 +312,7 @@ do { \ · 34 unmodified lines
305 default: \312 default: \
306 (x) = __get_user_bad(); \313 (x) = __get_user_bad(); \
307 } \314 } \
315 instrument_get_user(x); \
308} while (0)316} while (0)
309 317
310#define __get_user_asm(x, addr, itype, ltype, label) \318#define __get_user_asm(x, addr, itype, ltype, label) \
arch/x86/kernel/Makefile+2−0
@@ -29,6 +29,8 @@ KASAN_SANITIZE_sev.o := n · 28 unmodified lines
29# With some compiler versions the generated code results in boot hangs, caused29# With some compiler versions the generated code results in boot hangs, caused
30# by several compilation units. To be safe, disable all instrumentation.30# by several compilation units. To be safe, disable all instrumentation.
31KCSAN_SANITIZE := n31KCSAN_SANITIZE := n
32KMSAN_SANITIZE_head$(BITS).o := n
33KMSAN_SANITIZE_nmi.o := n
32 34
33# If instrumentation of this dir is enabled, boot hangs during first second.35# If instrumentation of this dir is enabled, boot hangs during first second.
34# Probably could be more selective here, but note that files related to irqs,36# Probably could be more selective here, but note that files related to irqs,
arch/x86/kernel/cpu/Makefile+1−0
@@ -12,6 +12,7 @@ endif · 11 unmodified lines
12# If these files are instrumented, boot hangs during the first second.12# If these files are instrumented, boot hangs during the first second.
13KCOV_INSTRUMENT_common.o := n13KCOV_INSTRUMENT_common.o := n
14KCOV_INSTRUMENT_perf_event.o := n14KCOV_INSTRUMENT_perf_event.o := n
15KMSAN_SANITIZE_common.o := n
15 16
16# As above, instrumenting secondary CPU boot code causes boot hangs.17# As above, instrumenting secondary CPU boot code causes boot hangs.
17KCSAN_SANITIZE_common.o := n18KCSAN_SANITIZE_common.o := n
arch/x86/kernel/dumpstack.c+6−0
@@ -177,6 +177,12 @@ static void show_regs_if_on_stack(struct stack_info *info, struct pt_regs *regs, · 176 unmodified lines
177 }177 }
178}178}
179 179
180/*
181 * This function reads pointers from the stack and dereferences them. The
182 * pointers may not have their KMSAN shadow set up properly, which may result
183 * in false positive reports. Disable instrumentation to avoid those.
184 */
185__no_kmsan_checks
180static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,186static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
181 unsigned long *stack, const char *log_lvl)187 unsigned long *stack, const char *log_lvl)
182{188{
arch/x86/kernel/process_64.c+1−0
@@ -553,6 +553,7 @@ void compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp, bool x32) · 552 unmodified lines
553 * Kprobes not supported here. Set the probe on schedule instead.553 * Kprobes not supported here. Set the probe on schedule instead.
554 * Function graph tracer not supported too.554 * Function graph tracer not supported too.
555 */555 */
556__no_kmsan_checks
556__visible __notrace_funcgraph struct task_struct *557__visible __notrace_funcgraph struct task_struct *
557__switch_to(struct task_struct *prev_p, struct task_struct *next_p)558__switch_to(struct task_struct *prev_p, struct task_struct *next_p)
558{559{
arch/x86/kernel/tboot.c+1−1
@@ -95,7 +95,7 @@ void __init tboot_probe(void) · 94 unmodified lines
95 95
96static pgd_t *tboot_pg_dir;96static pgd_t *tboot_pg_dir;
97static struct mm_struct tboot_mm = {97static struct mm_struct tboot_mm = {
98 .mm_rb = RB_ROOT,98 .mm_mt = MTREE_INIT_EXT(mm_mt, MM_MT_FLAGS, tboot_mm.mmap_lock),
99 .pgd = swapper_pg_dir,99 .pgd = swapper_pg_dir,
100 .mm_users = ATOMIC_INIT(2),100 .mm_users = ATOMIC_INIT(2),
101 .mm_count = ATOMIC_INIT(1),101 .mm_count = ATOMIC_INIT(1),
arch/x86/kernel/unwind_frame.c+11−0
@@ -183,6 +183,16 @@ static struct pt_regs *decode_frame_pointer(unsigned long *bp) · 182 unmodified lines
183}183}
184#endif184#endif
185 185
186/*
187 * While walking the stack, KMSAN may stomp on stale locals from other
188 * functions that were marked as uninitialized upon function exit, and
189 * now hold the call frame information for the current function (e.g. the frame
190 * pointer). Because KMSAN does not specifically mark call frames as
191 * initialized, false positive reports are possible. To prevent such reports,
192 * we mark the functions scanning the stack (here and below) with
193 * __no_kmsan_checks.
194 */
195__no_kmsan_checks
186static bool update_stack_state(struct unwind_state *state,196static bool update_stack_state(struct unwind_state *state,
187 unsigned long *next_bp)197 unsigned long *next_bp)
188{198{
@@ -250,6 +260,7 @@ static bool update_stack_state(struct unwind_state *state, · 61 unmodified lines
250 return true;260 return true;
251}261}
252 262
263__no_kmsan_checks
253bool unwind_next_frame(struct unwind_state *state)264bool unwind_next_frame(struct unwind_state *state)
254{265{
255 struct pt_regs *regs;266 struct pt_regs *regs;
arch/x86/lib/Makefile+2−0
@@ -65,7 +65,9 @@ ifneq ($(CONFIG_X86_CMPXCHG64),y) · 64 unmodified lines
65endif65endif
66else66else
67 obj-y += iomap_copy_64.o67 obj-y += iomap_copy_64.o
68ifneq ($(CONFIG_GENERIC_CSUM),y)
68 lib-y += csum-partial_64.o csum-copy_64.o csum-wrappers_64.o69 lib-y += csum-partial_64.o csum-copy_64.o csum-wrappers_64.o
70endif
69 lib-y += clear_page_64.o copy_page_64.o71 lib-y += clear_page_64.o copy_page_64.o
70 lib-y += memmove_64.o memset_64.o72 lib-y += memmove_64.o memset_64.o
71 lib-y += copy_user_64.o73 lib-y += copy_user_64.o
arch/x86/lib/iomem.c+5−0
@@ -1,6 +1,7 @@
1#include <linux/string.h>1#include <linux/string.h>
2#include <linux/module.h>2#include <linux/module.h>
3#include <linux/io.h>3#include <linux/io.h>
4#include <linux/kmsan-checks.h>
4 5
5#define movs(type,to,from) \6#define movs(type,to,from) \
6 asm volatile("movs" type:"=&D" (to), "=&S" (from):"0" (to), "1" (from):"memory")7 asm volatile("movs" type:"=&D" (to), "=&S" (from):"0" (to), "1" (from):"memory")
@@ -37,6 +38,8 @@ static void string_memcpy_fromio(void *to, const volatile void __iomem *from, si · 30 unmodified lines
37 n-=2;38 n-=2;
38 }39 }
39 rep_movs(to, (const void *)from, n);40 rep_movs(to, (const void *)from, n);
41 /* KMSAN must treat values read from devices as initialized. */
42 kmsan_unpoison_memory(to, n);
40}43}
41 44
42static void string_memcpy_toio(volatile void __iomem *to, const void *from, size_t n)45static void string_memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
@@ -44,6 +47,8 @@ static void string_memcpy_toio(volatile void __iomem *to, const void *from, size · 1 unmodified line
44 if (unlikely(!n))47 if (unlikely(!n))
45 return;48 return;
46 49
50 /* Make sure uninitialized memory isn't copied to devices. */
51 kmsan_check_memory(from, n);
47 /* Align any unaligned destination IO */52 /* Align any unaligned destination IO */
48 if (unlikely(1 & (unsigned long)to)) {53 if (unlikely(1 & (unsigned long)to)) {
49 movs("b", to, from);54 movs("b", to, from);
arch/x86/mm/Makefile+5−0
@@ -14,6 +14,8 @@ KASAN_SANITIZE_pgprot.o := n · 13 unmodified lines
14# Disable KCSAN entirely, because otherwise we get warnings that some functions14# Disable KCSAN entirely, because otherwise we get warnings that some functions
15# reference __initdata sections.15# reference __initdata sections.
16KCSAN_SANITIZE := n16KCSAN_SANITIZE := n
17# Avoid recursion by not calling KMSAN hooks for CEA code.
18KMSAN_SANITIZE_cpu_entry_area.o := n
17 19
18ifdef CONFIG_FUNCTION_TRACER20ifdef CONFIG_FUNCTION_TRACER
19CFLAGS_REMOVE_mem_encrypt.o = -pg21CFLAGS_REMOVE_mem_encrypt.o = -pg
@@ -44,6 +46,9 @@ obj-$(CONFIG_HIGHMEM) += highmem_32.o · 24 unmodified lines
44KASAN_SANITIZE_kasan_init_$(BITS).o := n46KASAN_SANITIZE_kasan_init_$(BITS).o := n
45obj-$(CONFIG_KASAN) += kasan_init_$(BITS).o47obj-$(CONFIG_KASAN) += kasan_init_$(BITS).o
46 48
49KMSAN_SANITIZE_kmsan_shadow.o := n
50obj-$(CONFIG_KMSAN) += kmsan_shadow.o
51
47obj-$(CONFIG_MMIOTRACE) += mmiotrace.o52obj-$(CONFIG_MMIOTRACE) += mmiotrace.o
48mmiotrace-y := kmmio.o pf_in.o mmio-mod.o53mmiotrace-y := kmmio.o pf_in.o mmio-mod.o
49obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o54obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o
arch/x86/mm/fault.c+22−1
@@ -260,7 +260,7 @@ static noinline int vmalloc_fault(unsigned long address) · 259 unmodified lines
260}260}
261NOKPROBE_SYMBOL(vmalloc_fault);261NOKPROBE_SYMBOL(vmalloc_fault);
262 262
263void arch_sync_kernel_mappings(unsigned long start, unsigned long end)263static void __arch_sync_kernel_mappings(unsigned long start, unsigned long end)
264{264{
265 unsigned long addr;265 unsigned long addr;
266 266
@@ -284,6 +284,27 @@ void arch_sync_kernel_mappings(unsigned long start, unsigned long end) · 17 unmodified lines
284 }284 }
285}285}
286 286
287void arch_sync_kernel_mappings(unsigned long start, unsigned long end)
288{
289 __arch_sync_kernel_mappings(start, end);
290#ifdef CONFIG_KMSAN
291 /*
292 * KMSAN maintains two additional metadata page mappings for the
293 * [VMALLOC_START, VMALLOC_END) range. These mappings start at
294 * KMSAN_VMALLOC_SHADOW_START and KMSAN_VMALLOC_ORIGIN_START and
295 * have to be synced together with the vmalloc memory mapping.
296 */
297 if (start >= VMALLOC_START && end < VMALLOC_END) {
298 __arch_sync_kernel_mappings(
299 start - VMALLOC_START + KMSAN_VMALLOC_SHADOW_START,
300 end - VMALLOC_START + KMSAN_VMALLOC_SHADOW_START);
301 __arch_sync_kernel_mappings(
302 start - VMALLOC_START + KMSAN_VMALLOC_ORIGIN_START,
303 end - VMALLOC_START + KMSAN_VMALLOC_ORIGIN_START);
304 }
305#endif
306}
307
287static bool low_pfn(unsigned long pfn)308static bool low_pfn(unsigned long pfn)
288{309{
289 return pfn < max_low_pfn;310 return pfn < max_low_pfn;
arch/x86/mm/init.c+1−1
@@ -1054,7 +1054,7 @@ void update_cache_mode_entry(unsigned entry, enum page_cache_mode cache) · 1053 unmodified lines
1054}1054}
1055 1055
1056#ifdef CONFIG_SWAP1056#ifdef CONFIG_SWAP
1057unsigned long max_swapfile_size(void)1057unsigned long arch_max_swapfile_size(void)
1058{1058{
1059 unsigned long pages;1059 unsigned long pages;
1060 1060
arch/x86/mm/init_64.c+1−1
@@ -1288,7 +1288,7 @@ static void __init preallocate_vmalloc_pages(void) · 1287 unmodified lines
1288 unsigned long addr;1288 unsigned long addr;
1289 const char *lvl;1289 const char *lvl;
1290 1290
1291 for (addr = VMALLOC_START; addr <= VMALLOC_END; addr = ALIGN(addr + 1, PGDIR_SIZE)) {1291 for (addr = VMALLOC_START; addr <= VMEMORY_END; addr = ALIGN(addr + 1, PGDIR_SIZE)) {
1292 pgd_t *pgd = pgd_offset_k(addr);1292 pgd_t *pgd = pgd_offset_k(addr);
1293 p4d_t *p4d;1293 p4d_t *p4d;
1294 pud_t *pud;1294 pud_t *pud;
arch/x86/mm/ioremap.c+3−0
@@ -17,6 +17,7 @@ · 16 unmodified lines
17#include <linux/cc_platform.h>17#include <linux/cc_platform.h>
18#include <linux/efi.h>18#include <linux/efi.h>
19#include <linux/pgtable.h>19#include <linux/pgtable.h>
20#include <linux/kmsan.h>
20 21
21#include <asm/set_memory.h>22#include <asm/set_memory.h>
22#include <asm/e820/api.h>23#include <asm/e820/api.h>
@@ -479,6 +480,8 @@ void iounmap(volatile void __iomem *addr) · 456 unmodified lines
479 return;480 return;
480 }481 }
481 482
483 kmsan_iounmap_page_range((unsigned long)addr,
484 (unsigned long)addr + get_vm_area_size(p));
482 memtype_free(p->phys_addr, p->phys_addr + get_vm_area_size(p));485 memtype_free(p->phys_addr, p->phys_addr + get_vm_area_size(p));
483 486
484 /* Finally remove it */487 /* Finally remove it */
arch/x86/mm/kmsan_shadow.c+20−0
@@ -0,0 +1,20 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * x86-specific bits of KMSAN shadow implementation.
4 *
5 * Copyright (C) 2022 Google LLC
6 * Author: Alexander Potapenko <glider@google.com>
7 */
8
9#include <asm/cpu_entry_area.h>
10#include <linux/percpu-defs.h>
11
12/*
13 * Addresses within the CPU entry area (including e.g. exception stacks) do not
14 * have struct page entries corresponding to them, so they need separate
15 * handling.
16 * arch_kmsan_get_meta_or_null() (declared in the header) maps the addresses in
17 * CPU entry area to addresses in cpu_entry_area_shadow/cpu_entry_area_origin.
18 */
19DEFINE_PER_CPU(char[CPU_ENTRY_AREA_SIZE], cpu_entry_area_shadow);
20DEFINE_PER_CPU(char[CPU_ENTRY_AREA_SIZE], cpu_entry_area_origin);
arch/x86/mm/pgtable.c+4−1
@@ -550,7 +550,7 @@ int ptep_test_and_clear_young(struct vm_area_struct *vma, · 549 unmodified lines
550 return ret;550 return ret;
551}551}
552 552
553#ifdef CONFIG_TRANSPARENT_HUGEPAGE553#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)
554int pmdp_test_and_clear_young(struct vm_area_struct *vma,554int pmdp_test_and_clear_young(struct vm_area_struct *vma,
555 unsigned long addr, pmd_t *pmdp)555 unsigned long addr, pmd_t *pmdp)
556{556{
@@ -562,6 +562,9 @@ int pmdp_test_and_clear_young(struct vm_area_struct *vma, · 5 unmodified lines
562 562
563 return ret;563 return ret;
564}564}
565#endif
566
567#ifdef CONFIG_TRANSPARENT_HUGEPAGE
565int pudp_test_and_clear_young(struct vm_area_struct *vma,568int pudp_test_and_clear_young(struct vm_area_struct *vma,
566 unsigned long addr, pud_t *pudp)569 unsigned long addr, pud_t *pudp)
567{570{
arch/x86/realmode/rm/Makefile+1−0
@@ -10,6 +10,7 @@ · 9 unmodified lines
10# Sanitizer runtimes are unavailable and cannot be linked here.10# Sanitizer runtimes are unavailable and cannot be linked here.
11KASAN_SANITIZE := n11KASAN_SANITIZE := n
12KCSAN_SANITIZE := n12KCSAN_SANITIZE := n
13KMSAN_SANITIZE := n
13OBJECT_FILES_NON_STANDARD := y14OBJECT_FILES_NON_STANDARD := y
14 15
15# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.16# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
arch/xtensa/Kconfig+1−1
@@ -771,7 +771,7 @@ config HIGHMEM · 770 unmodified lines
771 771
772 If unsure, say Y.772 If unsure, say Y.
773 773
774config FORCE_MAX_ZONEORDER774config ARCH_FORCE_MAX_ORDER
775 int "Maximum zone order"775 int "Maximum zone order"
776 default "11"776 default "11"
777 help777 help
arch/xtensa/include/uapi/asm/mman.h+2−0
@@ -111,6 +111,8 @@ · 110 unmodified lines
111 111
112#define MADV_DONTNEED_LOCKED 24 /* like DONTNEED, but drop locked pages too */112#define MADV_DONTNEED_LOCKED 24 /* like DONTNEED, but drop locked pages too */
113 113
114#define MADV_COLLAPSE 25 /* Synchronous hugepage collapse */
115
114/* compatibility flags */116/* compatibility flags */
115#define MAP_FILE 0117#define MAP_FILE 0
116 118
arch/xtensa/kernel/syscall.c+12−6
@@ -58,6 +58,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, · 57 unmodified lines
58 unsigned long len, unsigned long pgoff, unsigned long flags)58 unsigned long len, unsigned long pgoff, unsigned long flags)
59{59{
60 struct vm_area_struct *vmm;60 struct vm_area_struct *vmm;
61 struct vma_iterator vmi;
61 62
62 if (flags & MAP_FIXED) {63 if (flags & MAP_FIXED) {
63 /* We do not accept a shared mapping if it would violate64 /* We do not accept a shared mapping if it would violate
@@ -79,15 +80,20 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, · 15 unmodified lines
79 else80 else
80 addr = PAGE_ALIGN(addr);81 addr = PAGE_ALIGN(addr);
81 82
82 for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {83 vma_iter_init(&vmi, current->mm, addr);
83 /* At this point: (!vmm || addr < vmm->vm_end). */84 for_each_vma(vmi, vmm) {
84 if (TASK_SIZE - len < addr)85 /* At this point: (addr < vmm->vm_end). */
85 return -ENOMEM;86 if (addr + len <= vm_start_gap(vmm))
86 if (!vmm || addr + len <= vm_start_gap(vmm))87 break;
87 return addr;88
88 addr = vmm->vm_end;89 addr = vmm->vm_end;
89 if (flags & MAP_SHARED)90 if (flags & MAP_SHARED)
90 addr = COLOUR_ALIGN(addr, pgoff);91 addr = COLOUR_ALIGN(addr, pgoff);
91 }92 }
93
94 if (TASK_SIZE - len < addr)
95 return -ENOMEM;
96
97 return addr;
92}98}
93#endif99#endif
block/bio.c+2−0
@@ -867,6 +867,8 @@ static inline bool page_is_mergeable(const struct bio_vec *bv, · 866 unmodified lines
867 *same_page = ((vec_end_addr & PAGE_MASK) == page_addr);867 *same_page = ((vec_end_addr & PAGE_MASK) == page_addr);
868 if (*same_page)868 if (*same_page)
869 return true;869 return true;
870 else if (IS_ENABLED(CONFIG_KMSAN))
871 return false;
870 return (bv->bv_page + bv_end / PAGE_SIZE) == (page + off / PAGE_SIZE);872 return (bv->bv_page + bv_end / PAGE_SIZE) == (page + off / PAGE_SIZE);
871}873}
872 874
block/blk.h+7−0
@@ -88,6 +88,13 @@ static inline bool biovec_phys_mergeable(struct request_queue *q, · 87 unmodified lines
88 phys_addr_t addr1 = page_to_phys(vec1->bv_page) + vec1->bv_offset;88 phys_addr_t addr1 = page_to_phys(vec1->bv_page) + vec1->bv_offset;
89 phys_addr_t addr2 = page_to_phys(vec2->bv_page) + vec2->bv_offset;89 phys_addr_t addr2 = page_to_phys(vec2->bv_page) + vec2->bv_offset;
90 90
91 /*
92 * Merging adjacent physical pages may not work correctly under KMSAN
93 * if their metadata pages aren't adjacent. Just disable merging.
94 */
95 if (IS_ENABLED(CONFIG_KMSAN))
96 return false;
97
91 if (addr1 + vec1->bv_len != addr2)98 if (addr1 + vec1->bv_len != addr2)
92 return false;99 return false;
93 if (xen_domain() && !xen_biovec_phys_mergeable(vec1, vec2->bv_page))100 if (xen_domain() && !xen_biovec_phys_mergeable(vec1, vec2->bv_page))
crypto/Kconfig+2−0
@@ -1391,6 +1391,7 @@ endmenu · 1390 unmodified lines
1391config CRYPTO_HASH_INFO1391config CRYPTO_HASH_INFO
1392 bool1392 bool
1393 1393
1394if !KMSAN # avoid false positives from assembly
1394if ARM1395if ARM
1395source "arch/arm/crypto/Kconfig"1396source "arch/arm/crypto/Kconfig"
1396endif1397endif
@@ -1412,6 +1413,7 @@ endif · 15 unmodified lines
1412if X861413if X86
1413source "arch/x86/crypto/Kconfig"1414source "arch/x86/crypto/Kconfig"
1414endif1415endif
1416endif
1415 1417
1416source "drivers/crypto/Kconfig"1418source "drivers/crypto/Kconfig"
1417source "crypto/asymmetric_keys/Kconfig"1419source "crypto/asymmetric_keys/Kconfig"
drivers/base/memory.c+0−6
@@ -869,12 +869,6 @@ void remove_memory_block_devices(unsigned long start, unsigned long size) · 868 unmodified lines
869 }869 }
870}870}
871 871
872/* return true if the memory block is offlined, otherwise, return false */
873bool is_memblock_offlined(struct memory_block *mem)
874{
875 return mem->state == MEM_OFFLINE;
876}
877
878static struct attribute *memory_root_attrs[] = {872static struct attribute *memory_root_attrs[] = {
879#ifdef CONFIG_ARCH_MEMORY_PROBE873#ifdef CONFIG_ARCH_MEMORY_PROBE
880 &dev_attr_probe.attr,874 &dev_attr_probe.attr,
drivers/base/node.c+6−135
@@ -20,6 +20,7 @@ · 19 unmodified lines
20#include <linux/pm_runtime.h>20#include <linux/pm_runtime.h>
21#include <linux/swap.h>21#include <linux/swap.h>
22#include <linux/slab.h>22#include <linux/slab.h>
23#include <linux/hugetlb.h>
23 24
24static struct bus_type node_subsys = {25static struct bus_type node_subsys = {
25 .name = "node",26 .name = "node",
@@ -589,64 +590,9 @@ static const struct attribute_group *node_dev_groups[] = { · 563 unmodified lines
589 NULL590 NULL
590};591};
591 592
592#ifdef CONFIG_HUGETLBFS
593/*
594 * hugetlbfs per node attributes registration interface:
595 * When/if hugetlb[fs] subsystem initializes [sometime after this module],
596 * it will register its per node attributes for all online nodes with
597 * memory. It will also call register_hugetlbfs_with_node(), below, to
598 * register its attribute registration functions with this node driver.
599 * Once these hooks have been initialized, the node driver will call into
600 * the hugetlb module to [un]register attributes for hot-plugged nodes.
601 */
602static node_registration_func_t __hugetlb_register_node;
603static node_registration_func_t __hugetlb_unregister_node;
604
605static inline bool hugetlb_register_node(struct node *node)
606{
607 if (__hugetlb_register_node &&
608 node_state(node->dev.id, N_MEMORY)) {
609 __hugetlb_register_node(node);
610 return true;
611 }
612 return false;
613}
614
615static inline void hugetlb_unregister_node(struct node *node)
616{
617 if (__hugetlb_unregister_node)
618 __hugetlb_unregister_node(node);
619}
620
621void register_hugetlbfs_with_node(node_registration_func_t doregister,
622 node_registration_func_t unregister)
623{
624 __hugetlb_register_node = doregister;
625 __hugetlb_unregister_node = unregister;
626}
627#else
628static inline void hugetlb_register_node(struct node *node) {}
629
630static inline void hugetlb_unregister_node(struct node *node) {}
631#endif
632
633static void node_device_release(struct device *dev)593static void node_device_release(struct device *dev)
634{594{
635 struct node *node = to_node(dev);595 kfree(to_node(dev));
636
637#if defined(CONFIG_MEMORY_HOTPLUG) && defined(CONFIG_HUGETLBFS)
638 /*
639 * We schedule the work only when a memory section is
640 * onlined/offlined on this node. When we come here,
641 * all the memory on this node has been offlined,
642 * so we won't enqueue new work to this work.
643 *
644 * The work is using node->node_work, so we should
645 * flush work before freeing the memory.
646 */
647 flush_work(&node->node_work);
648#endif
649 kfree(node);
650}596}
651 597
652/*598/*
@@ -665,13 +611,13 @@ static int register_node(struct node *node, int num) · 12 unmodified lines
665 node->dev.groups = node_dev_groups;611 node->dev.groups = node_dev_groups;
666 error = device_register(&node->dev);612 error = device_register(&node->dev);
667 613
668 if (error)614 if (error) {
669 put_device(&node->dev);615 put_device(&node->dev);
670 else {616 } else {
671 hugetlb_register_node(node);617 hugetlb_register_node(node);
672
673 compaction_register_node(node);618 compaction_register_node(node);
674 }619 }
620
675 return error;621 return error;
676}622}
677 623
@@ -684,8 +630,8 @@ static int register_node(struct node *node, int num) · 6 unmodified lines
684 */630 */
685void unregister_node(struct node *node)631void unregister_node(struct node *node)
686{632{
633 hugetlb_unregister_node(node);
687 compaction_unregister_node(node);634 compaction_unregister_node(node);
688 hugetlb_unregister_node(node); /* no-op, if memoryless node */
689 node_remove_accesses(node);635 node_remove_accesses(node);
690 node_remove_caches(node);636 node_remove_caches(node);
691 device_unregister(&node->dev);637 device_unregister(&node->dev);
@@ -907,74 +853,8 @@ void register_memory_blocks_under_node(int nid, unsigned long start_pfn, · 215 unmodified lines
907 (void *)&nid, func);853 (void *)&nid, func);
908 return;854 return;
909}855}
910
911#ifdef CONFIG_HUGETLBFS
912/*
913 * Handle per node hstate attribute [un]registration on transistions
914 * to/from memoryless state.
915 */
916static void node_hugetlb_work(struct work_struct *work)
917{
918 struct node *node = container_of(work, struct node, node_work);
919
920 /*
921 * We only get here when a node transitions to/from memoryless state.
922 * We can detect which transition occurred by examining whether the
923 * node has memory now. hugetlb_register_node() already check this
924 * so we try to register the attributes. If that fails, then the
925 * node has transitioned to memoryless, try to unregister the
926 * attributes.
927 */
928 if (!hugetlb_register_node(node))
929 hugetlb_unregister_node(node);
930}
931
932static void init_node_hugetlb_work(int nid)
933{
934 INIT_WORK(&node_devices[nid]->node_work, node_hugetlb_work);
935}
936
937static int node_memory_callback(struct notifier_block *self,
938 unsigned long action, void *arg)
939{
940 struct memory_notify *mnb = arg;
941 int nid = mnb->status_change_nid;
942
943 switch (action) {
944 case MEM_ONLINE:
945 case MEM_OFFLINE:
946 /*
947 * offload per node hstate [un]registration to a work thread
948 * when transitioning to/from memoryless state.
949 */
950 if (nid != NUMA_NO_NODE)
951 schedule_work(&node_devices[nid]->node_work);
952 break;
953
954 case MEM_GOING_ONLINE:
955 case MEM_GOING_OFFLINE:
956 case MEM_CANCEL_ONLINE:
957 case MEM_CANCEL_OFFLINE:
958 default:
959 break;
960 }
961
962 return NOTIFY_OK;
963}
964#endif /* CONFIG_HUGETLBFS */
965#endif /* CONFIG_MEMORY_HOTPLUG */856#endif /* CONFIG_MEMORY_HOTPLUG */
966 857
967#if !defined(CONFIG_MEMORY_HOTPLUG) || !defined(CONFIG_HUGETLBFS)
968static inline int node_memory_callback(struct notifier_block *self,
969 unsigned long action, void *arg)
970{
971 return NOTIFY_OK;
972}
973
974static void init_node_hugetlb_work(int nid) { }
975
976#endif
977
978int __register_one_node(int nid)858int __register_one_node(int nid)
979{859{
980 int error;860 int error;
@@ -993,8 +873,6 @@ int __register_one_node(int nid) · 12 unmodified lines
993 }873 }
994 874
995 INIT_LIST_HEAD(&node_devices[nid]->access_list);875 INIT_LIST_HEAD(&node_devices[nid]->access_list);
996 /* initialize work queue for memory hot plug */
997 init_node_hugetlb_work(nid);
998 node_init_caches(nid);876 node_init_caches(nid);
999 877
1000 return error;878 return error;
@@ -1065,13 +943,8 @@ static const struct attribute_group *cpu_root_attr_groups[] = { · 64 unmodified lines
1065 NULL,943 NULL,
1066};944};
1067 945
1068#define NODE_CALLBACK_PRI 2 /* lower than SLAB */
1069void __init node_dev_init(void)946void __init node_dev_init(void)
1070{947{
1071 static struct notifier_block node_memory_callback_nb = {
1072 .notifier_call = node_memory_callback,
1073 .priority = NODE_CALLBACK_PRI,
1074 };
1075 int ret, i;948 int ret, i;
1076 949
1077 BUILD_BUG_ON(ARRAY_SIZE(node_state_attr) != NR_NODE_STATES);950 BUILD_BUG_ON(ARRAY_SIZE(node_state_attr) != NR_NODE_STATES);
@@ -1081,8 +954,6 @@ void __init node_dev_init(void) · 3 unmodified lines
1081 if (ret)954 if (ret)
1082 panic("%s() failed to register subsystem: %d\n", __func__, ret);955 panic("%s() failed to register subsystem: %d\n", __func__, ret);
1083 956
1084 register_hotmemory_notifier(&node_memory_callback_nb);
1085
1086 /*957 /*
1087 * Create all node devices, which will properly link the node958 * Create all node devices, which will properly link the node
1088 * to applicable memory block devices and already created cpu devices.959 * to applicable memory block devices and already created cpu devices.
drivers/block/zram/zram_drv.c+24−14
@@ -329,8 +329,8 @@ static ssize_t idle_store(struct device *dev, · 328 unmodified lines
329 329
330 if (!sysfs_streq(buf, "all")) {330 if (!sysfs_streq(buf, "all")) {
331 /*331 /*
332 * If it did not parse as 'all' try to treat it as an integer when332 * If it did not parse as 'all' try to treat it as an integer
333 * we have memory tracking enabled.333 * when we have memory tracking enabled.
334 */334 */
335 u64 age_sec;335 u64 age_sec;
336 336
@@ -345,7 +345,10 @@ static ssize_t idle_store(struct device *dev, · 8 unmodified lines
345 if (!init_done(zram))345 if (!init_done(zram))
346 goto out_unlock;346 goto out_unlock;
347 347
348 /* A cutoff_time of 0 marks everything as idle, this is the "all" behavior */348 /*
349 * A cutoff_time of 0 marks everything as idle, this is the
350 * "all" behavior.
351 */
349 mark_idle(zram, cutoff_time);352 mark_idle(zram, cutoff_time);
350 rv = len;353 rv = len;
351 354
@@ -1410,9 +1413,19 @@ compress_again: · 1058 unmodified lines
1410 handle = zs_malloc(zram->mem_pool, comp_len,1413 handle = zs_malloc(zram->mem_pool, comp_len,
1411 GFP_NOIO | __GFP_HIGHMEM |1414 GFP_NOIO | __GFP_HIGHMEM |
1412 __GFP_MOVABLE);1415 __GFP_MOVABLE);
1413 if (!IS_ERR((void *)handle))1416 if (IS_ERR((void *)handle))
1417 return PTR_ERR((void *)handle);
1418
1419 if (comp_len != PAGE_SIZE)
1414 goto compress_again;1420 goto compress_again;
1415 return PTR_ERR((void *)handle);1421 /*
1422 * If the page is not compressible, you need to acquire the
1423 * lock and execute the code below. The zcomp_stream_get()
1424 * call is needed to disable the cpu hotplug and grab the
1425 * zstrm buffer back. It is necessary that the dereferencing
1426 * of the zstrm variable below occurs correctly.
1427 */
1428 zstrm = zcomp_stream_get(zram->comp);
1416 }1429 }
1417 1430
1418 alloced_pages = zs_get_total_pages(zram->mem_pool);1431 alloced_pages = zs_get_total_pages(zram->mem_pool);
@@ -1710,9 +1723,6 @@ out: · 291 unmodified lines
1710 1723
1711static void zram_reset_device(struct zram *zram)1724static void zram_reset_device(struct zram *zram)
1712{1725{
1713 struct zcomp *comp;
1714 u64 disksize;
1715
1716 down_write(&zram->init_lock);1726 down_write(&zram->init_lock);
1717 1727
1718 zram->limit_pages = 0;1728 zram->limit_pages = 0;
@@ -1722,17 +1732,15 @@ static void zram_reset_device(struct zram *zram) · 3 unmodified lines
1722 return;1732 return;
1723 }1733 }
1724 1734
1725 comp = zram->comp;
1726 disksize = zram->disksize;
1727 zram->disksize = 0;
1728
1729 set_capacity_and_notify(zram->disk, 0);1735 set_capacity_and_notify(zram->disk, 0);
1730 part_stat_set_all(zram->disk->part0, 0);1736 part_stat_set_all(zram->disk->part0, 0);
1731 1737
1732 /* I/O operation under all of CPU are done so let's free */1738 /* I/O operation under all of CPU are done so let's free */
1733 zram_meta_free(zram, disksize);1739 zram_meta_free(zram, zram->disksize);
1740 zram->disksize = 0;
1734 memset(&zram->stats, 0, sizeof(zram->stats));1741 memset(&zram->stats, 0, sizeof(zram->stats));
1735 zcomp_destroy(comp);1742 zcomp_destroy(zram->comp);
1743 zram->comp = NULL;
1736 reset_bdev(zram);1744 reset_bdev(zram);
1737 1745
1738 up_write(&zram->init_lock);1746 up_write(&zram->init_lock);
@@ -2126,6 +2134,8 @@ static int __init zram_init(void) · 387 unmodified lines
2126{2134{
2127 int ret;2135 int ret;
2128 2136
2137 BUILD_BUG_ON(__NR_ZRAM_PAGEFLAGS > BITS_PER_LONG);
2138
2129 ret = cpuhp_setup_state_multi(CPUHP_ZCOMP_PREPARE, "block/zram:prepare",2139 ret = cpuhp_setup_state_multi(CPUHP_ZCOMP_PREPARE, "block/zram:prepare",
2130 zcomp_cpu_up_prepare, zcomp_cpu_dead);2140 zcomp_cpu_up_prepare, zcomp_cpu_dead);
2131 if (ret < 0)2141 if (ret < 0)
drivers/block/zram/zram_drv.h+7−8
@@ -30,16 +30,15 @@ · 29 unmodified lines
30 30
31 31
32/*32/*
33 * The lower ZRAM_FLAG_SHIFT bits of table.flags is for33 * ZRAM is mainly used for memory efficiency so we want to keep memory
34 * object size (excluding header), the higher bits is for34 * footprint small and thus squeeze size and zram pageflags into a flags
35 * zram_pageflags.35 * member. The lower ZRAM_FLAG_SHIFT bits is for object size (excluding
36 * header), which cannot be larger than PAGE_SIZE (requiring PAGE_SHIFT
37 * bits), the higher bits are for zram_pageflags.
36 *38 *
37 * zram is mainly used for memory efficiency so we want to keep memory39 * We use BUILD_BUG_ON() to make sure that zram pageflags don't overflow.
38 * footprint small so we can squeeze size and flags into a field.
39 * The lower ZRAM_FLAG_SHIFT bits is for object size (excluding header),
40 * the higher bits is for zram_pageflags.
41 */40 */
42#define ZRAM_FLAG_SHIFT 2441#define ZRAM_FLAG_SHIFT (PAGE_SHIFT + 1)
43 42
44/* Flags for zram pages (table[page_no].flags) */43/* Flags for zram pages (table[page_no].flags) */
45enum zram_pageflags {44enum zram_pageflags {
drivers/dax/kmem.c+39−3
@@ -11,9 +11,17 @@ · 10 unmodified lines
11#include <linux/fs.h>11#include <linux/fs.h>
12#include <linux/mm.h>12#include <linux/mm.h>
13#include <linux/mman.h>13#include <linux/mman.h>
14#include <linux/memory-tiers.h>
14#include "dax-private.h"15#include "dax-private.h"
15#include "bus.h"16#include "bus.h"
16 17
18/*
19 * Default abstract distance assigned to the NUMA node onlined
20 * by DAX/kmem if the low level platform driver didn't initialize
21 * one for this NUMA node.
22 */
23#define MEMTIER_DEFAULT_DAX_ADISTANCE (MEMTIER_ADISTANCE_DRAM * 5)
24
17/* Memory resource name used for add_memory_driver_managed(). */25/* Memory resource name used for add_memory_driver_managed(). */
18static const char *kmem_name;26static const char *kmem_name;
19/* Set if any memory will remain added when the driver will be unloaded. */27/* Set if any memory will remain added when the driver will be unloaded. */
@@ -41,6 +49,7 @@ struct dax_kmem_data { · 21 unmodified lines
41 struct resource *res[];49 struct resource *res[];
42};50};
43 51
52static struct memory_dev_type *dax_slowmem_type;
44static int dev_dax_kmem_probe(struct dev_dax *dev_dax)53static int dev_dax_kmem_probe(struct dev_dax *dev_dax)
45{54{
46 struct device *dev = &dev_dax->dev;55 struct device *dev = &dev_dax->dev;
@@ -79,11 +88,13 @@ static int dev_dax_kmem_probe(struct dev_dax *dev_dax) · 32 unmodified lines
79 return -EINVAL;88 return -EINVAL;
80 }89 }
81 90
91 init_node_memory_type(numa_node, dax_slowmem_type);
92
93 rc = -ENOMEM;
82 data = kzalloc(struct_size(data, res, dev_dax->nr_range), GFP_KERNEL);94 data = kzalloc(struct_size(data, res, dev_dax->nr_range), GFP_KERNEL);
83 if (!data)95 if (!data)
84 return -ENOMEM;96 goto err_dax_kmem_data;
85 97
86 rc = -ENOMEM;
87 data->res_name = kstrdup(dev_name(dev), GFP_KERNEL);98 data->res_name = kstrdup(dev_name(dev), GFP_KERNEL);
88 if (!data->res_name)99 if (!data->res_name)
89 goto err_res_name;100 goto err_res_name;
@@ -155,6 +166,8 @@ err_reg_mgid: · 65 unmodified lines
155 kfree(data->res_name);166 kfree(data->res_name);
156err_res_name:167err_res_name:
157 kfree(data);168 kfree(data);
169err_dax_kmem_data:
170 clear_node_memory_type(numa_node, dax_slowmem_type);
158 return rc;171 return rc;
159}172}
160 173
@@ -162,6 +175,7 @@ err_res_name: · 1 unmodified line
162static void dev_dax_kmem_remove(struct dev_dax *dev_dax)175static void dev_dax_kmem_remove(struct dev_dax *dev_dax)
163{176{
164 int i, success = 0;177 int i, success = 0;
178 int node = dev_dax->target_node;
165 struct device *dev = &dev_dax->dev;179 struct device *dev = &dev_dax->dev;
166 struct dax_kmem_data *data = dev_get_drvdata(dev);180 struct dax_kmem_data *data = dev_get_drvdata(dev);
167 181
@@ -198,6 +212,14 @@ static void dev_dax_kmem_remove(struct dev_dax *dev_dax) · 30 unmodified lines
198 kfree(data->res_name);212 kfree(data->res_name);
199 kfree(data);213 kfree(data);
200 dev_set_drvdata(dev, NULL);214 dev_set_drvdata(dev, NULL);
215 /*
216 * Clear the memtype association on successful unplug.
217 * If not, we have memory blocks left which can be
218 * offlined/onlined later. We need to keep memory_dev_type
219 * for that. This implies this reference will be around
220 * till next reboot.
221 */
222 clear_node_memory_type(node, dax_slowmem_type);
201 }223 }
202}224}
203#else225#else
@@ -228,9 +250,22 @@ static int __init dax_kmem_init(void) · 24 unmodified lines
228 if (!kmem_name)250 if (!kmem_name)
229 return -ENOMEM;251 return -ENOMEM;
230 252
253 dax_slowmem_type = alloc_memory_type(MEMTIER_DEFAULT_DAX_ADISTANCE);
254 if (IS_ERR(dax_slowmem_type)) {
255 rc = PTR_ERR(dax_slowmem_type);
256 goto err_dax_slowmem_type;
257 }
258
231 rc = dax_driver_register(&device_dax_kmem_driver);259 rc = dax_driver_register(&device_dax_kmem_driver);
232 if (rc)260 if (rc)
233 kfree_const(kmem_name);261 goto error_dax_driver;
262
263 return rc;
264
265error_dax_driver:
266 destroy_memory_type(dax_slowmem_type);
267err_dax_slowmem_type:
268 kfree_const(kmem_name);
234 return rc;269 return rc;
235}270}
236 271
@@ -239,6 +274,7 @@ static void __exit dax_kmem_exit(void) · 2 unmodified lines
239 dax_driver_unregister(&device_dax_kmem_driver);274 dax_driver_unregister(&device_dax_kmem_driver);
240 if (!any_hotremove_failed)275 if (!any_hotremove_failed)
241 kfree_const(kmem_name);276 kfree_const(kmem_name);
277 destroy_memory_type(dax_slowmem_type);
242}278}
243 279
244MODULE_AUTHOR("Intel Corporation");280MODULE_AUTHOR("Intel Corporation");
drivers/firmware/efi/efi.c+1−1
@@ -59,7 +59,7 @@ static unsigned long __initdata rt_prop = EFI_INVALID_TABLE_ADDR; · 58 unmodified lines
59static unsigned long __initdata initrd = EFI_INVALID_TABLE_ADDR;59static unsigned long __initdata initrd = EFI_INVALID_TABLE_ADDR;
60 60
61struct mm_struct efi_mm = {61struct mm_struct efi_mm = {
62 .mm_rb = RB_ROOT,62 .mm_mt = MTREE_INIT_EXT(mm_mt, MM_MT_FLAGS, efi_mm.mmap_lock),
63 .mm_users = ATOMIC_INIT(2),63 .mm_users = ATOMIC_INIT(2),
64 .mm_count = ATOMIC_INIT(1),64 .mm_count = ATOMIC_INIT(1),
65 .write_protect_seq = SEQCNT_ZERO(efi_mm.write_protect_seq),65 .write_protect_seq = SEQCNT_ZERO(efi_mm.write_protect_seq),
drivers/firmware/efi/libstub/Makefile+1−0
@@ -57,6 +57,7 @@ GCOV_PROFILE := n · 56 unmodified lines
57# Sanitizer runtimes are unavailable and cannot be linked here.57# Sanitizer runtimes are unavailable and cannot be linked here.
58KASAN_SANITIZE := n58KASAN_SANITIZE := n
59KCSAN_SANITIZE := n59KCSAN_SANITIZE := n
60KMSAN_SANITIZE := n
60UBSAN_SANITIZE := n61UBSAN_SANITIZE := n
61OBJECT_FILES_NON_STANDARD := y62OBJECT_FILES_NON_STANDARD := y
62 63
drivers/gpu/drm/i915/gem/i915_gem_userptr.c+5−9
@@ -426,12 +426,11 @@ static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = { · 425 unmodified lines
426static int426static int
427probe_range(struct mm_struct *mm, unsigned long addr, unsigned long len)427probe_range(struct mm_struct *mm, unsigned long addr, unsigned long len)
428{428{
429 const unsigned long end = addr + len;429 VMA_ITERATOR(vmi, mm, addr);
430 struct vm_area_struct *vma;430 struct vm_area_struct *vma;
431 int ret = -EFAULT;
432 431
433 mmap_read_lock(mm);432 mmap_read_lock(mm);
434 for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {433 for_each_vma_range(vmi, vma, addr + len) {
435 /* Check for holes, note that we also update the addr below */434 /* Check for holes, note that we also update the addr below */
436 if (vma->vm_start > addr)435 if (vma->vm_start > addr)
437 break;436 break;
@@ -439,16 +438,13 @@ probe_range(struct mm_struct *mm, unsigned long addr, unsigned long len) · 1 unmodified line
439 if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP))438 if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP))
440 break;439 break;
441 440
442 if (vma->vm_end >= end) {
443 ret = 0;
444 break;
445 }
446
447 addr = vma->vm_end;441 addr = vma->vm_end;
448 }442 }
449 mmap_read_unlock(mm);443 mmap_read_unlock(mm);
450 444
451 return ret;445 if (vma)
446 return -EFAULT;
447 return 0;
452}448}
453 449
454/*450/*
drivers/input/serio/libps2.c+4−1
@@ -12,6 +12,7 @@ · 11 unmodified lines
12#include <linux/sched.h>12#include <linux/sched.h>
13#include <linux/interrupt.h>13#include <linux/interrupt.h>
14#include <linux/input.h>14#include <linux/input.h>
15#include <linux/kmsan-checks.h>
15#include <linux/serio.h>16#include <linux/serio.h>
16#include <linux/i8042.h>17#include <linux/i8042.h>
17#include <linux/libps2.h>18#include <linux/libps2.h>
@@ -294,9 +295,11 @@ int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) · 276 unmodified lines
294 295
295 serio_pause_rx(ps2dev->serio);296 serio_pause_rx(ps2dev->serio);
296 297
297 if (param)298 if (param) {
298 for (i = 0; i < receive; i++)299 for (i = 0; i < receive; i++)
299 param[i] = ps2dev->cmdbuf[(receive - 1) - i];300 param[i] = ps2dev->cmdbuf[(receive - 1) - i];
301 kmsan_unpoison_memory(param, receive);
302 }
300 303
301 if (ps2dev->cmdcnt &&304 if (ps2dev->cmdcnt &&
302 (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1)) {305 (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1)) {
drivers/misc/cxl/fault.c+15−30
@@ -280,22 +280,6 @@ void cxl_handle_fault(struct work_struct *fault_work) · 279 unmodified lines
280 mmput(mm);280 mmput(mm);
281}281}
282 282
283static void cxl_prefault_one(struct cxl_context *ctx, u64 ea)
284{
285 struct mm_struct *mm;
286
287 mm = get_mem_context(ctx);
288 if (mm == NULL) {
289 pr_devel("cxl_prefault_one unable to get mm %i\n",
290 pid_nr(ctx->pid));
291 return;
292 }
293
294 cxl_fault_segment(ctx, mm, ea);
295
296 mmput(mm);
297}
298
299static u64 next_segment(u64 ea, u64 vsid)283static u64 next_segment(u64 ea, u64 vsid)
300{284{
301 if (vsid & SLB_VSID_B_1T)285 if (vsid & SLB_VSID_B_1T)
@@ -306,23 +290,16 @@ static u64 next_segment(u64 ea, u64 vsid) · 4 unmodified lines
306 return ea + 1;290 return ea + 1;
307}291}
308 292
309static void cxl_prefault_vma(struct cxl_context *ctx)293static void cxl_prefault_vma(struct cxl_context *ctx, struct mm_struct *mm)
310{294{
311 u64 ea, last_esid = 0;295 u64 ea, last_esid = 0;
312 struct copro_slb slb;296 struct copro_slb slb;
297 VMA_ITERATOR(vmi, mm, 0);
313 struct vm_area_struct *vma;298 struct vm_area_struct *vma;
314 int rc;299 int rc;
315 struct mm_struct *mm;
316
317 mm = get_mem_context(ctx);
318 if (mm == NULL) {
319 pr_devel("cxl_prefault_vm unable to get mm %i\n",
320 pid_nr(ctx->pid));
321 return;
322 }
323 300
324 mmap_read_lock(mm);301 mmap_read_lock(mm);
325 for (vma = mm->mmap; vma; vma = vma->vm_next) {302 for_each_vma(vmi, vma) {
326 for (ea = vma->vm_start; ea < vma->vm_end;303 for (ea = vma->vm_start; ea < vma->vm_end;
327 ea = next_segment(ea, slb.vsid)) {304 ea = next_segment(ea, slb.vsid)) {
328 rc = copro_calculate_slb(mm, ea, &slb);305 rc = copro_calculate_slb(mm, ea, &slb);
@@ -337,20 +314,28 @@ static void cxl_prefault_vma(struct cxl_context *ctx) · 8 unmodified lines
337 }314 }
338 }315 }
339 mmap_read_unlock(mm);316 mmap_read_unlock(mm);
340
341 mmput(mm);
342}317}
343 318
344void cxl_prefault(struct cxl_context *ctx, u64 wed)319void cxl_prefault(struct cxl_context *ctx, u64 wed)
345{320{
321 struct mm_struct *mm = get_mem_context(ctx);
322
323 if (mm == NULL) {
324 pr_devel("cxl_prefault unable to get mm %i\n",
325 pid_nr(ctx->pid));
326 return;
327 }
328
346 switch (ctx->afu->prefault_mode) {329 switch (ctx->afu->prefault_mode) {
347 case CXL_PREFAULT_WED:330 case CXL_PREFAULT_WED:
348 cxl_prefault_one(ctx, wed);331 cxl_fault_segment(ctx, mm, wed);
349 break;332 break;
350 case CXL_PREFAULT_ALL:333 case CXL_PREFAULT_ALL:
351 cxl_prefault_vma(ctx);334 cxl_prefault_vma(ctx, mm);
352 break;335 break;
353 default:336 default:
354 break;337 break;
355 }338 }
339
340 mmput(mm);
356}341}
drivers/net/Kconfig+1−0
@@ -76,6 +76,7 @@ config WIREGUARD · 75 unmodified lines
76 tristate "WireGuard secure network tunnel"76 tristate "WireGuard secure network tunnel"
77 depends on NET && INET77 depends on NET && INET
78 depends on IPV6 || !IPV678 depends on IPV6 || !IPV6
79 depends on !KMSAN # KMSAN doesn't support the crypto configs below
79 select NET_UDP_TUNNEL80 select NET_UDP_TUNNEL
80 select DST_CACHE81 select DST_CACHE
81 select CRYPTO82 select CRYPTO
drivers/nvdimm/nd.h+1−1
@@ -652,7 +652,7 @@ void devm_namespace_disable(struct device *dev, · 651 unmodified lines
652 struct nd_namespace_common *ndns);652 struct nd_namespace_common *ndns);
653#if IS_ENABLED(CONFIG_ND_CLAIM)653#if IS_ENABLED(CONFIG_ND_CLAIM)
654/* max struct page size independent of kernel config */654/* max struct page size independent of kernel config */
655#define MAX_STRUCT_PAGE_SIZE 64655#define MAX_STRUCT_PAGE_SIZE 128
656int nvdimm_setup_pfn(struct nd_pfn *nd_pfn, struct dev_pagemap *pgmap);656int nvdimm_setup_pfn(struct nd_pfn *nd_pfn, struct dev_pagemap *pgmap);
657#else657#else
658static inline int nvdimm_setup_pfn(struct nd_pfn *nd_pfn,658static inline int nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
drivers/nvdimm/pfn_devs.c+1−1
@@ -787,7 +787,7 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn) · 786 unmodified lines
787 * when populating the vmemmap. This *should* be equal to787 * when populating the vmemmap. This *should* be equal to
788 * PMD_SIZE for most architectures.788 * PMD_SIZE for most architectures.
789 *789 *
790 * Also make sure size of struct page is less than 64. We790 * Also make sure size of struct page is less than 128. We
791 * want to make sure we use large enough size here so that791 * want to make sure we use large enough size here so that
792 * we don't have a dynamic reserve space depending on792 * we don't have a dynamic reserve space depending on
793 * struct page size. But we also want to make sure we notice793 * struct page size. But we also want to make sure we notice
drivers/tee/optee/call.c+10−8
@@ -492,15 +492,18 @@ static bool is_normal_memory(pgprot_t p) · 491 unmodified lines
492#endif492#endif
493}493}
494 494
495static int __check_mem_type(struct vm_area_struct *vma, unsigned long end)495static int __check_mem_type(struct mm_struct *mm, unsigned long start,
496 unsigned long end)
496{497{
497 while (vma && is_normal_memory(vma->vm_page_prot)) {498 struct vm_area_struct *vma;
498 if (vma->vm_end >= end)499 VMA_ITERATOR(vmi, mm, start);
499 return 0;500
500 vma = vma->vm_next;501 for_each_vma_range(vmi, vma, end) {
502 if (!is_normal_memory(vma->vm_page_prot))
503 return -EINVAL;
501 }504 }
502 505
503 return -EINVAL;506 return 0;
504}507}
505 508
506int optee_check_mem_type(unsigned long start, size_t num_pages)509int optee_check_mem_type(unsigned long start, size_t num_pages)
@@ -516,8 +519,7 @@ int optee_check_mem_type(unsigned long start, size_t num_pages) · 9 unmodified lines
516 return 0;519 return 0;
517 520
518 mmap_read_lock(mm);521 mmap_read_lock(mm);
519 rc = __check_mem_type(find_vma(mm, start),522 rc = __check_mem_type(mm, start, start + num_pages * PAGE_SIZE);
520 start + num_pages * PAGE_SIZE);
521 mmap_read_unlock(mm);523 mmap_read_unlock(mm);
522 524
523 return rc;525 return rc;
drivers/usb/core/urb.c+2−0
@@ -8,6 +8,7 @@ · 7 unmodified lines
8#include <linux/bitops.h>8#include <linux/bitops.h>
9#include <linux/slab.h>9#include <linux/slab.h>
10#include <linux/log2.h>10#include <linux/log2.h>
11#include <linux/kmsan.h>
11#include <linux/usb.h>12#include <linux/usb.h>
12#include <linux/wait.h>13#include <linux/wait.h>
13#include <linux/usb/hcd.h>14#include <linux/usb/hcd.h>
@@ -426,6 +427,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) · 412 unmodified lines
426 URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL |427 URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL |
427 URB_DMA_SG_COMBINED);428 URB_DMA_SG_COMBINED);
428 urb->transfer_flags |= (is_out ? URB_DIR_OUT : URB_DIR_IN);429 urb->transfer_flags |= (is_out ? URB_DIR_OUT : URB_DIR_IN);
430 kmsan_handle_urb(urb, is_out);
429 431
430 if (xfertype != USB_ENDPOINT_XFER_CONTROL &&432 if (xfertype != USB_ENDPOINT_XFER_CONTROL &&
431 dev->state < USB_STATE_CONFIGURED)433 dev->state < USB_STATE_CONFIGURED)
drivers/virtio/virtio_ring.c+9−1
@@ -11,6 +11,7 @@ · 10 unmodified lines
11#include <linux/module.h>11#include <linux/module.h>
12#include <linux/hrtimer.h>12#include <linux/hrtimer.h>
13#include <linux/dma-mapping.h>13#include <linux/dma-mapping.h>
14#include <linux/kmsan.h>
14#include <linux/spinlock.h>15#include <linux/spinlock.h>
15#include <xen/xen.h>16#include <xen/xen.h>
16 17
@@ -352,8 +353,15 @@ static dma_addr_t vring_map_one_sg(const struct vring_virtqueue *vq, · 335 unmodified lines
352 struct scatterlist *sg,353 struct scatterlist *sg,
353 enum dma_data_direction direction)354 enum dma_data_direction direction)
354{355{
355 if (!vq->use_dma_api)356 if (!vq->use_dma_api) {
357 /*
358 * If DMA is not used, KMSAN doesn't know that the scatterlist
359 * is initialized by the hardware. Explicitly check/unpoison it
360 * depending on the direction.
361 */
362 kmsan_handle_dma(sg_page(sg), sg->offset, sg->length, direction);
356 return (dma_addr_t)sg_phys(sg);363 return (dma_addr_t)sg_phys(sg);
364 }
357 365
358 /*366 /*
359 * We can't use dma_map_sg, because we don't use scatterlists in367 * We can't use dma_map_sg, because we don't use scatterlists in
drivers/xen/privcmd.c+1−1
@@ -282,7 +282,7 @@ static long privcmd_ioctl_mmap(struct file *file, void __user *udata) · 281 unmodified lines
282 struct page, lru);282 struct page, lru);
283 struct privcmd_mmap_entry *msg = page_address(page);283 struct privcmd_mmap_entry *msg = page_address(page);
284 284
285 vma = find_vma(mm, msg->va);285 vma = vma_lookup(mm, msg->va);
286 rc = -EINVAL;286 rc = -EINVAL;
287 287
288 if (!vma || (msg->va != vma->vm_start) || vma->vm_private_data)288 if (!vma || (msg->va != vma->vm_start) || vma->vm_private_data)
fs/Kconfig+1−0
@@ -235,6 +235,7 @@ config ARCH_SUPPORTS_HUGETLBFS · 234 unmodified lines
235config HUGETLBFS235config HUGETLBFS
236 bool "HugeTLB file system support"236 bool "HugeTLB file system support"
237 depends on X86 || IA64 || SPARC64 || ARCH_SUPPORTS_HUGETLBFS || BROKEN237 depends on X86 || IA64 || SPARC64 || ARCH_SUPPORTS_HUGETLBFS || BROKEN
238 depends on (SYSFS || SYSCTL)
238 help239 help
239 hugetlbfs is a filesystem backing for HugeTLB pages, based on240 hugetlbfs is a filesystem backing for HugeTLB pages, based on
240 ramfs. For architectures that support it, say Y here and read241 ramfs. For architectures that support it, say Y here and read
fs/btrfs/compression.c+15−16
@@ -8,6 +8,7 @@ · 7 unmodified lines
8#include <linux/file.h>8#include <linux/file.h>
9#include <linux/fs.h>9#include <linux/fs.h>
10#include <linux/pagemap.h>10#include <linux/pagemap.h>
11#include <linux/pagevec.h>
11#include <linux/highmem.h>12#include <linux/highmem.h>
12#include <linux/kthread.h>13#include <linux/kthread.h>
13#include <linux/time.h>14#include <linux/time.h>
@@ -219,8 +220,7 @@ static noinline void end_compressed_writeback(struct inode *inode, · 205 unmodified lines
219 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);220 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
220 unsigned long index = cb->start >> PAGE_SHIFT;221 unsigned long index = cb->start >> PAGE_SHIFT;
221 unsigned long end_index = (cb->start + cb->len - 1) >> PAGE_SHIFT;222 unsigned long end_index = (cb->start + cb->len - 1) >> PAGE_SHIFT;
222 struct page *pages[16];223 struct folio_batch fbatch;
223 unsigned long nr_pages = end_index - index + 1;
224 const int errno = blk_status_to_errno(cb->status);224 const int errno = blk_status_to_errno(cb->status);
225 int i;225 int i;
226 int ret;226 int ret;
@@ -228,24 +228,23 @@ static noinline void end_compressed_writeback(struct inode *inode, · 1 unmodified line
228 if (errno)228 if (errno)
229 mapping_set_error(inode->i_mapping, errno);229 mapping_set_error(inode->i_mapping, errno);
230 230
231 while (nr_pages > 0) {231 folio_batch_init(&fbatch);
232 ret = find_get_pages_contig(inode->i_mapping, index,232 while (index <= end_index) {
233 min_t(unsigned long,233 ret = filemap_get_folios(inode->i_mapping, &index, end_index,
234 nr_pages, ARRAY_SIZE(pages)), pages);234 &fbatch);
235 if (ret == 0) {235
236 nr_pages -= 1;236 if (ret == 0)
237 index += 1;237 return;
238 continue;238
239 }
240 for (i = 0; i < ret; i++) {239 for (i = 0; i < ret; i++) {
240 struct folio *folio = fbatch.folios[i];
241
241 if (errno)242 if (errno)
242 SetPageError(pages[i]);243 folio_set_error(folio);
243 btrfs_page_clamp_clear_writeback(fs_info, pages[i],244 btrfs_page_clamp_clear_writeback(fs_info, &folio->page,
244 cb->start, cb->len);245 cb->start, cb->len);
245 put_page(pages[i]);
246 }246 }
247 nr_pages -= ret;247 folio_batch_release(&fbatch);
248 index += ret;
249 }248 }
250 /* the inode may be gone now */249 /* the inode may be gone now */
251}250}
fs/btrfs/extent_io.c+15−18
@@ -270,9 +270,8 @@ static int __process_pages_contig(struct address_space *mapping, · 269 unmodified lines
270 pgoff_t start_index = start >> PAGE_SHIFT;270 pgoff_t start_index = start >> PAGE_SHIFT;
271 pgoff_t end_index = end >> PAGE_SHIFT;271 pgoff_t end_index = end >> PAGE_SHIFT;
272 pgoff_t index = start_index;272 pgoff_t index = start_index;
273 unsigned long nr_pages = end_index - start_index + 1;
274 unsigned long pages_processed = 0;273 unsigned long pages_processed = 0;
275 struct page *pages[16];274 struct folio_batch fbatch;
276 int err = 0;275 int err = 0;
277 int i;276 int i;
278 277
@@ -281,16 +280,17 @@ static int __process_pages_contig(struct address_space *mapping, · 2 unmodified lines
281 ASSERT(processed_end && *processed_end == start);280 ASSERT(processed_end && *processed_end == start);
282 }281 }
283 282
284 if ((page_ops & PAGE_SET_ERROR) && nr_pages > 0)283 if ((page_ops & PAGE_SET_ERROR) && start_index <= end_index)
285 mapping_set_error(mapping, -EIO);284 mapping_set_error(mapping, -EIO);
286 285
287 while (nr_pages > 0) {286 folio_batch_init(&fbatch);
288 int found_pages;287 while (index <= end_index) {
288 int found_folios;
289
290 found_folios = filemap_get_folios_contig(mapping, &index,
291 end_index, &fbatch);
289 292
290 found_pages = find_get_pages_contig(mapping, index,293 if (found_folios == 0) {
291 min_t(unsigned long,
292 nr_pages, ARRAY_SIZE(pages)), pages);
293 if (found_pages == 0) {
294 /*294 /*
295 * Only if we're going to lock these pages, we can find295 * Only if we're going to lock these pages, we can find
296 * nothing at @index.296 * nothing at @index.
@@ -300,23 +300,20 @@ static int __process_pages_contig(struct address_space *mapping, · 3 unmodified lines
300 goto out;300 goto out;
301 }301 }
302 302
303 for (i = 0; i < found_pages; i++) {303 for (i = 0; i < found_folios; i++) {
304 int process_ret;304 int process_ret;
305 305 struct folio *folio = fbatch.folios[i];
306 process_ret = process_one_page(fs_info, mapping,306 process_ret = process_one_page(fs_info, mapping,
307 pages[i], locked_page, page_ops,307 &folio->page, locked_page, page_ops,
308 start, end);308 start, end);
309 if (process_ret < 0) {309 if (process_ret < 0) {
310 for (; i < found_pages; i++)
311 put_page(pages[i]);
312 err = -EAGAIN;310 err = -EAGAIN;
311 folio_batch_release(&fbatch);
313 goto out;312 goto out;
314 }313 }
315 put_page(pages[i]);314 pages_processed += folio_nr_pages(folio);
316 pages_processed++;
317 }315 }
318 nr_pages -= found_pages;316 folio_batch_release(&fbatch);
319 index += found_pages;
320 cond_resched();317 cond_resched();
321 }318 }
322out:319out:
fs/btrfs/subpage.c+1−1
@@ -337,7 +337,7 @@ bool btrfs_subpage_end_and_test_writer(const struct btrfs_fs_info *fs_info, · 336 unmodified lines
337 *337 *
338 * Even with 0 returned, the page still need extra check to make sure338 * Even with 0 returned, the page still need extra check to make sure
339 * it's really the correct page, as the caller is using339 * it's really the correct page, as the caller is using
340 * find_get_pages_contig(), which can race with page invalidating.340 * filemap_get_folios_contig(), which can race with page invalidating.
341 */341 */
342int btrfs_page_start_writer_lock(const struct btrfs_fs_info *fs_info,342int btrfs_page_start_writer_lock(const struct btrfs_fs_info *fs_info,
343 struct page *page, u64 start, u32 len)343 struct page *page, u64 start, u32 len)
fs/btrfs/tests/extent-io-tests.c+17−15
@@ -4,6 +4,7 @@ · 3 unmodified lines
4 */4 */
5 5
6#include <linux/pagemap.h>6#include <linux/pagemap.h>
7#include <linux/pagevec.h>
7#include <linux/sched.h>8#include <linux/sched.h>
8#include <linux/slab.h>9#include <linux/slab.h>
9#include <linux/sizes.h>10#include <linux/sizes.h>
@@ -20,39 +21,40 @@ static noinline int process_page_range(struct inode *inode, u64 start, u64 end, · 10 unmodified lines
20 unsigned long flags)21 unsigned long flags)
21{22{
22 int ret;23 int ret;
23 struct page *pages[16];24 struct folio_batch fbatch;
24 unsigned long index = start >> PAGE_SHIFT;25 unsigned long index = start >> PAGE_SHIFT;
25 unsigned long end_index = end >> PAGE_SHIFT;26 unsigned long end_index = end >> PAGE_SHIFT;
26 unsigned long nr_pages = end_index - index + 1;
27 int i;27 int i;
28 int count = 0;28 int count = 0;
29 int loops = 0;29 int loops = 0;
30 30
31 while (nr_pages > 0) {31 folio_batch_init(&fbatch);
32 ret = find_get_pages_contig(inode->i_mapping, index,32
33 min_t(unsigned long, nr_pages,33 while (index <= end_index) {
34 ARRAY_SIZE(pages)), pages);34 ret = filemap_get_folios_contig(inode->i_mapping, &index,
35 end_index, &fbatch);
35 for (i = 0; i < ret; i++) {36 for (i = 0; i < ret; i++) {
37 struct folio *folio = fbatch.folios[i];
38
36 if (flags & PROCESS_TEST_LOCKED &&39 if (flags & PROCESS_TEST_LOCKED &&
37 !PageLocked(pages[i]))40 !folio_test_locked(folio))
38 count++;41 count++;
39 if (flags & PROCESS_UNLOCK && PageLocked(pages[i]))42 if (flags & PROCESS_UNLOCK && folio_test_locked(folio))
40 unlock_page(pages[i]);43 folio_unlock(folio);
41 put_page(pages[i]);
42 if (flags & PROCESS_RELEASE)44 if (flags & PROCESS_RELEASE)
43 put_page(pages[i]);45 folio_put(folio);
44 }46 }
45 nr_pages -= ret;47 folio_batch_release(&fbatch);
46 index += ret;
47 cond_resched();48 cond_resched();
48 loops++;49 loops++;
49 if (loops > 100000) {50 if (loops > 100000) {
50 printk(KERN_ERR51 printk(KERN_ERR
51 "stuck in a loop, start %llu, end %llu, nr_pages %lu, ret %d\n",52 "stuck in a loop, start %llu, end %llu, ret %d\n",
52 start, end, nr_pages, ret);53 start, end, ret);
53 break;54 break;
54 }55 }
55 }56 }
57
56 return count;58 return count;
57}59}
58 60
fs/buffer.c+65−93
@@ -152,7 +152,7 @@ static void __end_buffer_read_notouch(struct buffer_head *bh, int uptodate) · 151 unmodified lines
152 152
153/*153/*
154 * Default synchronous end-of-IO handler.. Just mark it up-to-date and154 * Default synchronous end-of-IO handler.. Just mark it up-to-date and
155 * unlock the buffer. This is what ll_rw_block uses too.155 * unlock the buffer.
156 */156 */
157void end_buffer_read_sync(struct buffer_head *bh, int uptodate)157void end_buffer_read_sync(struct buffer_head *bh, int uptodate)
158{158{
@@ -491,8 +491,8 @@ int inode_has_buffers(struct inode *inode) · 332 unmodified lines
491 * all already-submitted IO to complete, but does not queue any new491 * all already-submitted IO to complete, but does not queue any new
492 * writes to the disk.492 * writes to the disk.
493 *493 *
494 * To do O_SYNC writes, just queue the buffer writes with ll_rw_block as494 * To do O_SYNC writes, just queue the buffer writes with write_dirty_buffer
495 * you dirty the buffers, and then use osync_inode_buffers to wait for495 * as you dirty the buffers, and then use osync_inode_buffers to wait for
496 * completion. Any other dirty buffers which are not yet queued for496 * completion. Any other dirty buffers which are not yet queued for
497 * write will not be flushed to disk by the osync.497 * write will not be flushed to disk by the osync.
498 */498 */
@@ -562,7 +562,7 @@ void write_boundary_block(struct block_device *bdev, · 63 unmodified lines
562 struct buffer_head *bh = __find_get_block(bdev, bblock + 1, blocksize);562 struct buffer_head *bh = __find_get_block(bdev, bblock + 1, blocksize);
563 if (bh) {563 if (bh) {
564 if (buffer_dirty(bh))564 if (buffer_dirty(bh))
565 ll_rw_block(REQ_OP_WRITE, 1, &bh);565 write_dirty_buffer(bh, 0);
566 put_bh(bh);566 put_bh(bh);
567 }567 }
568}568}
@@ -1342,23 +1342,12 @@ void __breadahead(struct block_device *bdev, sector_t block, unsigned size) · 773 unmodified lines
1342{1342{
1343 struct buffer_head *bh = __getblk(bdev, block, size);1343 struct buffer_head *bh = __getblk(bdev, block, size);
1344 if (likely(bh)) {1344 if (likely(bh)) {
1345 ll_rw_block(REQ_OP_READ | REQ_RAHEAD, 1, &bh);1345 bh_readahead(bh, REQ_RAHEAD);
1346 brelse(bh);1346 brelse(bh);
1347 }1347 }
1348}1348}
1349EXPORT_SYMBOL(__breadahead);1349EXPORT_SYMBOL(__breadahead);
1350 1350
1351void __breadahead_gfp(struct block_device *bdev, sector_t block, unsigned size,
1352 gfp_t gfp)
1353{
1354 struct buffer_head *bh = __getblk_gfp(bdev, block, size, gfp);
1355 if (likely(bh)) {
1356 ll_rw_block(REQ_OP_READ | REQ_RAHEAD, 1, &bh);
1357 brelse(bh);
1358 }
1359}
1360EXPORT_SYMBOL(__breadahead_gfp);
1361
1362/**1351/**
1363 * __bread_gfp() - reads a specified block and returns the bh1352 * __bread_gfp() - reads a specified block and returns the bh
1364 * @bdev: the block_device to read from1353 * @bdev: the block_device to read from
@@ -1817,7 +1806,7 @@ done: · 452 unmodified lines
1817 /*1806 /*
1818 * The page was marked dirty, but the buffers were1807 * The page was marked dirty, but the buffers were
1819 * clean. Someone wrote them back by hand with1808 * clean. Someone wrote them back by hand with
1820 * ll_rw_block/submit_bh. A rare case.1809 * write_dirty_buffer/submit_bh. A rare case.
1821 */1810 */
1822 end_page_writeback(page);1811 end_page_writeback(page);
1823 1812
@@ -2033,7 +2022,7 @@ int __block_write_begin_int(struct folio *folio, loff_t pos, unsigned len, · 209 unmodified lines
2033 if (!buffer_uptodate(bh) && !buffer_delay(bh) &&2022 if (!buffer_uptodate(bh) && !buffer_delay(bh) &&
2034 !buffer_unwritten(bh) &&2023 !buffer_unwritten(bh) &&
2035 (block_start < from || block_end > to)) {2024 (block_start < from || block_end > to)) {
2036 ll_rw_block(REQ_OP_READ, 1, &bh);2025 bh_read_nowait(bh, 0);
2037 *wait_bh++=bh;2026 *wait_bh++=bh;
2038 }2027 }
2039 }2028 }
@@ -2352,7 +2341,7 @@ int generic_cont_expand_simple(struct inode *inode, loff_t size) · 312 unmodified lines
2352 struct address_space *mapping = inode->i_mapping;2341 struct address_space *mapping = inode->i_mapping;
2353 const struct address_space_operations *aops = mapping->a_ops;2342 const struct address_space_operations *aops = mapping->a_ops;
2354 struct page *page;2343 struct page *page;
2355 void *fsdata;2344 void *fsdata = NULL;
2356 int err;2345 int err;
2357 2346
2358 err = inode_newsize_ok(inode, size);2347 err = inode_newsize_ok(inode, size);
@@ -2378,7 +2367,7 @@ static int cont_expand_zero(struct file *file, struct address_space *mapping, · 19 unmodified lines
2378 const struct address_space_operations *aops = mapping->a_ops;2367 const struct address_space_operations *aops = mapping->a_ops;
2379 unsigned int blocksize = i_blocksize(inode);2368 unsigned int blocksize = i_blocksize(inode);
2380 struct page *page;2369 struct page *page;
2381 void *fsdata;2370 void *fsdata = NULL;
2382 pgoff_t index, curidx;2371 pgoff_t index, curidx;
2383 loff_t curpos;2372 loff_t curpos;
2384 unsigned zerofrom, offset, len;2373 unsigned zerofrom, offset, len;
@@ -2593,11 +2582,9 @@ int block_truncate_page(struct address_space *mapping, · 208 unmodified lines
2593 set_buffer_uptodate(bh);2582 set_buffer_uptodate(bh);
2594 2583
2595 if (!buffer_uptodate(bh) && !buffer_delay(bh) && !buffer_unwritten(bh)) {2584 if (!buffer_uptodate(bh) && !buffer_delay(bh) && !buffer_unwritten(bh)) {
2596 err = -EIO;2585 err = bh_read(bh, 0);
2597 ll_rw_block(REQ_OP_READ, 1, &bh);
2598 wait_on_buffer(bh);
2599 /* Uhhuh. Read error. Complain and punt. */2586 /* Uhhuh. Read error. Complain and punt. */
2600 if (!buffer_uptodate(bh))2587 if (err < 0)
2601 goto unlock;2588 goto unlock;
2602 }2589 }
2603 2590
@@ -2725,61 +2712,6 @@ void submit_bh(blk_opf_t opf, struct buffer_head *bh) · 121 unmodified lines
2725}2712}
2726EXPORT_SYMBOL(submit_bh);2713EXPORT_SYMBOL(submit_bh);
2727 2714
2728/**
2729 * ll_rw_block: low-level access to block devices (DEPRECATED)
2730 * @opf: block layer request operation and flags.
2731 * @nr: number of &struct buffer_heads in the array
2732 * @bhs: array of pointers to &struct buffer_head
2733 *
2734 * ll_rw_block() takes an array of pointers to &struct buffer_heads, and
2735 * requests an I/O operation on them, either a %REQ_OP_READ or a %REQ_OP_WRITE.
2736 * @opf contains flags modifying the detailed I/O behavior, most notably
2737 * %REQ_RAHEAD.
2738 *
2739 * This function drops any buffer that it cannot get a lock on (with the
2740 * BH_Lock state bit), any buffer that appears to be clean when doing a write
2741 * request, and any buffer that appears to be up-to-date when doing read
2742 * request. Further it marks as clean buffers that are processed for
2743 * writing (the buffer cache won't assume that they are actually clean
2744 * until the buffer gets unlocked).
2745 *
2746 * ll_rw_block sets b_end_io to simple completion handler that marks
2747 * the buffer up-to-date (if appropriate), unlocks the buffer and wakes
2748 * any waiters.
2749 *
2750 * All of the buffers must be for the same device, and must also be a
2751 * multiple of the current approved size for the device.
2752 */
2753void ll_rw_block(const blk_opf_t opf, int nr, struct buffer_head *bhs[])
2754{
2755 const enum req_op op = opf & REQ_OP_MASK;
2756 int i;
2757
2758 for (i = 0; i < nr; i++) {
2759 struct buffer_head *bh = bhs[i];
2760
2761 if (!trylock_buffer(bh))
2762 continue;
2763 if (op == REQ_OP_WRITE) {
2764 if (test_clear_buffer_dirty(bh)) {
2765 bh->b_end_io = end_buffer_write_sync;
2766 get_bh(bh);
2767 submit_bh(opf, bh);
2768 continue;
2769 }
2770 } else {
2771 if (!buffer_uptodate(bh)) {
2772 bh->b_end_io = end_buffer_read_sync;
2773 get_bh(bh);
2774 submit_bh(opf, bh);
2775 continue;
2776 }
2777 }
2778 unlock_buffer(bh);
2779 }
2780}
2781EXPORT_SYMBOL(ll_rw_block);
2782
2783void write_dirty_buffer(struct buffer_head *bh, blk_opf_t op_flags)2715void write_dirty_buffer(struct buffer_head *bh, blk_opf_t op_flags)
2784{2716{
2785 lock_buffer(bh);2717 lock_buffer(bh);
@@ -3026,29 +2958,69 @@ int bh_uptodate_or_lock(struct buffer_head *bh) · 240 unmodified lines
3026EXPORT_SYMBOL(bh_uptodate_or_lock);2958EXPORT_SYMBOL(bh_uptodate_or_lock);
3027 2959
3028/**2960/**
3029 * bh_submit_read - Submit a locked buffer for reading2961 * __bh_read - Submit read for a locked buffer
3030 * @bh: struct buffer_head2962 * @bh: struct buffer_head
2963 * @op_flags: appending REQ_OP_* flags besides REQ_OP_READ
2964 * @wait: wait until reading finish
3031 *2965 *
3032 * Returns zero on success and -EIO on error.2966 * Returns zero on success or don't wait, and -EIO on error.
3033 */2967 */
3034int bh_submit_read(struct buffer_head *bh)2968int __bh_read(struct buffer_head *bh, blk_opf_t op_flags, bool wait)
3035{2969{
3036 BUG_ON(!buffer_locked(bh));2970 int ret = 0;
3037 2971
3038 if (buffer_uptodate(bh)) {2972 BUG_ON(!buffer_locked(bh));
3039 unlock_buffer(bh);
3040 return 0;
3041 }
3042 2973
3043 get_bh(bh);2974 get_bh(bh);
3044 bh->b_end_io = end_buffer_read_sync;2975 bh->b_end_io = end_buffer_read_sync;
3045 submit_bh(REQ_OP_READ, bh);2976 submit_bh(REQ_OP_READ | op_flags, bh);
3046 wait_on_buffer(bh);2977 if (wait) {
3047 if (buffer_uptodate(bh))2978 wait_on_buffer(bh);
3048 return 0;2979 if (!buffer_uptodate(bh))
3049 return -EIO;2980 ret = -EIO;
2981 }
2982 return ret;
2983}
2984EXPORT_SYMBOL(__bh_read);
2985
2986/**
2987 * __bh_read_batch - Submit read for a batch of unlocked buffers
2988 * @nr: entry number of the buffer batch
2989 * @bhs: a batch of struct buffer_head
2990 * @op_flags: appending REQ_OP_* flags besides REQ_OP_READ
2991 * @force_lock: force to get a lock on the buffer if set, otherwise drops any
2992 * buffer that cannot lock.
2993 *
2994 * Returns zero on success or don't wait, and -EIO on error.
2995 */
2996void __bh_read_batch(int nr, struct buffer_head *bhs[],
2997 blk_opf_t op_flags, bool force_lock)
2998{
2999 int i;
3000
3001 for (i = 0; i < nr; i++) {
3002 struct buffer_head *bh = bhs[i];
3003
3004 if (buffer_uptodate(bh))
3005 continue;
3006
3007 if (force_lock)
3008 lock_buffer(bh);
3009 else
3010 if (!trylock_buffer(bh))
3011 continue;
3012
3013 if (buffer_uptodate(bh)) {
3014 unlock_buffer(bh);
3015 continue;
3016 }
3017
3018 bh->b_end_io = end_buffer_read_sync;
3019 get_bh(bh);
3020 submit_bh(REQ_OP_READ | op_flags, bh);
3021 }
3050}3022}
3051EXPORT_SYMBOL(bh_submit_read);3023EXPORT_SYMBOL(__bh_read_batch);
3052 3024
3053void __init buffer_init(void)3025void __init buffer_init(void)
3054{3026{
fs/coredump.c+12−22
@@ -1100,30 +1100,20 @@ whole: · 1099 unmodified lines
1100 return vma->vm_end - vma->vm_start;1100 return vma->vm_end - vma->vm_start;
1101}1101}
1102 1102
1103static struct vm_area_struct *first_vma(struct task_struct *tsk,
1104 struct vm_area_struct *gate_vma)
1105{
1106 struct vm_area_struct *ret = tsk->mm->mmap;
1107
1108 if (ret)
1109 return ret;
1110 return gate_vma;
1111}
1112
1113/*1103/*
1114 * Helper function for iterating across a vma list. It ensures that the caller1104 * Helper function for iterating across a vma list. It ensures that the caller
1115 * will visit `gate_vma' prior to terminating the search.1105 * will visit `gate_vma' prior to terminating the search.
1116 */1106 */
1117static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma,1107static struct vm_area_struct *coredump_next_vma(struct ma_state *mas,
1108 struct vm_area_struct *vma,
1118 struct vm_area_struct *gate_vma)1109 struct vm_area_struct *gate_vma)
1119{1110{
1120 struct vm_area_struct *ret;1111 if (gate_vma && (vma == gate_vma))
1121
1122 ret = this_vma->vm_next;
1123 if (ret)
1124 return ret;
1125 if (this_vma == gate_vma)
1126 return NULL;1112 return NULL;
1113
1114 vma = mas_next(mas, ULONG_MAX);
1115 if (vma)
1116 return vma;
1127 return gate_vma;1117 return gate_vma;
1128}1118}
1129 1119
@@ -1147,9 +1137,10 @@ static void free_vma_snapshot(struct coredump_params *cprm) · 17 unmodified lines
1147 */1137 */
1148static bool dump_vma_snapshot(struct coredump_params *cprm)1138static bool dump_vma_snapshot(struct coredump_params *cprm)
1149{1139{
1150 struct vm_area_struct *vma, *gate_vma;1140 struct vm_area_struct *gate_vma, *vma = NULL;
1151 struct mm_struct *mm = current->mm;1141 struct mm_struct *mm = current->mm;
1152 int i;1142 MA_STATE(mas, &mm->mm_mt, 0, 0);
1143 int i = 0;
1153 1144
1154 /*1145 /*
1155 * Once the stack expansion code is fixed to not change VMA bounds1146 * Once the stack expansion code is fixed to not change VMA bounds
@@ -1169,8 +1160,7 @@ static bool dump_vma_snapshot(struct coredump_params *cprm) · 13 unmodified lines
1169 return false;1160 return false;
1170 }1161 }
1171 1162
1172 for (i = 0, vma = first_vma(current, gate_vma); vma != NULL;1163 while ((vma = coredump_next_vma(&mas, vma, gate_vma)) != NULL) {
1173 vma = next_vma(vma, gate_vma), i++) {
1174 struct core_vma_metadata *m = cprm->vma_meta + i;1164 struct core_vma_metadata *m = cprm->vma_meta + i;
1175 1165
1176 m->start = vma->vm_start;1166 m->start = vma->vm_start;
@@ -1178,10 +1168,10 @@ static bool dump_vma_snapshot(struct coredump_params *cprm) · 1 unmodified line
1178 m->flags = vma->vm_flags;1168 m->flags = vma->vm_flags;
1179 m->dump_size = vma_dump_size(vma, cprm->mm_flags);1169 m->dump_size = vma_dump_size(vma, cprm->mm_flags);
1180 m->pgoff = vma->vm_pgoff;1170 m->pgoff = vma->vm_pgoff;
1181
1182 m->file = vma->vm_file;1171 m->file = vma->vm_file;
1183 if (m->file)1172 if (m->file)
1184 get_file(m->file);1173 get_file(m->file);
1174 i++;
1185 }1175 }
1186 1176
1187 mmap_write_unlock(mm);1177 mmap_write_unlock(mm);
fs/exec.c+8−6
@@ -28,7 +28,6 @@ · 27 unmodified lines
28#include <linux/file.h>28#include <linux/file.h>
29#include <linux/fdtable.h>29#include <linux/fdtable.h>
30#include <linux/mm.h>30#include <linux/mm.h>
31#include <linux/vmacache.h>
32#include <linux/stat.h>31#include <linux/stat.h>
33#include <linux/fcntl.h>32#include <linux/fcntl.h>
34#include <linux/swap.h>33#include <linux/swap.h>
@@ -683,6 +682,8 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) · 648 unmodified lines
683 unsigned long length = old_end - old_start;682 unsigned long length = old_end - old_start;
684 unsigned long new_start = old_start - shift;683 unsigned long new_start = old_start - shift;
685 unsigned long new_end = old_end - shift;684 unsigned long new_end = old_end - shift;
685 VMA_ITERATOR(vmi, mm, new_start);
686 struct vm_area_struct *next;
686 struct mmu_gather tlb;687 struct mmu_gather tlb;
687 688
688 BUG_ON(new_start > new_end);689 BUG_ON(new_start > new_end);
@@ -691,7 +692,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) · 2 unmodified lines
691 * ensure there are no vmas between where we want to go692 * ensure there are no vmas between where we want to go
692 * and where we are693 * and where we are
693 */694 */
694 if (vma != find_vma(mm, new_start))695 if (vma != vma_next(&vmi))
695 return -EFAULT;696 return -EFAULT;
696 697
697 /*698 /*
@@ -710,12 +711,13 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) · 12 unmodified lines
710 711
711 lru_add_drain();712 lru_add_drain();
712 tlb_gather_mmu(&tlb, mm);713 tlb_gather_mmu(&tlb, mm);
714 next = vma_next(&vmi);
713 if (new_end > old_start) {715 if (new_end > old_start) {
714 /*716 /*
715 * when the old and new regions overlap clear from new_end.717 * when the old and new regions overlap clear from new_end.
716 */718 */
717 free_pgd_range(&tlb, new_end, old_end, new_end,719 free_pgd_range(&tlb, new_end, old_end, new_end,
718 vma->vm_next ? vma->vm_next->vm_start : USER_PGTABLES_CEILING);720 next ? next->vm_start : USER_PGTABLES_CEILING);
719 } else {721 } else {
720 /*722 /*
721 * otherwise, clean from old_start; this is done to not touch723 * otherwise, clean from old_start; this is done to not touch
@@ -724,7 +726,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) · 2 unmodified lines
724 * for the others its just a little faster.726 * for the others its just a little faster.
725 */727 */
726 free_pgd_range(&tlb, old_start, old_end, new_end,728 free_pgd_range(&tlb, old_start, old_end, new_end,
727 vma->vm_next ? vma->vm_next->vm_start : USER_PGTABLES_CEILING);729 next ? next->vm_start : USER_PGTABLES_CEILING);
728 }730 }
729 tlb_finish_mmu(&tlb);731 tlb_finish_mmu(&tlb);
730 732
@@ -1010,6 +1012,7 @@ static int exec_mmap(struct mm_struct *mm) · 279 unmodified lines
1010 active_mm = tsk->active_mm;1012 active_mm = tsk->active_mm;
1011 tsk->active_mm = mm;1013 tsk->active_mm = mm;
1012 tsk->mm = mm;1014 tsk->mm = mm;
1015 lru_gen_add_mm(mm);
1013 /*1016 /*
1014 * This prevents preemption while active_mm is being loaded and1017 * This prevents preemption while active_mm is being loaded and
1015 * it and mm are being updated, which could cause problems for1018 * it and mm are being updated, which could cause problems for
@@ -1022,9 +1025,8 @@ static int exec_mmap(struct mm_struct *mm) · 6 unmodified lines
1022 activate_mm(active_mm, mm);1025 activate_mm(active_mm, mm);
1023 if (IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM))1026 if (IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM))
1024 local_irq_enable();1027 local_irq_enable();
1025 tsk->mm->vmacache_seqnum = 0;
1026 vmacache_flush(tsk);
1027 task_unlock(tsk);1028 task_unlock(tsk);
1029 lru_gen_use_mm(mm);
1028 if (old_mm) {1030 if (old_mm) {
1029 mmap_read_unlock(old_mm);1031 mmap_read_unlock(old_mm);
1030 BUG_ON(active_mm != old_mm);1032 BUG_ON(active_mm != old_mm);
fs/ext2/balloc.c+4−3
@@ -126,6 +126,7 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group) · 125 unmodified lines
126 struct ext2_group_desc * desc;126 struct ext2_group_desc * desc;
127 struct buffer_head * bh = NULL;127 struct buffer_head * bh = NULL;
128 ext2_fsblk_t bitmap_blk;128 ext2_fsblk_t bitmap_blk;
129 int ret;
129 130
130 desc = ext2_get_group_desc(sb, block_group, NULL);131 desc = ext2_get_group_desc(sb, block_group, NULL);
131 if (!desc)132 if (!desc)
@@ -139,10 +140,10 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group) · 7 unmodified lines
139 block_group, le32_to_cpu(desc->bg_block_bitmap));140 block_group, le32_to_cpu(desc->bg_block_bitmap));
140 return NULL;141 return NULL;
141 }142 }
142 if (likely(bh_uptodate_or_lock(bh)))143 ret = bh_read(bh, 0);
144 if (ret > 0)
143 return bh;145 return bh;
144 146 if (ret < 0) {
145 if (bh_submit_read(bh) < 0) {
146 brelse(bh);147 brelse(bh);
147 ext2_error(sb, __func__,148 ext2_error(sb, __func__,
148 "Cannot read block bitmap - "149 "Cannot read block bitmap - "
fs/fuse/dev.c+2−1
@@ -776,7 +776,8 @@ static int fuse_check_page(struct page *page) · 775 unmodified lines
776 1 << PG_active |776 1 << PG_active |
777 1 << PG_workingset |777 1 << PG_workingset |
778 1 << PG_reclaim |778 1 << PG_reclaim |
779 1 << PG_waiters))) {779 1 << PG_waiters |
780 LRU_GEN_MASK | LRU_REFS_MASK))) {
780 dump_page(page, "fuse: trying to steal weird page");781 dump_page(page, "fuse: trying to steal weird page");
781 return 1;782 return 1;
782 }783 }
fs/gfs2/meta_io.c+2−5
@@ -525,8 +525,7 @@ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) · 524 unmodified lines
525 525
526 if (buffer_uptodate(first_bh))526 if (buffer_uptodate(first_bh))
527 goto out;527 goto out;
528 if (!buffer_locked(first_bh))528 bh_read_nowait(first_bh, REQ_META | REQ_PRIO);
529 ll_rw_block(REQ_OP_READ | REQ_META | REQ_PRIO, 1, &first_bh);
530 529
531 dblock++;530 dblock++;
532 extlen--;531 extlen--;
@@ -534,9 +533,7 @@ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) · 1 unmodified line
534 while (extlen) {533 while (extlen) {
535 bh = gfs2_getbuf(gl, dblock, CREATE);534 bh = gfs2_getbuf(gl, dblock, CREATE);
536 535
537 if (!buffer_uptodate(bh) && !buffer_locked(bh))536 bh_readahead(bh, REQ_RAHEAD | REQ_META | REQ_PRIO);
538 ll_rw_block(REQ_OP_READ | REQ_RAHEAD | REQ_META |
539 REQ_PRIO, 1, &bh);
540 brelse(bh);537 brelse(bh);
541 dblock++;538 dblock++;
542 extlen--;539 extlen--;
fs/gfs2/quota.c+2−6
@@ -745,12 +745,8 @@ static int gfs2_write_buf_to_page(struct gfs2_inode *ip, unsigned long index, · 744 unmodified lines
745 }745 }
746 if (PageUptodate(page))746 if (PageUptodate(page))
747 set_buffer_uptodate(bh);747 set_buffer_uptodate(bh);
748 if (!buffer_uptodate(bh)) {748 if (bh_read(bh, REQ_META | REQ_PRIO) < 0)
749 ll_rw_block(REQ_OP_READ | REQ_META | REQ_PRIO, 1, &bh);749 goto unlock_out;
750 wait_on_buffer(bh);
751 if (!buffer_uptodate(bh))
752 goto unlock_out;
753 }
754 if (gfs2_is_jdata(ip))750 if (gfs2_is_jdata(ip))
755 gfs2_trans_add_data(ip->i_gl, bh);751 gfs2_trans_add_data(ip->i_gl, bh);
756 else752 else
fs/hugetlbfs/inode.c+214−86
@@ -364,13 +364,155 @@ static int hugetlbfs_write_end(struct file *file, struct address_space *mapping, · 363 unmodified lines
364 return -EINVAL;364 return -EINVAL;
365}365}
366 366
367static void remove_huge_page(struct page *page)367static void hugetlb_delete_from_page_cache(struct page *page)
368{368{
369 ClearPageDirty(page);369 ClearPageDirty(page);
370 ClearPageUptodate(page);370 ClearPageUptodate(page);
371 delete_from_page_cache(page);371 delete_from_page_cache(page);
372}372}
373 373
374/*
375 * Called with i_mmap_rwsem held for inode based vma maps. This makes
376 * sure vma (and vm_mm) will not go away. We also hold the hugetlb fault
377 * mutex for the page in the mapping. So, we can not race with page being
378 * faulted into the vma.
379 */
380static bool hugetlb_vma_maps_page(struct vm_area_struct *vma,
381 unsigned long addr, struct page *page)
382{
383 pte_t *ptep, pte;
384
385 ptep = huge_pte_offset(vma->vm_mm, addr,
386 huge_page_size(hstate_vma(vma)));
387
388 if (!ptep)
389 return false;
390
391 pte = huge_ptep_get(ptep);
392 if (huge_pte_none(pte) || !pte_present(pte))
393 return false;
394
395 if (pte_page(pte) == page)
396 return true;
397
398 return false;
399}
400
401/*
402 * Can vma_offset_start/vma_offset_end overflow on 32-bit arches?
403 * No, because the interval tree returns us only those vmas
404 * which overlap the truncated area starting at pgoff,
405 * and no vma on a 32-bit arch can span beyond the 4GB.
406 */
407static unsigned long vma_offset_start(struct vm_area_struct *vma, pgoff_t start)
408{
409 if (vma->vm_pgoff < start)
410 return (start - vma->vm_pgoff) << PAGE_SHIFT;
411 else
412 return 0;
413}
414
415static unsigned long vma_offset_end(struct vm_area_struct *vma, pgoff_t end)
416{
417 unsigned long t_end;
418
419 if (!end)
420 return vma->vm_end;
421
422 t_end = ((end - vma->vm_pgoff) << PAGE_SHIFT) + vma->vm_start;
423 if (t_end > vma->vm_end)
424 t_end = vma->vm_end;
425 return t_end;
426}
427
428/*
429 * Called with hugetlb fault mutex held. Therefore, no more mappings to
430 * this folio can be created while executing the routine.
431 */
432static void hugetlb_unmap_file_folio(struct hstate *h,
433 struct address_space *mapping,
434 struct folio *folio, pgoff_t index)
435{
436 struct rb_root_cached *root = &mapping->i_mmap;
437 struct hugetlb_vma_lock *vma_lock;
438 struct page *page = &folio->page;
439 struct vm_area_struct *vma;
440 unsigned long v_start;
441 unsigned long v_end;
442 pgoff_t start, end;
443
444 start = index * pages_per_huge_page(h);
445 end = (index + 1) * pages_per_huge_page(h);
446
447 i_mmap_lock_write(mapping);
448retry:
449 vma_lock = NULL;
450 vma_interval_tree_foreach(vma, root, start, end - 1) {
451 v_start = vma_offset_start(vma, start);
452 v_end = vma_offset_end(vma, end);
453
454 if (!hugetlb_vma_maps_page(vma, vma->vm_start + v_start, page))
455 continue;
456
457 if (!hugetlb_vma_trylock_write(vma)) {
458 vma_lock = vma->vm_private_data;
459 /*
460 * If we can not get vma lock, we need to drop
461 * immap_sema and take locks in order. First,
462 * take a ref on the vma_lock structure so that
463 * we can be guaranteed it will not go away when
464 * dropping immap_sema.
465 */
466 kref_get(&vma_lock->refs);
467 break;
468 }
469
470 unmap_hugepage_range(vma, vma->vm_start + v_start, v_end,
471 NULL, ZAP_FLAG_DROP_MARKER);
472 hugetlb_vma_unlock_write(vma);
473 }
474
475 i_mmap_unlock_write(mapping);
476
477 if (vma_lock) {
478 /*
479 * Wait on vma_lock. We know it is still valid as we have
480 * a reference. We must 'open code' vma locking as we do
481 * not know if vma_lock is still attached to vma.
482 */
483 down_write(&vma_lock->rw_sema);
484 i_mmap_lock_write(mapping);
485
486 vma = vma_lock->vma;
487 if (!vma) {
488 /*
489 * If lock is no longer attached to vma, then just
490 * unlock, drop our reference and retry looking for
491 * other vmas.
492 */
493 up_write(&vma_lock->rw_sema);
494 kref_put(&vma_lock->refs, hugetlb_vma_lock_release);
495 goto retry;
496 }
497
498 /*
499 * vma_lock is still attached to vma. Check to see if vma
500 * still maps page and if so, unmap.
501 */
502 v_start = vma_offset_start(vma, start);
503 v_end = vma_offset_end(vma, end);
504 if (hugetlb_vma_maps_page(vma, vma->vm_start + v_start, page))
505 unmap_hugepage_range(vma, vma->vm_start + v_start,
506 v_end, NULL,
507 ZAP_FLAG_DROP_MARKER);
508
509 kref_put(&vma_lock->refs, hugetlb_vma_lock_release);
510 hugetlb_vma_unlock_write(vma);
511
512 goto retry;
513 }
514}
515
374static void516static void
375hugetlb_vmdelete_list(struct rb_root_cached *root, pgoff_t start, pgoff_t end,517hugetlb_vmdelete_list(struct rb_root_cached *root, pgoff_t start, pgoff_t end,
376 zap_flags_t zap_flags)518 zap_flags_t zap_flags)
@@ -383,32 +525,66 @@ hugetlb_vmdelete_list(struct rb_root_cached *root, pgoff_t start, pgoff_t end, · 6 unmodified lines
383 * an inclusive "last".525 * an inclusive "last".
384 */526 */
385 vma_interval_tree_foreach(vma, root, start, end ? end - 1 : ULONG_MAX) {527 vma_interval_tree_foreach(vma, root, start, end ? end - 1 : ULONG_MAX) {
386 unsigned long v_offset;528 unsigned long v_start;
387 unsigned long v_end;529 unsigned long v_end;
388 530
531 if (!hugetlb_vma_trylock_write(vma))
532 continue;
533
534 v_start = vma_offset_start(vma, start);
535 v_end = vma_offset_end(vma, end);
536
537 unmap_hugepage_range(vma, vma->vm_start + v_start, v_end,
538 NULL, zap_flags);
539
389 /*540 /*
390 * Can the expression below overflow on 32-bit arches?541 * Note that vma lock only exists for shared/non-private
391 * No, because the interval tree returns us only those vmas542 * vmas. Therefore, lock is not held when calling
392 * which overlap the truncated area starting at pgoff,543 * unmap_hugepage_range for private vmas.
393 * and no vma on a 32-bit arch can span beyond the 4GB.
394 */544 */
395 if (vma->vm_pgoff < start)545 hugetlb_vma_unlock_write(vma);
396 v_offset = (start - vma->vm_pgoff) << PAGE_SHIFT;546 }
397 else547}
398 v_offset = 0;
399
400 if (!end)
401 v_end = vma->vm_end;
402 else {
403 v_end = ((end - vma->vm_pgoff) << PAGE_SHIFT)
404 + vma->vm_start;
405 if (v_end > vma->vm_end)
406 v_end = vma->vm_end;
407 }
408 548
409 unmap_hugepage_range(vma, vma->vm_start + v_offset, v_end,549/*
410 NULL, zap_flags);550 * Called with hugetlb fault mutex held.
551 * Returns true if page was actually removed, false otherwise.
552 */
553static bool remove_inode_single_folio(struct hstate *h, struct inode *inode,
554 struct address_space *mapping,
555 struct folio *folio, pgoff_t index,
556 bool truncate_op)
557{
558 bool ret = false;
559
560 /*
561 * If folio is mapped, it was faulted in after being
562 * unmapped in caller. Unmap (again) while holding
563 * the fault mutex. The mutex will prevent faults
564 * until we finish removing the folio.
565 */
566 if (unlikely(folio_mapped(folio)))
567 hugetlb_unmap_file_folio(h, mapping, folio, index);
568
569 folio_lock(folio);
570 /*
571 * We must remove the folio from page cache before removing
572 * the region/ reserve map (hugetlb_unreserve_pages). In
573 * rare out of memory conditions, removal of the region/reserve
574 * map could fail. Correspondingly, the subpool and global
575 * reserve usage count can need to be adjusted.
576 */
577 VM_BUG_ON(HPageRestoreReserve(&folio->page));
578 hugetlb_delete_from_page_cache(&folio->page);
579 ret = true;
580 if (!truncate_op) {
581 if (unlikely(hugetlb_unreserve_pages(inode, index,
582 index + 1, 1)))
583 hugetlb_fix_reserve_counts(inode);
411 }584 }
585
586 folio_unlock(folio);
587 return ret;
412}588}
413 589
414/*590/*
@@ -418,10 +594,10 @@ hugetlb_vmdelete_list(struct rb_root_cached *root, pgoff_t start, pgoff_t end, · 3 unmodified lines
418 * truncation is indicated by end of range being LLONG_MAX594 * truncation is indicated by end of range being LLONG_MAX
419 * In this case, we first scan the range and release found pages.595 * In this case, we first scan the range and release found pages.
420 * After releasing pages, hugetlb_unreserve_pages cleans up region/reserve596 * After releasing pages, hugetlb_unreserve_pages cleans up region/reserve
421 * maps and global counts. Page faults can not race with truncation597 * maps and global counts. Page faults can race with truncation.
422 * in this routine. hugetlb_no_page() holds i_mmap_rwsem and prevents598 * During faults, hugetlb_no_page() checks i_size before page allocation,
423 * page faults in the truncated range by checking i_size. i_size is599 * and again after obtaining page table lock. It will 'back out'
424 * modified while holding i_mmap_rwsem.600 * allocations in the truncated range.
425 * hole punch is indicated if end is not LLONG_MAX601 * hole punch is indicated if end is not LLONG_MAX
426 * In the hole punch case we scan the range and release found pages.602 * In the hole punch case we scan the range and release found pages.
427 * Only when releasing a page is the associated region/reserve map603 * Only when releasing a page is the associated region/reserve map
@@ -451,61 +627,17 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart, · 23 unmodified lines
451 u32 hash = 0;627 u32 hash = 0;
452 628
453 index = folio->index;629 index = folio->index;
454 if (!truncate_op) {630 hash = hugetlb_fault_mutex_hash(mapping, index);
455 /*631 mutex_lock(&hugetlb_fault_mutex_table[hash]);
456 * Only need to hold the fault mutex in the
457 * hole punch case. This prevents races with
458 * page faults. Races are not possible in the
459 * case of truncation.
460 */
461 hash = hugetlb_fault_mutex_hash(mapping, index);
462 mutex_lock(&hugetlb_fault_mutex_table[hash]);
463 }
464 632
465 /*633 /*
466 * If folio is mapped, it was faulted in after being634 * Remove folio that was part of folio_batch.
467 * unmapped in caller. Unmap (again) now after taking
468 * the fault mutex. The mutex will prevent faults
469 * until we finish removing the folio.
470 *
471 * This race can only happen in the hole punch case.
472 * Getting here in a truncate operation is a bug.
473 */635 */
474 if (unlikely(folio_mapped(folio))) {636 if (remove_inode_single_folio(h, inode, mapping, folio,
475 BUG_ON(truncate_op);637 index, truncate_op))
476 638 freed++;
477 mutex_unlock(&hugetlb_fault_mutex_table[hash]);639
478 i_mmap_lock_write(mapping);640 mutex_unlock(&hugetlb_fault_mutex_table[hash]);
479 mutex_lock(&hugetlb_fault_mutex_table[hash]);
480 hugetlb_vmdelete_list(&mapping->i_mmap,
481 index * pages_per_huge_page(h),
482 (index + 1) * pages_per_huge_page(h),
483 ZAP_FLAG_DROP_MARKER);
484 i_mmap_unlock_write(mapping);
485 }
486
487 folio_lock(folio);
488 /*
489 * We must free the huge page and remove from page
490 * cache (remove_huge_page) BEFORE removing the
491 * region/reserve map (hugetlb_unreserve_pages). In
492 * rare out of memory conditions, removal of the
493 * region/reserve map could fail. Correspondingly,
494 * the subpool and global reserve usage count can need
495 * to be adjusted.
496 */
497 VM_BUG_ON(HPageRestoreReserve(&folio->page));
498 remove_huge_page(&folio->page);
499 freed++;
500 if (!truncate_op) {
501 if (unlikely(hugetlb_unreserve_pages(inode,
502 index, index + 1, 1)))
503 hugetlb_fix_reserve_counts(inode);
504 }
505
506 folio_unlock(folio);
507 if (!truncate_op)
508 mutex_unlock(&hugetlb_fault_mutex_table[hash]);
509 }641 }
510 folio_batch_release(&fbatch);642 folio_batch_release(&fbatch);
511 cond_resched();643 cond_resched();
@@ -543,8 +675,8 @@ static void hugetlb_vmtruncate(struct inode *inode, loff_t offset) · 31 unmodified lines
543 BUG_ON(offset & ~huge_page_mask(h));675 BUG_ON(offset & ~huge_page_mask(h));
544 pgoff = offset >> PAGE_SHIFT;676 pgoff = offset >> PAGE_SHIFT;
545 677
546 i_mmap_lock_write(mapping);
547 i_size_write(inode, offset);678 i_size_write(inode, offset);
679 i_mmap_lock_write(mapping);
548 if (!RB_EMPTY_ROOT(&mapping->i_mmap.rb_root))680 if (!RB_EMPTY_ROOT(&mapping->i_mmap.rb_root))
549 hugetlb_vmdelete_list(&mapping->i_mmap, pgoff, 0,681 hugetlb_vmdelete_list(&mapping->i_mmap, pgoff, 0,
550 ZAP_FLAG_DROP_MARKER);682 ZAP_FLAG_DROP_MARKER);
@@ -703,11 +835,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset, · 152 unmodified lines
703 /* addr is the offset within the file (zero based) */835 /* addr is the offset within the file (zero based) */
704 addr = index * hpage_size;836 addr = index * hpage_size;
705 837
706 /*838 /* mutex taken here, fault path and hole punch */
707 * fault mutex taken here, protects against fault path
708 * and hole punch. inode_lock previously taken protects
709 * against truncation.
710 */
711 hash = hugetlb_fault_mutex_hash(mapping, index);839 hash = hugetlb_fault_mutex_hash(mapping, index);
712 mutex_lock(&hugetlb_fault_mutex_table[hash]);840 mutex_lock(&hugetlb_fault_mutex_table[hash]);
713 841
@@ -737,7 +865,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset, · 23 unmodified lines
737 }865 }
738 clear_huge_page(page, addr, pages_per_huge_page(h));866 clear_huge_page(page, addr, pages_per_huge_page(h));
739 __SetPageUptodate(page);867 __SetPageUptodate(page);
740 error = huge_add_to_page_cache(page, mapping, index);868 error = hugetlb_add_to_page_cache(page, mapping, index);
741 if (unlikely(error)) {869 if (unlikely(error)) {
742 restore_reserve_on_error(h, &pseudo_vma, addr, page);870 restore_reserve_on_error(h, &pseudo_vma, addr, page);
743 put_page(page);871 put_page(page);
@@ -749,7 +877,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset, · 5 unmodified lines
749 877
750 SetHPageMigratable(page);878 SetHPageMigratable(page);
751 /*879 /*
752 * unlock_page because locked by huge_add_to_page_cache()880 * unlock_page because locked by hugetlb_add_to_page_cache()
753 * put_page() due to reference from alloc_huge_page()881 * put_page() due to reference from alloc_huge_page()
754 */882 */
755 unlock_page(page);883 unlock_page(page);
@@ -994,7 +1122,7 @@ static int hugetlbfs_error_remove_page(struct address_space *mapping, · 238 unmodified lines
994 struct inode *inode = mapping->host;1122 struct inode *inode = mapping->host;
995 pgoff_t index = page->index;1123 pgoff_t index = page->index;
996 1124
997 remove_huge_page(page);1125 hugetlb_delete_from_page_cache(page);
998 if (unlikely(hugetlb_unreserve_pages(inode, index, index + 1, 1)))1126 if (unlikely(hugetlb_unreserve_pages(inode, index, index + 1, 1)))
999 hugetlb_fix_reserve_counts(inode);1127 hugetlb_fix_reserve_counts(inode);
1000 1128
fs/isofs/compress.c+1−1
@@ -82,7 +82,7 @@ static loff_t zisofs_uncompress_block(struct inode *inode, loff_t block_start, · 81 unmodified lines
82 return 0;82 return 0;
83 }83 }
84 haveblocks = isofs_get_blocks(inode, blocknum, bhs, needblocks);84 haveblocks = isofs_get_blocks(inode, blocknum, bhs, needblocks);
85 ll_rw_block(REQ_OP_READ, haveblocks, bhs);85 bh_read_batch(haveblocks, bhs);
86 86
87 curbh = 0;87 curbh = 0;
88 curpage = 0;88 curpage = 0;
fs/jbd2/journal.c+6−9
@@ -1898,19 +1898,16 @@ static int journal_get_superblock(journal_t *journal) · 1897 unmodified lines
1898{1898{
1899 struct buffer_head *bh;1899 struct buffer_head *bh;
1900 journal_superblock_t *sb;1900 journal_superblock_t *sb;
1901 int err = -EIO;1901 int err;
1902 1902
1903 bh = journal->j_sb_buffer;1903 bh = journal->j_sb_buffer;
1904 1904
1905 J_ASSERT(bh != NULL);1905 J_ASSERT(bh != NULL);
1906 if (!buffer_uptodate(bh)) {1906 err = bh_read(bh, 0);
1907 ll_rw_block(REQ_OP_READ, 1, &bh);1907 if (err < 0) {
1908 wait_on_buffer(bh);1908 printk(KERN_ERR
1909 if (!buffer_uptodate(bh)) {1909 "JBD2: IO error reading journal superblock\n");
1910 printk(KERN_ERR1910 goto out;
1911 "JBD2: IO error reading journal superblock\n");
1912 goto out;
1913 }
1914 }1911 }
1915 1912
1916 if (buffer_verified(bh))1913 if (buffer_verified(bh))
fs/jbd2/recovery.c+10−6
@@ -100,7 +100,7 @@ static int do_readahead(journal_t *journal, unsigned int start) · 99 unmodified lines
100 if (!buffer_uptodate(bh) && !buffer_locked(bh)) {100 if (!buffer_uptodate(bh) && !buffer_locked(bh)) {
101 bufs[nbufs++] = bh;101 bufs[nbufs++] = bh;
102 if (nbufs == MAXBUF) {102 if (nbufs == MAXBUF) {
103 ll_rw_block(REQ_OP_READ, nbufs, bufs);103 bh_readahead_batch(nbufs, bufs, 0);
104 journal_brelse_array(bufs, nbufs);104 journal_brelse_array(bufs, nbufs);
105 nbufs = 0;105 nbufs = 0;
106 }106 }
@@ -109,7 +109,7 @@ static int do_readahead(journal_t *journal, unsigned int start) · 2 unmodified lines
109 }109 }
110 110
111 if (nbufs)111 if (nbufs)
112 ll_rw_block(REQ_OP_READ, nbufs, bufs);112 bh_readahead_batch(nbufs, bufs, 0);
113 err = 0;113 err = 0;
114 114
115failed:115failed:
@@ -152,9 +152,14 @@ static int jread(struct buffer_head **bhp, journal_t *journal, · 36 unmodified lines
152 return -ENOMEM;152 return -ENOMEM;
153 153
154 if (!buffer_uptodate(bh)) {154 if (!buffer_uptodate(bh)) {
155 /* If this is a brand new buffer, start readahead.155 /*
156 Otherwise, we assume we are already reading it. */156 * If this is a brand new buffer, start readahead.
157 if (!buffer_req(bh))157 * Otherwise, we assume we are already reading it.
158 */
159 bool need_readahead = !buffer_req(bh);
160
161 bh_read_nowait(bh, 0);
162 if (need_readahead)
158 do_readahead(journal, offset);163 do_readahead(journal, offset);
159 wait_on_buffer(bh);164 wait_on_buffer(bh);
160 }165 }
@@ -688,7 +693,6 @@ static int do_one_pass(journal_t *journal, · 527 unmodified lines
688 mark_buffer_dirty(nbh);693 mark_buffer_dirty(nbh);
689 BUFFER_TRACE(nbh, "marking uptodate");694 BUFFER_TRACE(nbh, "marking uptodate");
690 ++info->nr_replays;695 ++info->nr_replays;
691 /* ll_rw_block(WRITE, 1, &nbh); */
692 unlock_buffer(nbh);696 unlock_buffer(nbh);
693 brelse(obh);697 brelse(obh);
694 brelse(nbh);698 brelse(nbh);
fs/namei.c+1−1
@@ -5088,7 +5088,7 @@ int page_symlink(struct inode *inode, const char *symname, int len) · 5087 unmodified lines
5088 const struct address_space_operations *aops = mapping->a_ops;5088 const struct address_space_operations *aops = mapping->a_ops;
5089 bool nofs = !mapping_gfp_constraint(mapping, __GFP_FS);5089 bool nofs = !mapping_gfp_constraint(mapping, __GFP_FS);
5090 struct page *page;5090 struct page *page;
5091 void *fsdata;5091 void *fsdata = NULL;
5092 int err;5092 int err;
5093 unsigned int flags;5093 unsigned int flags;
5094 5094
fs/nilfs2/page.c+18−27
@@ -480,41 +480,36 @@ unsigned long nilfs_find_uncommitted_extent(struct inode *inode, · 479 unmodified lines
480 sector_t start_blk,480 sector_t start_blk,
481 sector_t *blkoff)481 sector_t *blkoff)
482{482{
483 unsigned int i;483 unsigned int i, nr_folios;
484 pgoff_t index;484 pgoff_t index;
485 unsigned int nblocks_in_page;
486 unsigned long length = 0;485 unsigned long length = 0;
487 sector_t b;486 struct folio_batch fbatch;
488 struct pagevec pvec;487 struct folio *folio;
489 struct page *page;
490 488
491 if (inode->i_mapping->nrpages == 0)489 if (inode->i_mapping->nrpages == 0)
492 return 0;490 return 0;
493 491
494 index = start_blk >> (PAGE_SHIFT - inode->i_blkbits);492 index = start_blk >> (PAGE_SHIFT - inode->i_blkbits);
495 nblocks_in_page = 1U << (PAGE_SHIFT - inode->i_blkbits);
496 493
497 pagevec_init(&pvec);494 folio_batch_init(&fbatch);
498 495
499repeat:496repeat:
500 pvec.nr = find_get_pages_contig(inode->i_mapping, index, PAGEVEC_SIZE,497 nr_folios = filemap_get_folios_contig(inode->i_mapping, &index, ULONG_MAX,
501 pvec.pages);498 &fbatch);
502 if (pvec.nr == 0)499 if (nr_folios == 0)
503 return length;500 return length;
504 501
505 if (length > 0 && pvec.pages[0]->index > index)
506 goto out;
507
508 b = pvec.pages[0]->index << (PAGE_SHIFT - inode->i_blkbits);
509 i = 0;502 i = 0;
510 do {503 do {
511 page = pvec.pages[i];504 folio = fbatch.folios[i];
512 505
513 lock_page(page);506 folio_lock(folio);
514 if (page_has_buffers(page)) {507 if (folio_buffers(folio)) {
515 struct buffer_head *bh, *head;508 struct buffer_head *bh, *head;
509 sector_t b;
516 510
517 bh = head = page_buffers(page);511 b = folio->index << (PAGE_SHIFT - inode->i_blkbits);
512 bh = head = folio_buffers(folio);
518 do {513 do {
519 if (b < start_blk)514 if (b < start_blk)
520 continue;515 continue;
@@ -529,21 +524,17 @@ repeat: · 8 unmodified lines
529 } else {524 } else {
530 if (length > 0)525 if (length > 0)
531 goto out_locked;526 goto out_locked;
532
533 b += nblocks_in_page;
534 }527 }
535 unlock_page(page);528 folio_unlock(folio);
536 529
537 } while (++i < pagevec_count(&pvec));530 } while (++i < nr_folios);
538 531
539 index = page->index + 1;532 folio_batch_release(&fbatch);
540 pagevec_release(&pvec);
541 cond_resched();533 cond_resched();
542 goto repeat;534 goto repeat;
543 535
544out_locked:536out_locked:
545 unlock_page(page);537 folio_unlock(folio);
546out:538 folio_batch_release(&fbatch);
547 pagevec_release(&pvec);
548 return length;539 return length;
549}540}
fs/ntfs3/inode.c+2−5
@@ -630,12 +630,9 @@ static noinline int ntfs_get_block_vbo(struct inode *inode, u64 vbo, · 629 unmodified lines
630 bh->b_size = block_size;630 bh->b_size = block_size;
631 off = vbo & (PAGE_SIZE - 1);631 off = vbo & (PAGE_SIZE - 1);
632 set_bh_page(bh, page, off);632 set_bh_page(bh, page, off);
633 ll_rw_block(REQ_OP_READ, 1, &bh);633 err = bh_read(bh, 0);
634 wait_on_buffer(bh);634 if (err < 0)
635 if (!buffer_uptodate(bh)) {
636 err = -EIO;
637 goto out;635 goto out;
638 }
639 zero_user_segment(page, off + voff, off + block_size);636 zero_user_segment(page, off + voff, off + block_size);
640 }637 }
641 }638 }
fs/ocfs2/aops.c+1−1
@@ -636,7 +636,7 @@ int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno, · 635 unmodified lines
636 !buffer_new(bh) &&636 !buffer_new(bh) &&
637 ocfs2_should_read_blk(inode, page, block_start) &&637 ocfs2_should_read_blk(inode, page, block_start) &&
638 (block_start < from || block_end > to)) {638 (block_start < from || block_end > to)) {
639 ll_rw_block(REQ_OP_READ, 1, &bh);639 bh_read_nowait(bh, 0);
640 *wait_bh++=bh;640 *wait_bh++=bh;
641 }641 }
642 642
fs/ocfs2/super.c+1−3
@@ -1764,9 +1764,7 @@ static int ocfs2_get_sector(struct super_block *sb, · 1763 unmodified lines
1764 if (!buffer_dirty(*bh))1764 if (!buffer_dirty(*bh))
1765 clear_buffer_uptodate(*bh);1765 clear_buffer_uptodate(*bh);
1766 unlock_buffer(*bh);1766 unlock_buffer(*bh);
1767 ll_rw_block(REQ_OP_READ, 1, bh);1767 if (bh_read(*bh, 0) < 0) {
1768 wait_on_buffer(*bh);
1769 if (!buffer_uptodate(*bh)) {
1770 mlog_errno(-EIO);1768 mlog_errno(-EIO);
1771 brelse(*bh);1769 brelse(*bh);
1772 *bh = NULL;1770 *bh = NULL;
fs/posix_acl.c+3−0
@@ -24,6 +24,7 @@ · 23 unmodified lines
24#include <linux/user_namespace.h>24#include <linux/user_namespace.h>
25#include <linux/namei.h>25#include <linux/namei.h>
26#include <linux/mnt_idmapping.h>26#include <linux/mnt_idmapping.h>
27#include <linux/iversion.h>
27 28
28static struct posix_acl **acl_by_type(struct inode *inode, int type)29static struct posix_acl **acl_by_type(struct inode *inode, int type)
29{30{
@@ -1227,6 +1228,8 @@ int simple_set_acl(struct user_namespace *mnt_userns, struct inode *inode, · 1197 unmodified lines
1227 }1228 }
1228 1229
1229 inode->i_ctime = current_time(inode);1230 inode->i_ctime = current_time(inode);
1231 if (IS_I_VERSION(inode))
1232 inode_inc_iversion(inode);
1230 set_cached_acl(inode, type, acl);1233 set_cached_acl(inode, type, acl);
1231 return 0;1234 return 0;
1232}1235}
fs/proc/base.c+19−1
@@ -2350,6 +2350,7 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx) · 2349 unmodified lines
2350 GENRADIX(struct map_files_info) fa;2350 GENRADIX(struct map_files_info) fa;
2351 struct map_files_info *p;2351 struct map_files_info *p;
2352 int ret;2352 int ret;
2353 struct vma_iterator vmi;
2353 2354
2354 genradix_init(&fa);2355 genradix_init(&fa);
2355 2356
@@ -2388,7 +2389,9 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx) · 32 unmodified lines
2388 * routine might require mmap_lock taken in might_fault().2389 * routine might require mmap_lock taken in might_fault().
2389 */2390 */
2390 2391
2391 for (vma = mm->mmap, pos = 2; vma; vma = vma->vm_next) {2392 pos = 2;
2393 vma_iter_init(&vmi, mm, 0);
2394 for_each_vma(vmi, vma) {
2392 if (!vma->vm_file)2395 if (!vma->vm_file)
2393 continue;2396 continue;
2394 if (++pos <= ctx->pos)2397 if (++pos <= ctx->pos)
@@ -3196,6 +3199,19 @@ static int proc_pid_ksm_merging_pages(struct seq_file *m, struct pid_namespace * · 801 unmodified lines
3196 3199
3197 return 0;3200 return 0;
3198}3201}
3202static int proc_pid_ksm_stat(struct seq_file *m, struct pid_namespace *ns,
3203 struct pid *pid, struct task_struct *task)
3204{
3205 struct mm_struct *mm;
3206
3207 mm = get_task_mm(task);
3208 if (mm) {
3209 seq_printf(m, "ksm_rmap_items %lu\n", mm->ksm_rmap_items);
3210 mmput(mm);
3211 }
3212
3213 return 0;
3214}
3199#endif /* CONFIG_KSM */3215#endif /* CONFIG_KSM */
3200 3216
3201#ifdef CONFIG_STACKLEAK_METRICS3217#ifdef CONFIG_STACKLEAK_METRICS
@@ -3331,6 +3347,7 @@ static const struct pid_entry tgid_base_stuff[] = { · 129 unmodified lines
3331#endif3347#endif
3332#ifdef CONFIG_KSM3348#ifdef CONFIG_KSM
3333 ONE("ksm_merging_pages", S_IRUSR, proc_pid_ksm_merging_pages),3349 ONE("ksm_merging_pages", S_IRUSR, proc_pid_ksm_merging_pages),
3350 ONE("ksm_stat", S_IRUSR, proc_pid_ksm_stat),
3334#endif3351#endif
3335};3352};
3336 3353
@@ -3668,6 +3685,7 @@ static const struct pid_entry tid_base_stuff[] = { · 331 unmodified lines
3668#endif3685#endif
3669#ifdef CONFIG_KSM3686#ifdef CONFIG_KSM
3670 ONE("ksm_merging_pages", S_IRUSR, proc_pid_ksm_merging_pages),3687 ONE("ksm_merging_pages", S_IRUSR, proc_pid_ksm_merging_pages),
3688 ONE("ksm_stat", S_IRUSR, proc_pid_ksm_stat),
3671#endif3689#endif
3672};3690};
3673 3691
fs/proc/internal.h+1−1
@@ -285,7 +285,7 @@ struct proc_maps_private { · 284 unmodified lines
285 struct task_struct *task;285 struct task_struct *task;
286 struct mm_struct *mm;286 struct mm_struct *mm;
287#ifdef CONFIG_MMU287#ifdef CONFIG_MMU
288 struct vm_area_struct *tail_vma;288 struct vma_iterator iter;
289#endif289#endif
290#ifdef CONFIG_NUMA290#ifdef CONFIG_NUMA
291 struct mempolicy *task_mempolicy;291 struct mempolicy *task_mempolicy;
fs/proc/task_mmu.c+59−37
@@ -1,6 +1,5 @@
1// SPDX-License-Identifier: GPL-2.01// SPDX-License-Identifier: GPL-2.0
2#include <linux/pagewalk.h>2#include <linux/pagewalk.h>
3#include <linux/vmacache.h>
4#include <linux/mm_inline.h>3#include <linux/mm_inline.h>
5#include <linux/hugetlb.h>4#include <linux/hugetlb.h>
6#include <linux/huge_mm.h>5#include <linux/huge_mm.h>
@@ -124,12 +123,26 @@ static void release_task_mempolicy(struct proc_maps_private *priv) · 117 unmodified lines
124}123}
125#endif124#endif
126 125
126static struct vm_area_struct *proc_get_vma(struct proc_maps_private *priv,
127 loff_t *ppos)
128{
129 struct vm_area_struct *vma = vma_next(&priv->iter);
130
131 if (vma) {
132 *ppos = vma->vm_start;
133 } else {
134 *ppos = -2UL;
135 vma = get_gate_vma(priv->mm);
136 }
137
138 return vma;
139}
140
127static void *m_start(struct seq_file *m, loff_t *ppos)141static void *m_start(struct seq_file *m, loff_t *ppos)
128{142{
129 struct proc_maps_private *priv = m->private;143 struct proc_maps_private *priv = m->private;
130 unsigned long last_addr = *ppos;144 unsigned long last_addr = *ppos;
131 struct mm_struct *mm;145 struct mm_struct *mm;
132 struct vm_area_struct *vma;
133 146
134 /* See m_next(). Zero at the start or after lseek. */147 /* See m_next(). Zero at the start or after lseek. */
135 if (last_addr == -1UL)148 if (last_addr == -1UL)
@@ -153,31 +166,21 @@ static void *m_start(struct seq_file *m, loff_t *ppos) · 17 unmodified lines
153 return ERR_PTR(-EINTR);166 return ERR_PTR(-EINTR);
154 }167 }
155 168
169 vma_iter_init(&priv->iter, mm, last_addr);
156 hold_task_mempolicy(priv);170 hold_task_mempolicy(priv);
157 priv->tail_vma = get_gate_vma(mm);171 if (last_addr == -2UL)
158 172 return get_gate_vma(mm);
159 vma = find_vma(mm, last_addr);
160 if (vma)
161 return vma;
162 173
163 return priv->tail_vma;174 return proc_get_vma(priv, ppos);
164}175}
165 176
166static void *m_next(struct seq_file *m, void *v, loff_t *ppos)177static void *m_next(struct seq_file *m, void *v, loff_t *ppos)
167{178{
168 struct proc_maps_private *priv = m->private;179 if (*ppos == -2UL) {
169 struct vm_area_struct *next, *vma = v;180 *ppos = -1UL;
170 181 return NULL;
171 if (vma == priv->tail_vma)182 }
172 next = NULL;183 return proc_get_vma(m->private, ppos);
173 else if (vma->vm_next)
174 next = vma->vm_next;
175 else
176 next = priv->tail_vma;
177
178 *ppos = next ? next->vm_start : -1UL;
179
180 return next;
181}184}
182 185
183static void m_stop(struct seq_file *m, void *v)186static void m_stop(struct seq_file *m, void *v)
@@ -864,7 +867,7 @@ static int show_smap(struct seq_file *m, void *v) · 680 unmodified lines
864 __show_smap(m, &mss, false);867 __show_smap(m, &mss, false);
865 868
866 seq_printf(m, "THPeligible: %d\n",869 seq_printf(m, "THPeligible: %d\n",
867 hugepage_vma_check(vma, vma->vm_flags, true, false));870 hugepage_vma_check(vma, vma->vm_flags, true, false, true));
868 871
869 if (arch_pkeys_enabled())872 if (arch_pkeys_enabled())
870 seq_printf(m, "ProtectionKey: %8u\n", vma_pkey(vma));873 seq_printf(m, "ProtectionKey: %8u\n", vma_pkey(vma));
@@ -877,16 +880,16 @@ static int show_smaps_rollup(struct seq_file *m, void *v) · 6 unmodified lines
877{880{
878 struct proc_maps_private *priv = m->private;881 struct proc_maps_private *priv = m->private;
879 struct mem_size_stats mss;882 struct mem_size_stats mss;
880 struct mm_struct *mm;883 struct mm_struct *mm = priv->mm;
881 struct vm_area_struct *vma;884 struct vm_area_struct *vma;
882 unsigned long last_vma_end = 0;885 unsigned long vma_start = 0, last_vma_end = 0;
883 int ret = 0;886 int ret = 0;
887 MA_STATE(mas, &mm->mm_mt, 0, 0);
884 888
885 priv->task = get_proc_task(priv->inode);889 priv->task = get_proc_task(priv->inode);
886 if (!priv->task)890 if (!priv->task)
887 return -ESRCH;891 return -ESRCH;
888 892
889 mm = priv->mm;
890 if (!mm || !mmget_not_zero(mm)) {893 if (!mm || !mmget_not_zero(mm)) {
891 ret = -ESRCH;894 ret = -ESRCH;
892 goto out_put_task;895 goto out_put_task;
@@ -899,8 +902,13 @@ static int show_smaps_rollup(struct seq_file *m, void *v) · 6 unmodified lines
899 goto out_put_mm;902 goto out_put_mm;
900 903
901 hold_task_mempolicy(priv);904 hold_task_mempolicy(priv);
905 vma = mas_find(&mas, 0);
906
907 if (unlikely(!vma))
908 goto empty_set;
902 909
903 for (vma = priv->mm->mmap; vma;) {910 vma_start = vma->vm_start;
911 do {
904 smap_gather_stats(vma, &mss, 0);912 smap_gather_stats(vma, &mss, 0);
905 last_vma_end = vma->vm_end;913 last_vma_end = vma->vm_end;
906 914
@@ -909,6 +917,7 @@ static int show_smaps_rollup(struct seq_file *m, void *v) · 2 unmodified lines
909 * access it for write request.917 * access it for write request.
910 */918 */
911 if (mmap_lock_is_contended(mm)) {919 if (mmap_lock_is_contended(mm)) {
920 mas_pause(&mas);
912 mmap_read_unlock(mm);921 mmap_read_unlock(mm);
913 ret = mmap_read_lock_killable(mm);922 ret = mmap_read_lock_killable(mm);
914 if (ret) {923 if (ret) {
@@ -952,7 +961,7 @@ static int show_smaps_rollup(struct seq_file *m, void *v) · 37 unmodified lines
952 * contains last_vma_end.961 * contains last_vma_end.
953 * Iterate VMA' from last_vma_end.962 * Iterate VMA' from last_vma_end.
954 */963 */
955 vma = find_vma(mm, last_vma_end - 1);964 vma = mas_find(&mas, ULONG_MAX);
956 /* Case 3 above */965 /* Case 3 above */
957 if (!vma)966 if (!vma)
958 break;967 break;
@@ -966,11 +975,10 @@ static int show_smaps_rollup(struct seq_file *m, void *v) · 7 unmodified lines
966 smap_gather_stats(vma, &mss, last_vma_end);975 smap_gather_stats(vma, &mss, last_vma_end);
967 }976 }
968 /* Case 2 above */977 /* Case 2 above */
969 vma = vma->vm_next;978 } while ((vma = mas_find(&mas, ULONG_MAX)) != NULL);
970 }
971 979
972 show_vma_header_prefix(m, priv->mm->mmap->vm_start,980empty_set:
973 last_vma_end, 0, 0, 0, 0);981 show_vma_header_prefix(m, vma_start, last_vma_end, 0, 0, 0, 0);
974 seq_pad(m, ' ');982 seq_pad(m, ' ');
975 seq_puts(m, "[rollup]\n");983 seq_puts(m, "[rollup]\n");
976 984
@@ -1263,6 +1271,7 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, · 286 unmodified lines
1263 return -ESRCH;1271 return -ESRCH;
1264 mm = get_task_mm(task);1272 mm = get_task_mm(task);
1265 if (mm) {1273 if (mm) {
1274 MA_STATE(mas, &mm->mm_mt, 0, 0);
1266 struct mmu_notifier_range range;1275 struct mmu_notifier_range range;
1267 struct clear_refs_private cp = {1276 struct clear_refs_private cp = {
1268 .type = type,1277 .type = type,
@@ -1282,7 +1291,7 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, · 13 unmodified lines
1282 }1291 }
1283 1292
1284 if (type == CLEAR_REFS_SOFT_DIRTY) {1293 if (type == CLEAR_REFS_SOFT_DIRTY) {
1285 for (vma = mm->mmap; vma; vma = vma->vm_next) {1294 mas_for_each(&mas, vma, ULONG_MAX) {
1286 if (!(vma->vm_flags & VM_SOFTDIRTY))1295 if (!(vma->vm_flags & VM_SOFTDIRTY))
1287 continue;1296 continue;
1288 vma->vm_flags &= ~VM_SOFTDIRTY;1297 vma->vm_flags &= ~VM_SOFTDIRTY;
@@ -1294,8 +1303,7 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, · 5 unmodified lines
1294 0, NULL, mm, 0, -1UL);1303 0, NULL, mm, 0, -1UL);
1295 mmu_notifier_invalidate_range_start(&range);1304 mmu_notifier_invalidate_range_start(&range);
1296 }1305 }
1297 walk_page_range(mm, 0, mm->highest_vm_end, &clear_refs_walk_ops,1306 walk_page_range(mm, 0, -1, &clear_refs_walk_ops, &cp);
1298 &cp);
1299 if (type == CLEAR_REFS_SOFT_DIRTY) {1307 if (type == CLEAR_REFS_SOFT_DIRTY) {
1300 mmu_notifier_invalidate_range_end(&range);1308 mmu_notifier_invalidate_range_end(&range);
1301 flush_tlb_mm(mm);1309 flush_tlb_mm(mm);
@@ -1418,9 +1426,19 @@ static pagemap_entry_t pte_to_pagemap_entry(struct pagemapread *pm, · 116 unmodified lines
1418 if (pte_swp_uffd_wp(pte))1426 if (pte_swp_uffd_wp(pte))
1419 flags |= PM_UFFD_WP;1427 flags |= PM_UFFD_WP;
1420 entry = pte_to_swp_entry(pte);1428 entry = pte_to_swp_entry(pte);
1421 if (pm->show_pfn)1429 if (pm->show_pfn) {
1430 pgoff_t offset;
1431 /*
1432 * For PFN swap offsets, keeping the offset field
1433 * to be PFN only to be compatible with old smaps.
1434 */
1435 if (is_pfn_swap_entry(entry))
1436 offset = swp_offset_pfn(entry);
1437 else
1438 offset = swp_offset(entry);
1422 frame = swp_type(entry) |1439 frame = swp_type(entry) |
1423 (swp_offset(entry) << MAX_SWAPFILES_SHIFT);1440 (offset << MAX_SWAPFILES_SHIFT);
1441 }
1424 flags |= PM_SWAP;1442 flags |= PM_SWAP;
1425 migration = is_migration_entry(entry);1443 migration = is_migration_entry(entry);
1426 if (is_pfn_swap_entry(entry))1444 if (is_pfn_swap_entry(entry))
@@ -1477,7 +1495,11 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end, · 50 unmodified lines
1477 unsigned long offset;1495 unsigned long offset;
1478 1496
1479 if (pm->show_pfn) {1497 if (pm->show_pfn) {
1480 offset = swp_offset(entry) +1498 if (is_pfn_swap_entry(entry))
1499 offset = swp_offset_pfn(entry);
1500 else
1501 offset = swp_offset(entry);
1502 offset = offset +
1481 ((addr & ~PMD_MASK) >> PAGE_SHIFT);1503 ((addr & ~PMD_MASK) >> PAGE_SHIFT);
1482 frame = swp_type(entry) |1504 frame = swp_type(entry) |
1483 (offset << MAX_SWAPFILES_SHIFT);1505 (offset << MAX_SWAPFILES_SHIFT);
fs/proc/task_nommu.c+21−24
@@ -20,15 +20,13 @@ · 19 unmodified lines
20 */20 */
21void task_mem(struct seq_file *m, struct mm_struct *mm)21void task_mem(struct seq_file *m, struct mm_struct *mm)
22{22{
23 VMA_ITERATOR(vmi, mm, 0);
23 struct vm_area_struct *vma;24 struct vm_area_struct *vma;
24 struct vm_region *region;25 struct vm_region *region;
25 struct rb_node *p;
26 unsigned long bytes = 0, sbytes = 0, slack = 0, size;26 unsigned long bytes = 0, sbytes = 0, slack = 0, size;
27
28 mmap_read_lock(mm);
29 for (p = rb_first(&mm->mm_rb); p; p = rb_next(p)) {
30 vma = rb_entry(p, struct vm_area_struct, vm_rb);
31 27
28 mmap_read_lock(mm);
29 for_each_vma(vmi, vma) {
32 bytes += kobjsize(vma);30 bytes += kobjsize(vma);
33 31
34 region = vma->vm_region;32 region = vma->vm_region;
@@ -82,15 +80,13 @@ void task_mem(struct seq_file *m, struct mm_struct *mm) · 47 unmodified lines
82 80
83unsigned long task_vsize(struct mm_struct *mm)81unsigned long task_vsize(struct mm_struct *mm)
84{82{
83 VMA_ITERATOR(vmi, mm, 0);
85 struct vm_area_struct *vma;84 struct vm_area_struct *vma;
86 struct rb_node *p;
87 unsigned long vsize = 0;85 unsigned long vsize = 0;
88 86
89 mmap_read_lock(mm);87 mmap_read_lock(mm);
90 for (p = rb_first(&mm->mm_rb); p; p = rb_next(p)) {88 for_each_vma(vmi, vma)
91 vma = rb_entry(p, struct vm_area_struct, vm_rb);
92 vsize += vma->vm_end - vma->vm_start;89 vsize += vma->vm_end - vma->vm_start;
93 }
94 mmap_read_unlock(mm);90 mmap_read_unlock(mm);
95 return vsize;91 return vsize;
96}92}
@@ -99,14 +95,13 @@ unsigned long task_statm(struct mm_struct *mm, · 2 unmodified lines
99 unsigned long *shared, unsigned long *text,95 unsigned long *shared, unsigned long *text,
100 unsigned long *data, unsigned long *resident)96 unsigned long *data, unsigned long *resident)
101{97{
98 VMA_ITERATOR(vmi, mm, 0);
102 struct vm_area_struct *vma;99 struct vm_area_struct *vma;
103 struct vm_region *region;100 struct vm_region *region;
104 struct rb_node *p;
105 unsigned long size = kobjsize(mm);101 unsigned long size = kobjsize(mm);
106 102
107 mmap_read_lock(mm);103 mmap_read_lock(mm);
108 for (p = rb_first(&mm->mm_rb); p; p = rb_next(p)) {104 for_each_vma(vmi, vma) {
109 vma = rb_entry(p, struct vm_area_struct, vm_rb);
110 size += kobjsize(vma);105 size += kobjsize(vma);
111 region = vma->vm_region;106 region = vma->vm_region;
112 if (region) {107 if (region) {
@@ -190,17 +185,19 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) · 77 unmodified lines
190 */185 */
191static int show_map(struct seq_file *m, void *_p)186static int show_map(struct seq_file *m, void *_p)
192{187{
193 struct rb_node *p = _p;188 return nommu_vma_show(m, _p);
194
195 return nommu_vma_show(m, rb_entry(p, struct vm_area_struct, vm_rb));
196}189}
197 190
198static void *m_start(struct seq_file *m, loff_t *pos)191static void *m_start(struct seq_file *m, loff_t *pos)
199{192{
200 struct proc_maps_private *priv = m->private;193 struct proc_maps_private *priv = m->private;
201 struct mm_struct *mm;194 struct mm_struct *mm;
202 struct rb_node *p;195 struct vm_area_struct *vma;
203 loff_t n = *pos;196 unsigned long addr = *pos;
197
198 /* See m_next(). Zero at the start or after lseek. */
199 if (addr == -1UL)
200 return NULL;
204 201
205 /* pin the task and mm whilst we play with them */202 /* pin the task and mm whilst we play with them */
206 priv->task = get_proc_task(priv->inode);203 priv->task = get_proc_task(priv->inode);
@@ -216,10 +213,10 @@ static void *m_start(struct seq_file *m, loff_t *pos) · 9 unmodified lines
216 return ERR_PTR(-EINTR);213 return ERR_PTR(-EINTR);
217 }214 }
218 215
219 /* start from the Nth VMA */216 /* start the next element from addr */
220 for (p = rb_first(&mm->mm_rb); p; p = rb_next(p))217 vma = find_vma(mm, addr);
221 if (n-- == 0)218 if (vma)
222 return p;219 return vma;
223 220
224 mmap_read_unlock(mm);221 mmap_read_unlock(mm);
225 mmput(mm);222 mmput(mm);
@@ -242,10 +239,10 @@ static void m_stop(struct seq_file *m, void *_vml) · 16 unmodified lines
242 239
243static void *m_next(struct seq_file *m, void *_p, loff_t *pos)240static void *m_next(struct seq_file *m, void *_p, loff_t *pos)
244{241{
245 struct rb_node *p = _p;242 struct vm_area_struct *vma = _p;
246 243
247 (*pos)++;244 *pos = vma->vm_end;
248 return p ? rb_next(p) : NULL;245 return find_vma(vma->vm_mm, vma->vm_end);
249}246}
250 247
251static const struct seq_operations proc_pid_maps_ops = {248static const struct seq_operations proc_pid_maps_ops = {
fs/ramfs/file-nommu.c+29−21
@@ -203,9 +203,9 @@ static unsigned long ramfs_nommu_get_unmapped_area(struct file *file, · 202 unmodified lines
203 unsigned long addr, unsigned long len,203 unsigned long addr, unsigned long len,
204 unsigned long pgoff, unsigned long flags)204 unsigned long pgoff, unsigned long flags)
205{205{
206 unsigned long maxpages, lpages, nr, loop, ret;206 unsigned long maxpages, lpages, nr_folios, loop, ret, nr_pages, pfn;
207 struct inode *inode = file_inode(file);207 struct inode *inode = file_inode(file);
208 struct page **pages = NULL, **ptr, *page;208 struct folio_batch fbatch;
209 loff_t isize;209 loff_t isize;
210 210
211 /* the mapping mustn't extend beyond the EOF */211 /* the mapping mustn't extend beyond the EOF */
@@ -221,31 +221,39 @@ static unsigned long ramfs_nommu_get_unmapped_area(struct file *file, · 9 unmodified lines
221 goto out;221 goto out;
222 222
223 /* gang-find the pages */223 /* gang-find the pages */
224 pages = kcalloc(lpages, sizeof(struct page *), GFP_KERNEL);224 folio_batch_init(&fbatch);
225 if (!pages)225 nr_pages = 0;
226 goto out_free;226repeat:
227 227 nr_folios = filemap_get_folios_contig(inode->i_mapping, &pgoff,
228 nr = find_get_pages_contig(inode->i_mapping, pgoff, lpages, pages);228 ULONG_MAX, &fbatch);
229 if (nr != lpages)229 if (!nr_folios) {
230 goto out_free_pages; /* leave if some pages were missing */230 ret = -ENOSYS;
231 return ret;
232 }
231 233
234 if (ret == -ENOSYS) {
235 ret = (unsigned long) folio_address(fbatch.folios[0]);
236 pfn = folio_pfn(fbatch.folios[0]);
237 }
232 /* check the pages for physical adjacency */238 /* check the pages for physical adjacency */
233 ptr = pages;239 for (loop = 0; loop < nr_folios; loop++) {
234 page = *ptr++;240 if (pfn + nr_pages != folio_pfn(fbatch.folios[loop])) {
235 page++;241 ret = -ENOSYS;
236 for (loop = lpages; loop > 1; loop--)242 goto out_free; /* leave if not physical adjacent */
237 if (*ptr++ != page++)243 }
238 goto out_free_pages;244 nr_pages += folio_nr_pages(fbatch.folios[loop]);
245 if (nr_pages >= lpages)
246 goto out_free; /* successfully found desired pages*/
247 }
239 248
249 if (nr_pages < lpages) {
250 folio_batch_release(&fbatch);
251 goto repeat; /* loop if pages are missing */
252 }
240 /* okay - all conditions fulfilled */253 /* okay - all conditions fulfilled */
241 ret = (unsigned long) page_address(pages[0]);
242 254
243out_free_pages:
244 ptr = pages;
245 for (loop = nr; loop > 0; loop--)
246 put_page(*ptr++);
247out_free:255out_free:
248 kfree(pages);256 folio_batch_release(&fbatch);
249out:257out:
250 return ret;258 return ret;
251}259}
fs/reiserfs/journal.c+6−5
@@ -868,7 +868,7 @@ loop_next: · 867 unmodified lines
868 */868 */
869 if (buffer_dirty(bh) && unlikely(bh->b_page->mapping == NULL)) {869 if (buffer_dirty(bh) && unlikely(bh->b_page->mapping == NULL)) {
870 spin_unlock(lock);870 spin_unlock(lock);
871 ll_rw_block(REQ_OP_WRITE, 1, &bh);871 write_dirty_buffer(bh, 0);
872 spin_lock(lock);872 spin_lock(lock);
873 }873 }
874 put_bh(bh);874 put_bh(bh);
@@ -1054,7 +1054,7 @@ static int flush_commit_list(struct super_block *s, · 179 unmodified lines
1054 if (tbh) {1054 if (tbh) {
1055 if (buffer_dirty(tbh)) {1055 if (buffer_dirty(tbh)) {
1056 depth = reiserfs_write_unlock_nested(s);1056 depth = reiserfs_write_unlock_nested(s);
1057 ll_rw_block(REQ_OP_WRITE, 1, &tbh);1057 write_dirty_buffer(tbh, 0);
1058 reiserfs_write_lock_nested(s, depth);1058 reiserfs_write_lock_nested(s, depth);
1059 }1059 }
1060 put_bh(tbh) ;1060 put_bh(tbh) ;
@@ -2240,7 +2240,7 @@ abort_replay: · 1179 unmodified lines
2240 }2240 }
2241 }2241 }
2242 /* read in the log blocks, memcpy to the corresponding real block */2242 /* read in the log blocks, memcpy to the corresponding real block */
2243 ll_rw_block(REQ_OP_READ, get_desc_trans_len(desc), log_blocks);2243 bh_read_batch(get_desc_trans_len(desc), log_blocks);
2244 for (i = 0; i < get_desc_trans_len(desc); i++) {2244 for (i = 0; i < get_desc_trans_len(desc); i++) {
2245 2245
2246 wait_on_buffer(log_blocks[i]);2246 wait_on_buffer(log_blocks[i]);
@@ -2342,10 +2342,11 @@ static struct buffer_head *reiserfs_breada(struct block_device *dev, · 95 unmodified lines
2342 } else2342 } else
2343 bhlist[j++] = bh;2343 bhlist[j++] = bh;
2344 }2344 }
2345 ll_rw_block(REQ_OP_READ, j, bhlist);2345 bh = bhlist[0];
2346 bh_read_nowait(bh, 0);
2347 bh_readahead_batch(j - 1, &bhlist[1], 0);
2346 for (i = 1; i < j; i++)2348 for (i = 1; i < j; i++)
2347 brelse(bhlist[i]);2349 brelse(bhlist[i]);
2348 bh = bhlist[0];
2349 wait_on_buffer(bh);2350 wait_on_buffer(bh);
2350 if (buffer_uptodate(bh))2351 if (buffer_uptodate(bh))
2351 return bh;2352 return bh;
fs/reiserfs/stree.c+2−2
@@ -579,7 +579,7 @@ static int search_by_key_reada(struct super_block *s, · 578 unmodified lines
579 if (!buffer_uptodate(bh[j])) {579 if (!buffer_uptodate(bh[j])) {
580 if (depth == -1)580 if (depth == -1)
581 depth = reiserfs_write_unlock_nested(s);581 depth = reiserfs_write_unlock_nested(s);
582 ll_rw_block(REQ_OP_READ | REQ_RAHEAD, 1, bh + j);582 bh_readahead(bh[j], REQ_RAHEAD);
583 }583 }
584 brelse(bh[j]);584 brelse(bh[j]);
585 }585 }
@@ -685,7 +685,7 @@ int search_by_key(struct super_block *sb, const struct cpu_key *key, · 99 unmodified lines
685 if (!buffer_uptodate(bh) && depth == -1)685 if (!buffer_uptodate(bh) && depth == -1)
686 depth = reiserfs_write_unlock_nested(sb);686 depth = reiserfs_write_unlock_nested(sb);
687 687
688 ll_rw_block(REQ_OP_READ, 1, &bh);688 bh_read_nowait(bh, 0);
689 wait_on_buffer(bh);689 wait_on_buffer(bh);
690 690
691 if (depth != -1)691 if (depth != -1)
fs/reiserfs/super.c+1−3
@@ -1702,9 +1702,7 @@ static int read_super_block(struct super_block *s, int offset) · 1701 unmodified lines
1702/* after journal replay, reread all bitmap and super blocks */1702/* after journal replay, reread all bitmap and super blocks */
1703static int reread_meta_blocks(struct super_block *s)1703static int reread_meta_blocks(struct super_block *s)
1704{1704{
1705 ll_rw_block(REQ_OP_READ, 1, &SB_BUFFER_WITH_SB(s));1705 if (bh_read(SB_BUFFER_WITH_SB(s), 0) < 0) {
1706 wait_on_buffer(SB_BUFFER_WITH_SB(s));
1707 if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) {
1708 reiserfs_warning(s, "reiserfs-2504", "error reading the super");1706 reiserfs_warning(s, "reiserfs-2504", "error reading the super");
1709 return 1;1707 return 1;
1710 }1708 }
fs/udf/dir.c+1−1
@@ -130,7 +130,7 @@ static int udf_readdir(struct file *file, struct dir_context *ctx) · 129 unmodified lines
130 brelse(tmp);130 brelse(tmp);
131 }131 }
132 if (num) {132 if (num) {
133 ll_rw_block(REQ_OP_READ | REQ_RAHEAD, num, bha);133 bh_readahead_batch(num, bha, REQ_RAHEAD);
134 for (i = 0; i < num; i++)134 for (i = 0; i < num; i++)
135 brelse(bha[i]);135 brelse(bha[i]);
136 }136 }
fs/udf/directory.c+1−1
@@ -89,7 +89,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos, · 88 unmodified lines
89 brelse(tmp);89 brelse(tmp);
90 }90 }
91 if (num) {91 if (num) {
92 ll_rw_block(REQ_OP_READ | REQ_RAHEAD, num, bha);92 bh_readahead_batch(num, bha, REQ_RAHEAD);
93 for (i = 0; i < num; i++)93 for (i = 0; i < num; i++)
94 brelse(bha[i]);94 brelse(bha[i]);
95 }95 }
fs/udf/inode.c+1−7
@@ -1211,13 +1211,7 @@ struct buffer_head *udf_bread(struct inode *inode, udf_pblk_t block, · 1210 unmodified lines
1211 if (!bh)1211 if (!bh)
1212 return NULL;1212 return NULL;
1213 1213
1214 if (buffer_uptodate(bh))1214 if (bh_read(bh, 0) >= 0)
1215 return bh;
1216
1217 ll_rw_block(REQ_OP_READ, 1, &bh);
1218
1219 wait_on_buffer(bh);
1220 if (buffer_uptodate(bh))
1221 return bh;1215 return bh;
1222 1216
1223 brelse(bh);1217 brelse(bh);
fs/ufs/balloc.c+4−8
@@ -295,14 +295,10 @@ static void ufs_change_blocknr(struct inode *inode, sector_t beg, · 294 unmodified lines
295 295
296 if (!buffer_mapped(bh))296 if (!buffer_mapped(bh))
297 map_bh(bh, inode->i_sb, oldb + pos);297 map_bh(bh, inode->i_sb, oldb + pos);
298 if (!buffer_uptodate(bh)) {298 if (bh_read(bh, 0) < 0) {
299 ll_rw_block(REQ_OP_READ, 1, &bh);299 ufs_error(inode->i_sb, __func__,
300 wait_on_buffer(bh);300 "read of block failed\n");
301 if (!buffer_uptodate(bh)) {301 break;
302 ufs_error(inode->i_sb, __func__,
303 "read of block failed\n");
304 break;
305 }
306 }302 }
307 303
308 UFSD(" change from %llu to %llu, pos %u\n",304 UFSD(" change from %llu to %llu, pos %u\n",
fs/userfaultfd.c+97−36
@@ -30,6 +30,7 @@ · 29 unmodified lines
30#include <linux/security.h>30#include <linux/security.h>
31#include <linux/hugetlb.h>31#include <linux/hugetlb.h>
32#include <linux/swapops.h>32#include <linux/swapops.h>
33#include <linux/miscdevice.h>
33 34
34int sysctl_unprivileged_userfaultfd __read_mostly;35int sysctl_unprivileged_userfaultfd __read_mostly;
35 36
@@ -415,13 +416,8 @@ vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason) · 379 unmodified lines
415 416
416 if (ctx->features & UFFD_FEATURE_SIGBUS)417 if (ctx->features & UFFD_FEATURE_SIGBUS)
417 goto out;418 goto out;
418 if ((vmf->flags & FAULT_FLAG_USER) == 0 &&419 if (!(vmf->flags & FAULT_FLAG_USER) && (ctx->flags & UFFD_USER_MODE_ONLY))
419 ctx->flags & UFFD_USER_MODE_ONLY) {
420 printk_once(KERN_WARNING "uffd: Set unprivileged_userfaultfd "
421 "sysctl knob to 1 if kernel faults must be handled "
422 "without obtaining CAP_SYS_PTRACE capability\n");
423 goto out;420 goto out;
424 }
425 421
426 /*422 /*
427 * If it's already released don't get it. This avoids to loop423 * If it's already released don't get it. This avoids to loop
@@ -615,14 +611,16 @@ static void userfaultfd_event_wait_completion(struct userfaultfd_ctx *ctx, · 187 unmodified lines
615 if (release_new_ctx) {611 if (release_new_ctx) {
616 struct vm_area_struct *vma;612 struct vm_area_struct *vma;
617 struct mm_struct *mm = release_new_ctx->mm;613 struct mm_struct *mm = release_new_ctx->mm;
614 VMA_ITERATOR(vmi, mm, 0);
618 615
619 /* the various vma->vm_userfaultfd_ctx still points to it */616 /* the various vma->vm_userfaultfd_ctx still points to it */
620 mmap_write_lock(mm);617 mmap_write_lock(mm);
621 for (vma = mm->mmap; vma; vma = vma->vm_next)618 for_each_vma(vmi, vma) {
622 if (vma->vm_userfaultfd_ctx.ctx == release_new_ctx) {619 if (vma->vm_userfaultfd_ctx.ctx == release_new_ctx) {
623 vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX;620 vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX;
624 vma->vm_flags &= ~__VM_UFFD_FLAGS;621 vma->vm_flags &= ~__VM_UFFD_FLAGS;
625 }622 }
623 }
626 mmap_write_unlock(mm);624 mmap_write_unlock(mm);
627 625
628 userfaultfd_ctx_put(release_new_ctx);626 userfaultfd_ctx_put(release_new_ctx);
@@ -803,11 +801,13 @@ static bool has_unmap_ctx(struct userfaultfd_ctx *ctx, struct list_head *unmaps, · 174 unmodified lines
803 return false;801 return false;
804}802}
805 803
806int userfaultfd_unmap_prep(struct vm_area_struct *vma,804int userfaultfd_unmap_prep(struct mm_struct *mm, unsigned long start,
807 unsigned long start, unsigned long end,805 unsigned long end, struct list_head *unmaps)
808 struct list_head *unmaps)
809{806{
810 for ( ; vma && vma->vm_start < end; vma = vma->vm_next) {807 VMA_ITERATOR(vmi, mm, start);
808 struct vm_area_struct *vma;
809
810 for_each_vma_range(vmi, vma, end) {
811 struct userfaultfd_unmap_ctx *unmap_ctx;811 struct userfaultfd_unmap_ctx *unmap_ctx;
812 struct userfaultfd_ctx *ctx = vma->vm_userfaultfd_ctx.ctx;812 struct userfaultfd_ctx *ctx = vma->vm_userfaultfd_ctx.ctx;
813 813
@@ -857,6 +857,7 @@ static int userfaultfd_release(struct inode *inode, struct file *file) · 43 unmodified lines
857 /* len == 0 means wake all */857 /* len == 0 means wake all */
858 struct userfaultfd_wake_range range = { .len = 0, };858 struct userfaultfd_wake_range range = { .len = 0, };
859 unsigned long new_flags;859 unsigned long new_flags;
860 MA_STATE(mas, &mm->mm_mt, 0, 0);
860 861
861 WRITE_ONCE(ctx->released, true);862 WRITE_ONCE(ctx->released, true);
862 863
@@ -873,7 +874,7 @@ static int userfaultfd_release(struct inode *inode, struct file *file) · 10 unmodified lines
873 */874 */
874 mmap_write_lock(mm);875 mmap_write_lock(mm);
875 prev = NULL;876 prev = NULL;
876 for (vma = mm->mmap; vma; vma = vma->vm_next) {877 mas_for_each(&mas, vma, ULONG_MAX) {
877 cond_resched();878 cond_resched();
878 BUG_ON(!!vma->vm_userfaultfd_ctx.ctx ^879 BUG_ON(!!vma->vm_userfaultfd_ctx.ctx ^
879 !!(vma->vm_flags & __VM_UFFD_FLAGS));880 !!(vma->vm_flags & __VM_UFFD_FLAGS));
@@ -887,10 +888,13 @@ static int userfaultfd_release(struct inode *inode, struct file *file) · 7 unmodified lines
887 vma->vm_file, vma->vm_pgoff,888 vma->vm_file, vma->vm_pgoff,
888 vma_policy(vma),889 vma_policy(vma),
889 NULL_VM_UFFD_CTX, anon_vma_name(vma));890 NULL_VM_UFFD_CTX, anon_vma_name(vma));
890 if (prev)891 if (prev) {
892 mas_pause(&mas);
891 vma = prev;893 vma = prev;
892 else894 } else {
893 prev = vma;895 prev = vma;
896 }
897
894 vma->vm_flags = new_flags;898 vma->vm_flags = new_flags;
895 vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX;899 vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX;
896 }900 }
@@ -1272,6 +1276,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, · 375 unmodified lines
1272 bool found;1276 bool found;
1273 bool basic_ioctls;1277 bool basic_ioctls;
1274 unsigned long start, end, vma_end;1278 unsigned long start, end, vma_end;
1279 MA_STATE(mas, &mm->mm_mt, 0, 0);
1275 1280
1276 user_uffdio_register = (struct uffdio_register __user *) arg;1281 user_uffdio_register = (struct uffdio_register __user *) arg;
1277 1282
@@ -1314,7 +1319,8 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, · 36 unmodified lines
1314 goto out;1319 goto out;
1315 1320
1316 mmap_write_lock(mm);1321 mmap_write_lock(mm);
1317 vma = find_vma_prev(mm, start, &prev);1322 mas_set(&mas, start);
1323 vma = mas_find(&mas, ULONG_MAX);
1318 if (!vma)1324 if (!vma)
1319 goto out_unlock;1325 goto out_unlock;
1320 1326
@@ -1339,7 +1345,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, · 18 unmodified lines
1339 */1345 */
1340 found = false;1346 found = false;
1341 basic_ioctls = false;1347 basic_ioctls = false;
1342 for (cur = vma; cur && cur->vm_start < end; cur = cur->vm_next) {1348 for (cur = vma; cur; cur = mas_next(&mas, end - 1)) {
1343 cond_resched();1349 cond_resched();
1344 1350
1345 BUG_ON(!!cur->vm_userfaultfd_ctx.ctx ^1351 BUG_ON(!!cur->vm_userfaultfd_ctx.ctx ^
@@ -1399,8 +1405,10 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, · 53 unmodified lines
1399 }1405 }
1400 BUG_ON(!found);1406 BUG_ON(!found);
1401 1407
1402 if (vma->vm_start < start)1408 mas_set(&mas, start);
1403 prev = vma;1409 prev = mas_prev(&mas, 0);
1410 if (prev != vma)
1411 mas_next(&mas, ULONG_MAX);
1404 1412
1405 ret = 0;1413 ret = 0;
1406 do {1414 do {
@@ -1430,6 +1438,8 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, · 23 unmodified lines
1430 ((struct vm_userfaultfd_ctx){ ctx }),1438 ((struct vm_userfaultfd_ctx){ ctx }),
1431 anon_vma_name(vma));1439 anon_vma_name(vma));
1432 if (prev) {1440 if (prev) {
1441 /* vma_merge() invalidated the mas */
1442 mas_pause(&mas);
1433 vma = prev;1443 vma = prev;
1434 goto next;1444 goto next;
1435 }1445 }
@@ -1437,11 +1447,15 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, · 1 unmodified line
1437 ret = split_vma(mm, vma, start, 1);1447 ret = split_vma(mm, vma, start, 1);
1438 if (ret)1448 if (ret)
1439 break;1449 break;
1450 /* split_vma() invalidated the mas */
1451 mas_pause(&mas);
1440 }1452 }
1441 if (vma->vm_end > end) {1453 if (vma->vm_end > end) {
1442 ret = split_vma(mm, vma, end, 0);1454 ret = split_vma(mm, vma, end, 0);
1443 if (ret)1455 if (ret)
1444 break;1456 break;
1457 /* split_vma() invalidated the mas */
1458 mas_pause(&mas);
1445 }1459 }
1446 next:1460 next:
1447 /*1461 /*
@@ -1458,8 +1472,8 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, · 10 unmodified lines
1458 skip:1472 skip:
1459 prev = vma;1473 prev = vma;
1460 start = vma->vm_end;1474 start = vma->vm_end;
1461 vma = vma->vm_next;1475 vma = mas_next(&mas, end - 1);
1462 } while (vma && vma->vm_start < end);1476 } while (vma);
1463out_unlock:1477out_unlock:
1464 mmap_write_unlock(mm);1478 mmap_write_unlock(mm);
1465 mmput(mm);1479 mmput(mm);
@@ -1503,6 +1517,7 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx, · 37 unmodified lines
1503 bool found;1517 bool found;
1504 unsigned long start, end, vma_end;1518 unsigned long start, end, vma_end;
1505 const void __user *buf = (void __user *)arg;1519 const void __user *buf = (void __user *)arg;
1520 MA_STATE(mas, &mm->mm_mt, 0, 0);
1506 1521
1507 ret = -EFAULT;1522 ret = -EFAULT;
1508 if (copy_from_user(&uffdio_unregister, buf, sizeof(uffdio_unregister)))1523 if (copy_from_user(&uffdio_unregister, buf, sizeof(uffdio_unregister)))
@@ -1521,7 +1536,8 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx, · 12 unmodified lines
1521 goto out;1536 goto out;
1522 1537
1523 mmap_write_lock(mm);1538 mmap_write_lock(mm);
1524 vma = find_vma_prev(mm, start, &prev);1539 mas_set(&mas, start);
1540 vma = mas_find(&mas, ULONG_MAX);
1525 if (!vma)1541 if (!vma)
1526 goto out_unlock;1542 goto out_unlock;
1527 1543
@@ -1546,7 +1562,7 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx, · 18 unmodified lines
1546 */1562 */
1547 found = false;1563 found = false;
1548 ret = -EINVAL;1564 ret = -EINVAL;
1549 for (cur = vma; cur && cur->vm_start < end; cur = cur->vm_next) {1565 for (cur = vma; cur; cur = mas_next(&mas, end - 1)) {
1550 cond_resched();1566 cond_resched();
1551 1567
1552 BUG_ON(!!cur->vm_userfaultfd_ctx.ctx ^1568 BUG_ON(!!cur->vm_userfaultfd_ctx.ctx ^
@@ -1566,8 +1582,10 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx, · 13 unmodified lines
1566 }1582 }
1567 BUG_ON(!found);1583 BUG_ON(!found);
1568 1584
1569 if (vma->vm_start < start)1585 mas_set(&mas, start);
1570 prev = vma;1586 prev = mas_prev(&mas, 0);
1587 if (prev != vma)
1588 mas_next(&mas, ULONG_MAX);
1571 1589
1572 ret = 0;1590 ret = 0;
1573 do {1591 do {
@@ -1636,8 +1654,8 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx, · 62 unmodified lines
1636 skip:1654 skip:
1637 prev = vma;1655 prev = vma;
1638 start = vma->vm_end;1656 start = vma->vm_end;
1639 vma = vma->vm_next;1657 vma = mas_next(&mas, end - 1);
1640 } while (vma && vma->vm_start < end);1658 } while (vma);
1641out_unlock:1659out_unlock:
1642 mmap_write_unlock(mm);1660 mmap_write_unlock(mm);
1643 mmput(mm);1661 mmput(mm);
@@ -2056,20 +2074,11 @@ static void init_once_userfaultfd_ctx(void *mem) · 412 unmodified lines
2056 seqcount_spinlock_init(&ctx->refile_seq, &ctx->fault_pending_wqh.lock);2074 seqcount_spinlock_init(&ctx->refile_seq, &ctx->fault_pending_wqh.lock);
2057}2075}
2058 2076
2059SYSCALL_DEFINE1(userfaultfd, int, flags)2077static int new_userfaultfd(int flags)
2060{2078{
2061 struct userfaultfd_ctx *ctx;2079 struct userfaultfd_ctx *ctx;
2062 int fd;2080 int fd;
2063 2081
2064 if (!sysctl_unprivileged_userfaultfd &&
2065 (flags & UFFD_USER_MODE_ONLY) == 0 &&
2066 !capable(CAP_SYS_PTRACE)) {
2067 printk_once(KERN_WARNING "uffd: Set unprivileged_userfaultfd "
2068 "sysctl knob to 1 if kernel faults must be handled "
2069 "without obtaining CAP_SYS_PTRACE capability\n");
2070 return -EPERM;
2071 }
2072
2073 BUG_ON(!current->mm);2082 BUG_ON(!current->mm);
2074 2083
2075 /* Check the UFFD_* constants for consistency. */2084 /* Check the UFFD_* constants for consistency. */
@@ -2102,8 +2111,60 @@ SYSCALL_DEFINE1(userfaultfd, int, flags) · 26 unmodified lines
2102 return fd;2111 return fd;
2103}2112}
2104 2113
2114static inline bool userfaultfd_syscall_allowed(int flags)
2115{
2116 /* Userspace-only page faults are always allowed */
2117 if (flags & UFFD_USER_MODE_ONLY)
2118 return true;
2119
2120 /*
2121 * The user is requesting a userfaultfd which can handle kernel faults.
2122 * Privileged users are always allowed to do this.
2123 */
2124 if (capable(CAP_SYS_PTRACE))
2125 return true;
2126
2127 /* Otherwise, access to kernel fault handling is sysctl controlled. */
2128 return sysctl_unprivileged_userfaultfd;
2129}
2130
2131SYSCALL_DEFINE1(userfaultfd, int, flags)
2132{
2133 if (!userfaultfd_syscall_allowed(flags))
2134 return -EPERM;
2135
2136 return new_userfaultfd(flags);
2137}
2138
2139static long userfaultfd_dev_ioctl(struct file *file, unsigned int cmd, unsigned long flags)
2140{
2141 if (cmd != USERFAULTFD_IOC_NEW)
2142 return -EINVAL;
2143
2144 return new_userfaultfd(flags);
2145}
2146
2147static const struct file_operations userfaultfd_dev_fops = {
2148 .unlocked_ioctl = userfaultfd_dev_ioctl,
2149 .compat_ioctl = userfaultfd_dev_ioctl,
2150 .owner = THIS_MODULE,
2151 .llseek = noop_llseek,
2152};
2153
2154static struct miscdevice userfaultfd_misc = {
2155 .minor = MISC_DYNAMIC_MINOR,
2156 .name = "userfaultfd",
2157 .fops = &userfaultfd_dev_fops
2158};
2159
2105static int __init userfaultfd_init(void)2160static int __init userfaultfd_init(void)
2106{2161{
2162 int ret;
2163
2164 ret = misc_register(&userfaultfd_misc);
2165 if (ret)
2166 return ret;
2167
2107 userfaultfd_ctx_cachep = kmem_cache_create("userfaultfd_ctx_cache",2168 userfaultfd_ctx_cachep = kmem_cache_create("userfaultfd_ctx_cache",
2108 sizeof(struct userfaultfd_ctx),2169 sizeof(struct userfaultfd_ctx),
2109 0,2170 0,
include/asm-generic/cacheflush.h+12−2
@@ -2,6 +2,8 @@ · 1 unmodified line
2#ifndef _ASM_GENERIC_CACHEFLUSH_H2#ifndef _ASM_GENERIC_CACHEFLUSH_H
3#define _ASM_GENERIC_CACHEFLUSH_H3#define _ASM_GENERIC_CACHEFLUSH_H
4 4
5#include <linux/instrumented.h>
6
5struct mm_struct;7struct mm_struct;
6struct vm_area_struct;8struct vm_area_struct;
7struct page;9struct page;
@@ -105,14 +107,22 @@ static inline void flush_cache_vunmap(unsigned long start, unsigned long end) · 97 unmodified lines
105#ifndef copy_to_user_page107#ifndef copy_to_user_page
106#define copy_to_user_page(vma, page, vaddr, dst, src, len) \108#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
107 do { \109 do { \
110 instrument_copy_to_user((void __user *)dst, src, len); \
108 memcpy(dst, src, len); \111 memcpy(dst, src, len); \
109 flush_icache_user_page(vma, page, vaddr, len); \112 flush_icache_user_page(vma, page, vaddr, len); \
110 } while (0)113 } while (0)
111#endif114#endif
112 115
116
113#ifndef copy_from_user_page117#ifndef copy_from_user_page
114#define copy_from_user_page(vma, page, vaddr, dst, src, len) \118#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
115 memcpy(dst, src, len)119 do { \
120 instrument_copy_from_user_before(dst, (void __user *)src, \
121 len); \
122 memcpy(dst, src, len); \
123 instrument_copy_from_user_after(dst, (void __user *)src, len, \
124 0); \
125 } while (0)
116#endif126#endif
117 127
118#endif /* _ASM_GENERIC_CACHEFLUSH_H */128#endif /* _ASM_GENERIC_CACHEFLUSH_H */
include/linux/buffer_head.h+38−10
@@ -225,8 +225,6 @@ struct buffer_head *__getblk_gfp(struct block_device *bdev, sector_t block, · 224 unmodified lines
225void __brelse(struct buffer_head *);225void __brelse(struct buffer_head *);
226void __bforget(struct buffer_head *);226void __bforget(struct buffer_head *);
227void __breadahead(struct block_device *, sector_t block, unsigned int size);227void __breadahead(struct block_device *, sector_t block, unsigned int size);
228void __breadahead_gfp(struct block_device *, sector_t block, unsigned int size,
229 gfp_t gfp);
230struct buffer_head *__bread_gfp(struct block_device *,228struct buffer_head *__bread_gfp(struct block_device *,
231 sector_t block, unsigned size, gfp_t gfp);229 sector_t block, unsigned size, gfp_t gfp);
232void invalidate_bh_lrus(void);230void invalidate_bh_lrus(void);
@@ -236,7 +234,6 @@ struct buffer_head *alloc_buffer_head(gfp_t gfp_flags); · 3 unmodified lines
236void free_buffer_head(struct buffer_head * bh);234void free_buffer_head(struct buffer_head * bh);
237void unlock_buffer(struct buffer_head *bh);235void unlock_buffer(struct buffer_head *bh);
238void __lock_buffer(struct buffer_head *bh);236void __lock_buffer(struct buffer_head *bh);
239void ll_rw_block(blk_opf_t, int, struct buffer_head * bh[]);
240int sync_dirty_buffer(struct buffer_head *bh);237int sync_dirty_buffer(struct buffer_head *bh);
241int __sync_dirty_buffer(struct buffer_head *bh, blk_opf_t op_flags);238int __sync_dirty_buffer(struct buffer_head *bh, blk_opf_t op_flags);
242void write_dirty_buffer(struct buffer_head *bh, blk_opf_t op_flags);239void write_dirty_buffer(struct buffer_head *bh, blk_opf_t op_flags);
@@ -244,7 +241,9 @@ void submit_bh(blk_opf_t, struct buffer_head *); · 1 unmodified line
244void write_boundary_block(struct block_device *bdev,241void write_boundary_block(struct block_device *bdev,
245 sector_t bblock, unsigned blocksize);242 sector_t bblock, unsigned blocksize);
246int bh_uptodate_or_lock(struct buffer_head *bh);243int bh_uptodate_or_lock(struct buffer_head *bh);
247int bh_submit_read(struct buffer_head *bh);244int __bh_read(struct buffer_head *bh, blk_opf_t op_flags, bool wait);
245void __bh_read_batch(int nr, struct buffer_head *bhs[],
246 blk_opf_t op_flags, bool force_lock);
248 247
249extern int buffer_heads_over_limit;248extern int buffer_heads_over_limit;
250 249
@@ -351,12 +350,6 @@ sb_breadahead(struct super_block *sb, sector_t block) · 100 unmodified lines
351 __breadahead(sb->s_bdev, block, sb->s_blocksize);350 __breadahead(sb->s_bdev, block, sb->s_blocksize);
352}351}
353 352
354static inline void
355sb_breadahead_unmovable(struct super_block *sb, sector_t block)
356{
357 __breadahead_gfp(sb->s_bdev, block, sb->s_blocksize, 0);
358}
359
360static inline struct buffer_head *353static inline struct buffer_head *
361sb_getblk(struct super_block *sb, sector_t block)354sb_getblk(struct super_block *sb, sector_t block)
362{355{
@@ -418,6 +411,41 @@ static inline struct buffer_head *__getblk(struct block_device *bdev, · 55 unmodified lines
418 return __getblk_gfp(bdev, block, size, __GFP_MOVABLE);411 return __getblk_gfp(bdev, block, size, __GFP_MOVABLE);
419}412}
420 413
414static inline void bh_readahead(struct buffer_head *bh, blk_opf_t op_flags)
415{
416 if (!buffer_uptodate(bh) && trylock_buffer(bh)) {
417 if (!buffer_uptodate(bh))
418 __bh_read(bh, op_flags, false);
419 else
420 unlock_buffer(bh);
421 }
422}
423
424static inline void bh_read_nowait(struct buffer_head *bh, blk_opf_t op_flags)
425{
426 if (!bh_uptodate_or_lock(bh))
427 __bh_read(bh, op_flags, false);
428}
429
430/* Returns 1 if buffer uptodated, 0 on success, and -EIO on error. */
431static inline int bh_read(struct buffer_head *bh, blk_opf_t op_flags)
432{
433 if (bh_uptodate_or_lock(bh))
434 return 1;
435 return __bh_read(bh, op_flags, true);
436}
437
438static inline void bh_read_batch(int nr, struct buffer_head *bhs[])
439{
440 __bh_read_batch(nr, bhs, 0, true);
441}
442
443static inline void bh_readahead_batch(int nr, struct buffer_head *bhs[],
444 blk_opf_t op_flags)
445{
446 __bh_read_batch(nr, bhs, op_flags, false);
447}
448
421/**449/**
422 * __bread() - reads a specified block and returns the bh450 * __bread() - reads a specified block and returns the bh
423 * @bdev: the block_device to read from451 * @bdev: the block_device to read from
include/linux/cache.h+13−0
@@ -85,4 +85,17 @@ · 84 unmodified lines
85#define cache_line_size() L1_CACHE_BYTES85#define cache_line_size() L1_CACHE_BYTES
86#endif86#endif
87 87
88/*
89 * Helper to add padding within a struct to ensure data fall into separate
90 * cachelines.
91 */
92#if defined(CONFIG_SMP)
93struct cacheline_padding {
94 char x[0];
95} ____cacheline_internodealigned_in_smp;
96#define CACHELINE_PADDING(name) struct cacheline_padding name
97#else
98#define CACHELINE_PADDING(name)
99#endif
100
88#endif /* __LINUX_CACHE_H */101#endif /* __LINUX_CACHE_H */
include/linux/cgroup.h+14−1
@@ -433,6 +433,18 @@ static inline void cgroup_put(struct cgroup *cgrp) · 432 unmodified lines
433 css_put(&cgrp->self);433 css_put(&cgrp->self);
434}434}
435 435
436extern struct mutex cgroup_mutex;
437
438static inline void cgroup_lock(void)
439{
440 mutex_lock(&cgroup_mutex);
441}
442
443static inline void cgroup_unlock(void)
444{
445 mutex_unlock(&cgroup_mutex);
446}
447
436/**448/**
437 * task_css_set_check - obtain a task's css_set with extra access conditions449 * task_css_set_check - obtain a task's css_set with extra access conditions
438 * @task: the task to obtain css_set for450 * @task: the task to obtain css_set for
@@ -447,7 +459,6 @@ static inline void cgroup_put(struct cgroup *cgrp) · 8 unmodified lines
447 * as locks used during the cgroup_subsys::attach() methods.459 * as locks used during the cgroup_subsys::attach() methods.
448 */460 */
449#ifdef CONFIG_PROVE_RCU461#ifdef CONFIG_PROVE_RCU
450extern struct mutex cgroup_mutex;
451extern spinlock_t css_set_lock;462extern spinlock_t css_set_lock;
452#define task_css_set_check(task, __c) \463#define task_css_set_check(task, __c) \
453 rcu_dereference_check((task)->cgroups, \464 rcu_dereference_check((task)->cgroups, \
@@ -707,6 +718,8 @@ struct cgroup; · 253 unmodified lines
707static inline u64 cgroup_id(const struct cgroup *cgrp) { return 1; }718static inline u64 cgroup_id(const struct cgroup *cgrp) { return 1; }
708static inline void css_get(struct cgroup_subsys_state *css) {}719static inline void css_get(struct cgroup_subsys_state *css) {}
709static inline void css_put(struct cgroup_subsys_state *css) {}720static inline void css_put(struct cgroup_subsys_state *css) {}
721static inline void cgroup_lock(void) {}
722static inline void cgroup_unlock(void) {}
710static inline int cgroup_attach_task_all(struct task_struct *from,723static inline int cgroup_attach_task_all(struct task_struct *from,
711 struct task_struct *t) { return 0; }724 struct task_struct *t) { return 0; }
712static inline int cgroupstats_build(struct cgroupstats *stats,725static inline int cgroupstats_build(struct cgroupstats *stats,
include/linux/compiler-clang.h+23−0
@@ -51,6 +51,29 @@ · 50 unmodified lines
51#define __no_sanitize_undefined51#define __no_sanitize_undefined
52#endif52#endif
53 53
54#if __has_feature(memory_sanitizer)
55#define __SANITIZE_MEMORY__
56/*
57 * Unlike other sanitizers, KMSAN still inserts code into functions marked with
58 * no_sanitize("kernel-memory"). Using disable_sanitizer_instrumentation
59 * provides the behavior consistent with other __no_sanitize_ attributes,
60 * guaranteeing that __no_sanitize_memory functions remain uninstrumented.
61 */
62#define __no_sanitize_memory __disable_sanitizer_instrumentation
63
64/*
65 * The __no_kmsan_checks attribute ensures that a function does not produce
66 * false positive reports by:
67 * - initializing all local variables and memory stores in this function;
68 * - skipping all shadow checks;
69 * - passing initialized arguments to this function's callees.
70 */
71#define __no_kmsan_checks __attribute__((no_sanitize("kernel-memory")))
72#else
73#define __no_sanitize_memory
74#define __no_kmsan_checks
75#endif
76
54/*77/*
55 * Support for __has_feature(coverage_sanitizer) was added in Clang 13 together78 * Support for __has_feature(coverage_sanitizer) was added in Clang 13 together
56 * with no_sanitize("coverage"). Prior versions of Clang support coverage79 * with no_sanitize("coverage"). Prior versions of Clang support coverage
include/linux/compiler-gcc.h+6−0
@@ -114,6 +114,12 @@ · 113 unmodified lines
114#define __SANITIZE_ADDRESS__114#define __SANITIZE_ADDRESS__
115#endif115#endif
116 116
117/*
118 * GCC does not support KMSAN.
119 */
120#define __no_sanitize_memory
121#define __no_kmsan_checks
122
117/*123/*
118 * Turn individual warnings and errors on and off locally, depending124 * Turn individual warnings and errors on and off locally, depending
119 * on version.125 * on version.
include/linux/compiler_types.h+2−1
@@ -233,7 +233,8 @@ struct ftrace_likely_data { · 232 unmodified lines
233/* Section for code which can't be instrumented at all */233/* Section for code which can't be instrumented at all */
234#define noinstr \234#define noinstr \
235 noinline notrace __attribute((__section__(".noinstr.text"))) \235 noinline notrace __attribute((__section__(".noinstr.text"))) \
236 __no_kcsan __no_sanitize_address __no_profile __no_sanitize_coverage236 __no_kcsan __no_sanitize_address __no_profile __no_sanitize_coverage \
237 __no_sanitize_memory
237 238
238#endif /* __KERNEL__ */239#endif /* __KERNEL__ */
239 240
include/linux/damon.h+54−32
@@ -216,13 +216,26 @@ struct damos_stat { · 215 unmodified lines
216};216};
217 217
218/**218/**
219 * struct damos - Represents a Data Access Monitoring-based Operation Scheme.219 * struct damos_access_pattern - Target access pattern of the given scheme.
220 * @min_sz_region: Minimum size of target regions.220 * @min_sz_region: Minimum size of target regions.
221 * @max_sz_region: Maximum size of target regions.221 * @max_sz_region: Maximum size of target regions.
222 * @min_nr_accesses: Minimum ``->nr_accesses`` of target regions.222 * @min_nr_accesses: Minimum ``->nr_accesses`` of target regions.
223 * @max_nr_accesses: Maximum ``->nr_accesses`` of target regions.223 * @max_nr_accesses: Maximum ``->nr_accesses`` of target regions.
224 * @min_age_region: Minimum age of target regions.224 * @min_age_region: Minimum age of target regions.
225 * @max_age_region: Maximum age of target regions.225 * @max_age_region: Maximum age of target regions.
226 */
227struct damos_access_pattern {
228 unsigned long min_sz_region;
229 unsigned long max_sz_region;
230 unsigned int min_nr_accesses;
231 unsigned int max_nr_accesses;
232 unsigned int min_age_region;
233 unsigned int max_age_region;
234};
235
236/**
237 * struct damos - Represents a Data Access Monitoring-based Operation Scheme.
238 * @pattern: Access pattern of target regions.
226 * @action: &damo_action to be applied to the target regions.239 * @action: &damo_action to be applied to the target regions.
227 * @quota: Control the aggressiveness of this scheme.240 * @quota: Control the aggressiveness of this scheme.
228 * @wmarks: Watermarks for automated (in)activation of this scheme.241 * @wmarks: Watermarks for automated (in)activation of this scheme.
@@ -230,10 +243,8 @@ struct damos_stat { · 1 unmodified line
230 * @list: List head for siblings.243 * @list: List head for siblings.
231 *244 *
232 * For each aggregation interval, DAMON finds regions which fit in the245 * For each aggregation interval, DAMON finds regions which fit in the
233 * condition (&min_sz_region, &max_sz_region, &min_nr_accesses,246 * &pattern and applies &action to those. To avoid consuming too much
234 * &max_nr_accesses, &min_age_region, &max_age_region) and applies &action to247 * CPU time or IO resources for the &action, &quota is used.
235 * those. To avoid consuming too much CPU time or IO resources for the
236 * &action, &quota is used.
237 *248 *
238 * To do the work only when needed, schemes can be activated for specific249 * To do the work only when needed, schemes can be activated for specific
239 * system situations using &wmarks. If all schemes that registered to the250 * system situations using &wmarks. If all schemes that registered to the
@@ -248,12 +259,7 @@ struct damos_stat { · 8 unmodified lines
248 * &action is applied.259 * &action is applied.
249 */260 */
250struct damos {261struct damos {
251 unsigned long min_sz_region;262 struct damos_access_pattern pattern;
252 unsigned long max_sz_region;
253 unsigned int min_nr_accesses;
254 unsigned int max_nr_accesses;
255 unsigned int min_age_region;
256 unsigned int max_age_region;
257 enum damos_action action;263 enum damos_action action;
258 struct damos_quota quota;264 struct damos_quota quota;
259 struct damos_watermarks wmarks;265 struct damos_watermarks wmarks;
@@ -340,7 +346,7 @@ struct damon_operations { · 80 unmodified lines
340 unsigned long (*apply_scheme)(struct damon_ctx *context,346 unsigned long (*apply_scheme)(struct damon_ctx *context,
341 struct damon_target *t, struct damon_region *r,347 struct damon_target *t, struct damon_region *r,
342 struct damos *scheme);348 struct damos *scheme);
343 bool (*target_valid)(void *target);349 bool (*target_valid)(struct damon_target *t);
344 void (*cleanup)(struct damon_ctx *context);350 void (*cleanup)(struct damon_ctx *context);
345};351};
346 352
@@ -383,13 +389,15 @@ struct damon_callback { · 36 unmodified lines
383};389};
384 390
385/**391/**
386 * struct damon_ctx - Represents a context for each monitoring. This is the392 * struct damon_attrs - Monitoring attributes for accuracy/overhead control.
387 * main interface that allows users to set the attributes and get the results
388 * of the monitoring.
389 *393 *
390 * @sample_interval: The time between access samplings.394 * @sample_interval: The time between access samplings.
391 * @aggr_interval: The time between monitor results aggregations.395 * @aggr_interval: The time between monitor results aggregations.
392 * @ops_update_interval: The time between monitoring operations updates.396 * @ops_update_interval: The time between monitoring operations updates.
397 * @min_nr_regions: The minimum number of adaptive monitoring
398 * regions.
399 * @max_nr_regions: The maximum number of adaptive monitoring
400 * regions.
393 *401 *
394 * For each @sample_interval, DAMON checks whether each region is accessed or402 * For each @sample_interval, DAMON checks whether each region is accessed or
395 * not. It aggregates and keeps the access information (number of accesses to403 * not. It aggregates and keeps the access information (number of accesses to
@@ -399,7 +407,21 @@ struct damon_callback { · 3 unmodified lines
399 * @ops_update_interval. All time intervals are in micro-seconds.407 * @ops_update_interval. All time intervals are in micro-seconds.
400 * Please refer to &struct damon_operations and &struct damon_callback for more408 * Please refer to &struct damon_operations and &struct damon_callback for more
401 * detail.409 * detail.
410 */
411struct damon_attrs {
412 unsigned long sample_interval;
413 unsigned long aggr_interval;
414 unsigned long ops_update_interval;
415 unsigned long min_nr_regions;
416 unsigned long max_nr_regions;
417};
418
419/**
420 * struct damon_ctx - Represents a context for each monitoring. This is the
421 * main interface that allows users to set the attributes and get the results
422 * of the monitoring.
402 *423 *
424 * @attrs: Monitoring attributes for accuracy/overhead control.
403 * @kdamond: Kernel thread who does the monitoring.425 * @kdamond: Kernel thread who does the monitoring.
404 * @kdamond_lock: Mutex for the synchronizations with @kdamond.426 * @kdamond_lock: Mutex for the synchronizations with @kdamond.
405 *427 *
@@ -421,15 +443,11 @@ struct damon_callback { · 15 unmodified lines
421 * @ops: Set of monitoring operations for given use cases.443 * @ops: Set of monitoring operations for given use cases.
422 * @callback: Set of callbacks for monitoring events notifications.444 * @callback: Set of callbacks for monitoring events notifications.
423 *445 *
424 * @min_nr_regions: The minimum number of adaptive monitoring regions.
425 * @max_nr_regions: The maximum number of adaptive monitoring regions.
426 * @adaptive_targets: Head of monitoring targets (&damon_target) list.446 * @adaptive_targets: Head of monitoring targets (&damon_target) list.
427 * @schemes: Head of schemes (&damos) list.447 * @schemes: Head of schemes (&damos) list.
428 */448 */
429struct damon_ctx {449struct damon_ctx {
430 unsigned long sample_interval;450 struct damon_attrs attrs;
431 unsigned long aggr_interval;
432 unsigned long ops_update_interval;
433 451
434/* private: internal use only */452/* private: internal use only */
435 struct timespec64 last_aggregation;453 struct timespec64 last_aggregation;
@@ -442,8 +460,6 @@ struct damon_ctx { · 6 unmodified lines
442 struct damon_operations ops;460 struct damon_operations ops;
443 struct damon_callback callback;461 struct damon_callback callback;
444 462
445 unsigned long min_nr_regions;
446 unsigned long max_nr_regions;
447 struct list_head adaptive_targets;463 struct list_head adaptive_targets;
448 struct list_head schemes;464 struct list_head schemes;
449};465};
@@ -463,9 +479,17 @@ static inline struct damon_region *damon_last_region(struct damon_target *t) · 13 unmodified lines
463 return list_last_entry(&t->regions_list, struct damon_region, list);479 return list_last_entry(&t->regions_list, struct damon_region, list);
464}480}
465 481
482static inline struct damon_region *damon_first_region(struct damon_target *t)
483{
484 return list_first_entry(&t->regions_list, struct damon_region, list);
485}
486
466#define damon_for_each_region(r, t) \487#define damon_for_each_region(r, t) \
467 list_for_each_entry(r, &t->regions_list, list)488 list_for_each_entry(r, &t->regions_list, list)
468 489
490#define damon_for_each_region_from(r, t) \
491 list_for_each_entry_from(r, &t->regions_list, list)
492
469#define damon_for_each_region_safe(r, next, t) \493#define damon_for_each_region_safe(r, next, t) \
470 list_for_each_entry_safe(r, next, &t->regions_list, list)494 list_for_each_entry_safe(r, next, &t->regions_list, list)
471 495
@@ -501,12 +525,9 @@ void damon_destroy_region(struct damon_region *r, struct damon_target *t); · 29 unmodified lines
501int damon_set_regions(struct damon_target *t, struct damon_addr_range *ranges,525int damon_set_regions(struct damon_target *t, struct damon_addr_range *ranges,
502 unsigned int nr_ranges);526 unsigned int nr_ranges);
503 527
504struct damos *damon_new_scheme(528struct damos *damon_new_scheme(struct damos_access_pattern *pattern,
505 unsigned long min_sz_region, unsigned long max_sz_region,529 enum damos_action action, struct damos_quota *quota,
506 unsigned int min_nr_accesses, unsigned int max_nr_accesses,530 struct damos_watermarks *wmarks);
507 unsigned int min_age_region, unsigned int max_age_region,
508 enum damos_action action, struct damos_quota *quota,
509 struct damos_watermarks *wmarks);
510void damon_add_scheme(struct damon_ctx *ctx, struct damos *s);531void damon_add_scheme(struct damon_ctx *ctx, struct damos *s);
511void damon_destroy_scheme(struct damos *s);532void damon_destroy_scheme(struct damos *s);
512 533
@@ -519,10 +540,8 @@ unsigned int damon_nr_regions(struct damon_target *t); · 6 unmodified lines
519 540
520struct damon_ctx *damon_new_ctx(void);541struct damon_ctx *damon_new_ctx(void);
521void damon_destroy_ctx(struct damon_ctx *ctx);542void damon_destroy_ctx(struct damon_ctx *ctx);
522int damon_set_attrs(struct damon_ctx *ctx, unsigned long sample_int,543int damon_set_attrs(struct damon_ctx *ctx, struct damon_attrs *attrs);
523 unsigned long aggr_int, unsigned long ops_upd_int,544void damon_set_schemes(struct damon_ctx *ctx,
524 unsigned long min_nr_reg, unsigned long max_nr_reg);
525int damon_set_schemes(struct damon_ctx *ctx,
526 struct damos **schemes, ssize_t nr_schemes);545 struct damos **schemes, ssize_t nr_schemes);
527int damon_nr_running_ctxs(void);546int damon_nr_running_ctxs(void);
528bool damon_is_registered_ops(enum damon_ops_id id);547bool damon_is_registered_ops(enum damon_ops_id id);
@@ -538,6 +557,9 @@ static inline bool damon_target_has_pid(const struct damon_ctx *ctx) · 9 unmodified lines
538int damon_start(struct damon_ctx **ctxs, int nr_ctxs, bool exclusive);557int damon_start(struct damon_ctx **ctxs, int nr_ctxs, bool exclusive);
539int damon_stop(struct damon_ctx **ctxs, int nr_ctxs);558int damon_stop(struct damon_ctx **ctxs, int nr_ctxs);
540 559
560int damon_set_region_biggest_system_ram_default(struct damon_target *t,
561 unsigned long *start, unsigned long *end);
562
541#endif /* CONFIG_DAMON */563#endif /* CONFIG_DAMON */
542 564
543#endif /* _DAMON_H */565#endif /* _DAMON_H */
include/linux/delayacct.h+8−8
@@ -73,8 +73,8 @@ extern int delayacct_add_tsk(struct taskstats *, struct task_struct *); · 72 unmodified lines
73extern __u64 __delayacct_blkio_ticks(struct task_struct *);73extern __u64 __delayacct_blkio_ticks(struct task_struct *);
74extern void __delayacct_freepages_start(void);74extern void __delayacct_freepages_start(void);
75extern void __delayacct_freepages_end(void);75extern void __delayacct_freepages_end(void);
76extern void __delayacct_thrashing_start(void);76extern void __delayacct_thrashing_start(bool *in_thrashing);
77extern void __delayacct_thrashing_end(void);77extern void __delayacct_thrashing_end(bool *in_thrashing);
78extern void __delayacct_swapin_start(void);78extern void __delayacct_swapin_start(void);
79extern void __delayacct_swapin_end(void);79extern void __delayacct_swapin_end(void);
80extern void __delayacct_compact_start(void);80extern void __delayacct_compact_start(void);
@@ -143,22 +143,22 @@ static inline void delayacct_freepages_end(void) · 62 unmodified lines
143 __delayacct_freepages_end();143 __delayacct_freepages_end();
144}144}
145 145
146static inline void delayacct_thrashing_start(void)146static inline void delayacct_thrashing_start(bool *in_thrashing)
147{147{
148 if (!static_branch_unlikely(&delayacct_key))148 if (!static_branch_unlikely(&delayacct_key))
149 return;149 return;
150 150
151 if (current->delays)151 if (current->delays)
152 __delayacct_thrashing_start();152 __delayacct_thrashing_start(in_thrashing);
153}153}
154 154
155static inline void delayacct_thrashing_end(void)155static inline void delayacct_thrashing_end(bool *in_thrashing)
156{156{
157 if (!static_branch_unlikely(&delayacct_key))157 if (!static_branch_unlikely(&delayacct_key))
158 return;158 return;
159 159
160 if (current->delays)160 if (current->delays)
161 __delayacct_thrashing_end();161 __delayacct_thrashing_end(in_thrashing);
162}162}
163 163
164static inline void delayacct_swapin_start(void)164static inline void delayacct_swapin_start(void)
@@ -237,9 +237,9 @@ static inline void delayacct_freepages_start(void) · 72 unmodified lines
237{}237{}
238static inline void delayacct_freepages_end(void)238static inline void delayacct_freepages_end(void)
239{}239{}
240static inline void delayacct_thrashing_start(void)240static inline void delayacct_thrashing_start(bool *in_thrashing)
241{}241{}
242static inline void delayacct_thrashing_end(void)242static inline void delayacct_thrashing_end(bool *in_thrashing)
243{}243{}
244static inline void delayacct_swapin_start(void)244static inline void delayacct_swapin_start(void)
245{}245{}
include/linux/fortify-string.h+2−0
@@ -328,8 +328,10 @@ __FORTIFY_INLINE void fortify_memset_chk(__kernel_size_t size, · 327 unmodified lines
328 * __struct_size() vs __member_size() must be captured here to avoid328 * __struct_size() vs __member_size() must be captured here to avoid
329 * evaluating argument side-effects further into the macro layers.329 * evaluating argument side-effects further into the macro layers.
330 */330 */
331#ifndef CONFIG_KMSAN
331#define memset(p, c, s) __fortify_memset_chk(p, c, s, \332#define memset(p, c, s) __fortify_memset_chk(p, c, s, \
332 __struct_size(p), __member_size(p))333 __struct_size(p), __member_size(p))
334#endif
333 335
334/*336/*
335 * To make sure the compiler can enforce protection against buffer overflows,337 * To make sure the compiler can enforce protection against buffer overflows,
include/linux/gfp.h+3−23
@@ -18,6 +18,9 @@ static inline int gfp_migratetype(const gfp_t gfp_flags) · 17 unmodified lines
18 VM_WARN_ON((gfp_flags & GFP_MOVABLE_MASK) == GFP_MOVABLE_MASK);18 VM_WARN_ON((gfp_flags & GFP_MOVABLE_MASK) == GFP_MOVABLE_MASK);
19 BUILD_BUG_ON((1UL << GFP_MOVABLE_SHIFT) != ___GFP_MOVABLE);19 BUILD_BUG_ON((1UL << GFP_MOVABLE_SHIFT) != ___GFP_MOVABLE);
20 BUILD_BUG_ON((___GFP_MOVABLE >> GFP_MOVABLE_SHIFT) != MIGRATE_MOVABLE);20 BUILD_BUG_ON((___GFP_MOVABLE >> GFP_MOVABLE_SHIFT) != MIGRATE_MOVABLE);
21 BUILD_BUG_ON((___GFP_RECLAIMABLE >> GFP_MOVABLE_SHIFT) != MIGRATE_RECLAIMABLE);
22 BUILD_BUG_ON(((___GFP_MOVABLE | ___GFP_RECLAIMABLE) >>
23 GFP_MOVABLE_SHIFT) != MIGRATE_HIGHATOMIC);
21 24
22 if (unlikely(page_group_by_mobility_disabled))25 if (unlikely(page_group_by_mobility_disabled))
23 return MIGRATE_UNMOVABLE;26 return MIGRATE_UNMOVABLE;
@@ -33,29 +36,6 @@ static inline bool gfpflags_allow_blocking(const gfp_t gfp_flags) · 9 unmodified lines
33 return !!(gfp_flags & __GFP_DIRECT_RECLAIM);36 return !!(gfp_flags & __GFP_DIRECT_RECLAIM);
34}37}
35 38
36/**
37 * gfpflags_normal_context - is gfp_flags a normal sleepable context?
38 * @gfp_flags: gfp_flags to test
39 *
40 * Test whether @gfp_flags indicates that the allocation is from the
41 * %current context and allowed to sleep.
42 *
43 * An allocation being allowed to block doesn't mean it owns the %current
44 * context. When direct reclaim path tries to allocate memory, the
45 * allocation context is nested inside whatever %current was doing at the
46 * time of the original allocation. The nested allocation may be allowed
47 * to block but modifying anything %current owns can corrupt the outer
48 * context's expectations.
49 *
50 * %true result from this function indicates that the allocation context
51 * can sleep and use anything that's associated with %current.
52 */
53static inline bool gfpflags_normal_context(const gfp_t gfp_flags)
54{
55 return (gfp_flags & (__GFP_DIRECT_RECLAIM | __GFP_MEMALLOC)) ==
56 __GFP_DIRECT_RECLAIM;
57}
58
59#ifdef CONFIG_HIGHMEM39#ifdef CONFIG_HIGHMEM
60#define OPT_ZONE_HIGHMEM ZONE_HIGHMEM40#define OPT_ZONE_HIGHMEM ZONE_HIGHMEM
61#else41#else
include/linux/highmem.h+3−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
6#include <linux/kernel.h>6#include <linux/kernel.h>
7#include <linux/bug.h>7#include <linux/bug.h>
8#include <linux/cacheflush.h>8#include <linux/cacheflush.h>
9#include <linux/kmsan.h>
9#include <linux/mm.h>10#include <linux/mm.h>
10#include <linux/uaccess.h>11#include <linux/uaccess.h>
11#include <linux/hardirq.h>12#include <linux/hardirq.h>
@@ -311,6 +312,7 @@ static inline void copy_user_highpage(struct page *to, struct page *from, · 299 unmodified lines
311 vfrom = kmap_local_page(from);312 vfrom = kmap_local_page(from);
312 vto = kmap_local_page(to);313 vto = kmap_local_page(to);
313 copy_user_page(vto, vfrom, vaddr, to);314 copy_user_page(vto, vfrom, vaddr, to);
315 kmsan_unpoison_memory(page_address(to), PAGE_SIZE);
314 kunmap_local(vto);316 kunmap_local(vto);
315 kunmap_local(vfrom);317 kunmap_local(vfrom);
316}318}
@@ -326,6 +328,7 @@ static inline void copy_highpage(struct page *to, struct page *from) · 9 unmodified lines
326 vfrom = kmap_local_page(from);328 vfrom = kmap_local_page(from);
327 vto = kmap_local_page(to);329 vto = kmap_local_page(to);
328 copy_page(vto, vfrom);330 copy_page(vto, vfrom);
331 kmsan_copy_page_meta(to, from);
329 kunmap_local(vto);332 kunmap_local(vto);
330 kunmap_local(vfrom);333 kunmap_local(vfrom);
331}334}
include/linux/huge_mm.h+21−7
@@ -168,9 +168,8 @@ static inline bool file_thp_enabled(struct vm_area_struct *vma) · 167 unmodified lines
168 !inode_is_open_for_write(inode) && S_ISREG(inode->i_mode);168 !inode_is_open_for_write(inode) && S_ISREG(inode->i_mode);
169}169}
170 170
171bool hugepage_vma_check(struct vm_area_struct *vma,171bool hugepage_vma_check(struct vm_area_struct *vma, unsigned long vm_flags,
172 unsigned long vm_flags,172 bool smaps, bool in_pf, bool enforce_sysfs);
173 bool smaps, bool in_pf);
174 173
175#define transparent_hugepage_use_zero_page() \174#define transparent_hugepage_use_zero_page() \
176 (transparent_hugepage_flags & \175 (transparent_hugepage_flags & \
@@ -219,6 +218,9 @@ void __split_huge_pud(struct vm_area_struct *vma, pud_t *pud, · 42 unmodified lines
219 218
220int hugepage_madvise(struct vm_area_struct *vma, unsigned long *vm_flags,219int hugepage_madvise(struct vm_area_struct *vma, unsigned long *vm_flags,
221 int advice);220 int advice);
221int madvise_collapse(struct vm_area_struct *vma,
222 struct vm_area_struct **prev,
223 unsigned long start, unsigned long end);
222void vma_adjust_trans_huge(struct vm_area_struct *vma, unsigned long start,224void vma_adjust_trans_huge(struct vm_area_struct *vma, unsigned long start,
223 unsigned long end, long adjust_next);225 unsigned long end, long adjust_next);
224spinlock_t *__pmd_trans_huge_lock(pmd_t *pmd, struct vm_area_struct *vma);226spinlock_t *__pmd_trans_huge_lock(pmd_t *pmd, struct vm_area_struct *vma);
@@ -321,8 +323,8 @@ static inline bool transhuge_vma_suitable(struct vm_area_struct *vma, · 96 unmodified lines
321}323}
322 324
323static inline bool hugepage_vma_check(struct vm_area_struct *vma,325static inline bool hugepage_vma_check(struct vm_area_struct *vma,
324 unsigned long vm_flags,326 unsigned long vm_flags, bool smaps,
325 bool smaps, bool in_pf)327 bool in_pf, bool enforce_sysfs)
326{328{
327 return false;329 return false;
328}330}
@@ -362,9 +364,16 @@ static inline void split_huge_pmd_address(struct vm_area_struct *vma, · 33 unmodified lines
362static inline int hugepage_madvise(struct vm_area_struct *vma,364static inline int hugepage_madvise(struct vm_area_struct *vma,
363 unsigned long *vm_flags, int advice)365 unsigned long *vm_flags, int advice)
364{366{
365 BUG();367 return -EINVAL;
366 return 0;368}
369
370static inline int madvise_collapse(struct vm_area_struct *vma,
371 struct vm_area_struct **prev,
372 unsigned long start, unsigned long end)
373{
374 return -EINVAL;
367}375}
376
368static inline void vma_adjust_trans_huge(struct vm_area_struct *vma,377static inline void vma_adjust_trans_huge(struct vm_area_struct *vma,
369 unsigned long start,378 unsigned long start,
370 unsigned long end,379 unsigned long end,
@@ -435,6 +444,11 @@ static inline int split_folio_to_list(struct folio *folio, · 64 unmodified lines
435 return split_huge_page_to_list(&folio->page, list);444 return split_huge_page_to_list(&folio->page, list);
436}445}
437 446
447static inline int split_folio(struct folio *folio)
448{
449 return split_folio_to_list(folio, NULL);
450}
451
438/*452/*
439 * archs that select ARCH_WANTS_THP_SWAP but don't support THP_SWP due to453 * archs that select ARCH_WANTS_THP_SWAP but don't support THP_SWP due to
440 * limitations in the implementation like arm64 MTE can override this to454 * limitations in the implementation like arm64 MTE can override this to
include/linux/hugetlb.h+56−7
@@ -16,6 +16,7 @@ · 15 unmodified lines
16struct ctl_table;16struct ctl_table;
17struct user_struct;17struct user_struct;
18struct mmu_gather;18struct mmu_gather;
19struct node;
19 20
20#ifndef CONFIG_ARCH_HAS_HUGEPD21#ifndef CONFIG_ARCH_HAS_HUGEPD
21typedef struct { unsigned long pd; } hugepd_t;22typedef struct { unsigned long pd; } hugepd_t;
@@ -114,6 +115,12 @@ struct file_region { · 92 unmodified lines
114#endif115#endif
115};116};
116 117
118struct hugetlb_vma_lock {
119 struct kref refs;
120 struct rw_semaphore rw_sema;
121 struct vm_area_struct *vma;
122};
123
117extern struct resv_map *resv_map_alloc(void);124extern struct resv_map *resv_map_alloc(void);
118void resv_map_release(struct kref *ref);125void resv_map_release(struct kref *ref);
119 126
@@ -126,7 +133,7 @@ struct hugepage_subpool *hugepage_new_subpool(struct hstate *h, long max_hpages, · 6 unmodified lines
126 long min_hpages);133 long min_hpages);
127void hugepage_put_subpool(struct hugepage_subpool *spool);134void hugepage_put_subpool(struct hugepage_subpool *spool);
128 135
129void reset_vma_resv_huge_pages(struct vm_area_struct *vma);136void hugetlb_dup_vma_private(struct vm_area_struct *vma);
130void clear_vma_resv_huge_pages(struct vm_area_struct *vma);137void clear_vma_resv_huge_pages(struct vm_area_struct *vma);
131int hugetlb_sysctl_handler(struct ctl_table *, int, void *, size_t *, loff_t *);138int hugetlb_sysctl_handler(struct ctl_table *, int, void *, size_t *, loff_t *);
132int hugetlb_overcommit_handler(struct ctl_table *, int, void *, size_t *,139int hugetlb_overcommit_handler(struct ctl_table *, int, void *, size_t *,
@@ -214,6 +221,14 @@ struct page *follow_huge_pud(struct mm_struct *mm, unsigned long address, · 81 unmodified lines
214struct page *follow_huge_pgd(struct mm_struct *mm, unsigned long address,221struct page *follow_huge_pgd(struct mm_struct *mm, unsigned long address,
215 pgd_t *pgd, int flags);222 pgd_t *pgd, int flags);
216 223
224void hugetlb_vma_lock_read(struct vm_area_struct *vma);
225void hugetlb_vma_unlock_read(struct vm_area_struct *vma);
226void hugetlb_vma_lock_write(struct vm_area_struct *vma);
227void hugetlb_vma_unlock_write(struct vm_area_struct *vma);
228int hugetlb_vma_trylock_write(struct vm_area_struct *vma);
229void hugetlb_vma_assert_locked(struct vm_area_struct *vma);
230void hugetlb_vma_lock_release(struct kref *kref);
231
217int pmd_huge(pmd_t pmd);232int pmd_huge(pmd_t pmd);
218int pud_huge(pud_t pud);233int pud_huge(pud_t pud);
219unsigned long hugetlb_change_protection(struct vm_area_struct *vma,234unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
@@ -225,7 +240,7 @@ void hugetlb_unshare_all_pmds(struct vm_area_struct *vma); · 5 unmodified lines
225 240
226#else /* !CONFIG_HUGETLB_PAGE */241#else /* !CONFIG_HUGETLB_PAGE */
227 242
228static inline void reset_vma_resv_huge_pages(struct vm_area_struct *vma)243static inline void hugetlb_dup_vma_private(struct vm_area_struct *vma)
229{244{
230}245}
231 246
@@ -336,6 +351,31 @@ static inline int prepare_hugepage_range(struct file *file, · 104 unmodified lines
336 return -EINVAL;351 return -EINVAL;
337}352}
338 353
354static inline void hugetlb_vma_lock_read(struct vm_area_struct *vma)
355{
356}
357
358static inline void hugetlb_vma_unlock_read(struct vm_area_struct *vma)
359{
360}
361
362static inline void hugetlb_vma_lock_write(struct vm_area_struct *vma)
363{
364}
365
366static inline void hugetlb_vma_unlock_write(struct vm_area_struct *vma)
367{
368}
369
370static inline int hugetlb_vma_trylock_write(struct vm_area_struct *vma)
371{
372 return 1;
373}
374
375static inline void hugetlb_vma_assert_locked(struct vm_area_struct *vma)
376{
377}
378
339static inline int pmd_huge(pmd_t pmd)379static inline int pmd_huge(pmd_t pmd)
340{380{
341 return 0;381 return 0;
@@ -665,7 +705,7 @@ struct page *alloc_huge_page_nodemask(struct hstate *h, int preferred_nid, · 323 unmodified lines
665 nodemask_t *nmask, gfp_t gfp_mask);705 nodemask_t *nmask, gfp_t gfp_mask);
666struct page *alloc_huge_page_vma(struct hstate *h, struct vm_area_struct *vma,706struct page *alloc_huge_page_vma(struct hstate *h, struct vm_area_struct *vma,
667 unsigned long address);707 unsigned long address);
668int huge_add_to_page_cache(struct page *page, struct address_space *mapping,708int hugetlb_add_to_page_cache(struct page *page, struct address_space *mapping,
669 pgoff_t idx);709 pgoff_t idx);
670void restore_reserve_on_error(struct hstate *h, struct vm_area_struct *vma,710void restore_reserve_on_error(struct hstate *h, struct vm_area_struct *vma,
671 unsigned long address, struct page *page);711 unsigned long address, struct page *page);
@@ -935,6 +975,11 @@ static inline void huge_ptep_modify_prot_commit(struct vm_area_struct *vma, · 263 unmodified lines
935}975}
936#endif976#endif
937 977
978#ifdef CONFIG_NUMA
979void hugetlb_register_node(struct node *node);
980void hugetlb_unregister_node(struct node *node);
981#endif
982
938#else /* CONFIG_HUGETLB_PAGE */983#else /* CONFIG_HUGETLB_PAGE */
939struct hstate {};984struct hstate {};
940 985
@@ -1109,6 +1154,14 @@ static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, · 168 unmodified lines
1109 pte_t *ptep, pte_t pte)1154 pte_t *ptep, pte_t pte)
1110{1155{
1111}1156}
1157
1158static inline void hugetlb_register_node(struct node *node)
1159{
1160}
1161
1162static inline void hugetlb_unregister_node(struct node *node)
1163{
1164}
1112#endif /* CONFIG_HUGETLB_PAGE */1165#endif /* CONFIG_HUGETLB_PAGE */
1113 1166
1114static inline spinlock_t *huge_pte_lock(struct hstate *h,1167static inline spinlock_t *huge_pte_lock(struct hstate *h,
@@ -1123,14 +1176,10 @@ static inline spinlock_t *huge_pte_lock(struct hstate *h, · 8 unmodified lines
1123 1176
1124#if defined(CONFIG_HUGETLB_PAGE) && defined(CONFIG_CMA)1177#if defined(CONFIG_HUGETLB_PAGE) && defined(CONFIG_CMA)
1125extern void __init hugetlb_cma_reserve(int order);1178extern void __init hugetlb_cma_reserve(int order);
1126extern void __init hugetlb_cma_check(void);
1127#else1179#else
1128static inline __init void hugetlb_cma_reserve(int order)1180static inline __init void hugetlb_cma_reserve(int order)
1129{1181{
1130}1182}
1131static inline __init void hugetlb_cma_check(void)
1132{
1133}
1134#endif1183#endif
1135 1184
1136bool want_pmd_share(struct vm_area_struct *vma, unsigned long addr);1185bool want_pmd_share(struct vm_area_struct *vma, unsigned long addr);
include/linux/hugetlb_cgroup.h+8−11
@@ -90,32 +90,31 @@ hugetlb_cgroup_from_page_rsvd(struct page *page) · 89 unmodified lines
90 return __hugetlb_cgroup_from_page(page, true);90 return __hugetlb_cgroup_from_page(page, true);
91}91}
92 92
93static inline int __set_hugetlb_cgroup(struct page *page,93static inline void __set_hugetlb_cgroup(struct page *page,
94 struct hugetlb_cgroup *h_cg, bool rsvd)94 struct hugetlb_cgroup *h_cg, bool rsvd)
95{95{
96 VM_BUG_ON_PAGE(!PageHuge(page), page);96 VM_BUG_ON_PAGE(!PageHuge(page), page);
97 97
98 if (compound_order(page) < HUGETLB_CGROUP_MIN_ORDER)98 if (compound_order(page) < HUGETLB_CGROUP_MIN_ORDER)
99 return -1;99 return;
100 if (rsvd)100 if (rsvd)
101 set_page_private(page + SUBPAGE_INDEX_CGROUP_RSVD,101 set_page_private(page + SUBPAGE_INDEX_CGROUP_RSVD,
102 (unsigned long)h_cg);102 (unsigned long)h_cg);
103 else103 else
104 set_page_private(page + SUBPAGE_INDEX_CGROUP,104 set_page_private(page + SUBPAGE_INDEX_CGROUP,
105 (unsigned long)h_cg);105 (unsigned long)h_cg);
106 return 0;
107}106}
108 107
109static inline int set_hugetlb_cgroup(struct page *page,108static inline void set_hugetlb_cgroup(struct page *page,
110 struct hugetlb_cgroup *h_cg)109 struct hugetlb_cgroup *h_cg)
111{110{
112 return __set_hugetlb_cgroup(page, h_cg, false);111 __set_hugetlb_cgroup(page, h_cg, false);
113}112}
114 113
115static inline int set_hugetlb_cgroup_rsvd(struct page *page,114static inline void set_hugetlb_cgroup_rsvd(struct page *page,
116 struct hugetlb_cgroup *h_cg)115 struct hugetlb_cgroup *h_cg)
117{116{
118 return __set_hugetlb_cgroup(page, h_cg, true);117 __set_hugetlb_cgroup(page, h_cg, true);
119}118}
120 119
121static inline bool hugetlb_cgroup_disabled(void)120static inline bool hugetlb_cgroup_disabled(void)
@@ -199,16 +198,14 @@ hugetlb_cgroup_from_page_rsvd(struct page *page) · 77 unmodified lines
199 return NULL;198 return NULL;
200}199}
201 200
202static inline int set_hugetlb_cgroup(struct page *page,201static inline void set_hugetlb_cgroup(struct page *page,
203 struct hugetlb_cgroup *h_cg)202 struct hugetlb_cgroup *h_cg)
204{203{
205 return 0;
206}204}
207 205
208static inline int set_hugetlb_cgroup_rsvd(struct page *page,206static inline void set_hugetlb_cgroup_rsvd(struct page *page,
209 struct hugetlb_cgroup *h_cg)207 struct hugetlb_cgroup *h_cg)
210{208{
211 return 0;
212}209}
213 210
214static inline bool hugetlb_cgroup_disabled(void)211static inline bool hugetlb_cgroup_disabled(void)
include/linux/instrumented.h+56−3
@@ -2,7 +2,7 @@ · 1 unmodified line
2 2
3/*3/*
4 * This header provides generic wrappers for memory access instrumentation that4 * This header provides generic wrappers for memory access instrumentation that
5 * the compiler cannot emit for: KASAN, KCSAN.5 * the compiler cannot emit for: KASAN, KCSAN, KMSAN.
6 */6 */
7#ifndef _LINUX_INSTRUMENTED_H7#ifndef _LINUX_INSTRUMENTED_H
8#define _LINUX_INSTRUMENTED_H8#define _LINUX_INSTRUMENTED_H
@@ -10,6 +10,7 @@ · 1 unmodified line
10#include <linux/compiler.h>10#include <linux/compiler.h>
11#include <linux/kasan-checks.h>11#include <linux/kasan-checks.h>
12#include <linux/kcsan-checks.h>12#include <linux/kcsan-checks.h>
13#include <linux/kmsan-checks.h>
13#include <linux/types.h>14#include <linux/types.h>
14 15
15/**16/**
@@ -117,10 +118,11 @@ instrument_copy_to_user(void __user *to, const void *from, unsigned long n) · 101 unmodified lines
117{118{
118 kasan_check_read(from, n);119 kasan_check_read(from, n);
119 kcsan_check_read(from, n);120 kcsan_check_read(from, n);
121 kmsan_copy_to_user(to, from, n, 0);
120}122}
121 123
122/**124/**
123 * instrument_copy_from_user - instrument writes of copy_from_user125 * instrument_copy_from_user_before - add instrumentation before copy_from_user
124 *126 *
125 * Instrument writes to kernel memory, that are due to copy_from_user (and127 * Instrument writes to kernel memory, that are due to copy_from_user (and
126 * variants). The instrumentation should be inserted before the accesses.128 * variants). The instrumentation should be inserted before the accesses.
@@ -130,10 +132,61 @@ instrument_copy_to_user(void __user *to, const void *from, unsigned long n) · 3 unmodified lines
130 * @n number of bytes to copy132 * @n number of bytes to copy
131 */133 */
132static __always_inline void134static __always_inline void
133instrument_copy_from_user(const void *to, const void __user *from, unsigned long n)135instrument_copy_from_user_before(const void *to, const void __user *from, unsigned long n)
134{136{
135 kasan_check_write(to, n);137 kasan_check_write(to, n);
136 kcsan_check_write(to, n);138 kcsan_check_write(to, n);
137}139}
138 140
141/**
142 * instrument_copy_from_user_after - add instrumentation after copy_from_user
143 *
144 * Instrument writes to kernel memory, that are due to copy_from_user (and
145 * variants). The instrumentation should be inserted after the accesses.
146 *
147 * @to destination address
148 * @from source address
149 * @n number of bytes to copy
150 * @left number of bytes not copied (as returned by copy_from_user)
151 */
152static __always_inline void
153instrument_copy_from_user_after(const void *to, const void __user *from,
154 unsigned long n, unsigned long left)
155{
156 kmsan_unpoison_memory(to, n - left);
157}
158
159/**
160 * instrument_get_user() - add instrumentation to get_user()-like macros
161 *
162 * get_user() and friends are fragile, so it may depend on the implementation
163 * whether the instrumentation happens before or after the data is copied from
164 * the userspace.
165 *
166 * @to destination variable, may not be address-taken
167 */
168#define instrument_get_user(to) \
169({ \
170 u64 __tmp = (u64)(to); \
171 kmsan_unpoison_memory(&__tmp, sizeof(__tmp)); \
172 to = __tmp; \
173})
174
175
176/**
177 * instrument_put_user() - add instrumentation to put_user()-like macros
178 *
179 * put_user() and friends are fragile, so it may depend on the implementation
180 * whether the instrumentation happens before or after the data is copied from
181 * the userspace.
182 *
183 * @from source address
184 * @ptr userspace pointer to copy to
185 * @size number of bytes to copy
186 */
187#define instrument_put_user(from, ptr, size) \
188({ \
189 kmsan_copy_to_user(ptr, &from, sizeof(from), 0); \
190})
191
139#endif /* _LINUX_INSTRUMENTED_H */192#endif /* _LINUX_INSTRUMENTED_H */
include/linux/kasan.h+22−33
@@ -98,19 +98,13 @@ static inline bool kasan_has_integrated_init(void) · 97 unmodified lines
98#ifdef CONFIG_KASAN98#ifdef CONFIG_KASAN
99 99
100struct kasan_cache {100struct kasan_cache {
101#ifdef CONFIG_KASAN_GENERIC
101 int alloc_meta_offset;102 int alloc_meta_offset;
102 int free_meta_offset;103 int free_meta_offset;
104#endif
103 bool is_kmalloc;105 bool is_kmalloc;
104};106};
105 107
106slab_flags_t __kasan_never_merge(void);
107static __always_inline slab_flags_t kasan_never_merge(void)
108{
109 if (kasan_enabled())
110 return __kasan_never_merge();
111 return 0;
112}
113
114void __kasan_unpoison_range(const void *addr, size_t size);108void __kasan_unpoison_range(const void *addr, size_t size);
115static __always_inline void kasan_unpoison_range(const void *addr, size_t size)109static __always_inline void kasan_unpoison_range(const void *addr, size_t size)
116{110{
@@ -134,15 +128,6 @@ static __always_inline void kasan_unpoison_pages(struct page *page, · 17 unmodified lines
134 __kasan_unpoison_pages(page, order, init);128 __kasan_unpoison_pages(page, order, init);
135}129}
136 130
137void __kasan_cache_create(struct kmem_cache *cache, unsigned int *size,
138 slab_flags_t *flags);
139static __always_inline void kasan_cache_create(struct kmem_cache *cache,
140 unsigned int *size, slab_flags_t *flags)
141{
142 if (kasan_enabled())
143 __kasan_cache_create(cache, size, flags);
144}
145
146void __kasan_cache_create_kmalloc(struct kmem_cache *cache);131void __kasan_cache_create_kmalloc(struct kmem_cache *cache);
147static __always_inline void kasan_cache_create_kmalloc(struct kmem_cache *cache)132static __always_inline void kasan_cache_create_kmalloc(struct kmem_cache *cache)
148{133{
@@ -150,14 +135,6 @@ static __always_inline void kasan_cache_create_kmalloc(struct kmem_cache *cache) · 1 unmodified line
150 __kasan_cache_create_kmalloc(cache);135 __kasan_cache_create_kmalloc(cache);
151}136}
152 137
153size_t __kasan_metadata_size(struct kmem_cache *cache);
154static __always_inline size_t kasan_metadata_size(struct kmem_cache *cache)
155{
156 if (kasan_enabled())
157 return __kasan_metadata_size(cache);
158 return 0;
159}
160
161void __kasan_poison_slab(struct slab *slab);138void __kasan_poison_slab(struct slab *slab);
162static __always_inline void kasan_poison_slab(struct slab *slab)139static __always_inline void kasan_poison_slab(struct slab *slab)
163{140{
@@ -269,20 +246,12 @@ static __always_inline bool kasan_check_byte(const void *addr) · 105 unmodified lines
269 246
270#else /* CONFIG_KASAN */247#else /* CONFIG_KASAN */
271 248
272static inline slab_flags_t kasan_never_merge(void)
273{
274 return 0;
275}
276static inline void kasan_unpoison_range(const void *address, size_t size) {}249static inline void kasan_unpoison_range(const void *address, size_t size) {}
277static inline void kasan_poison_pages(struct page *page, unsigned int order,250static inline void kasan_poison_pages(struct page *page, unsigned int order,
278 bool init) {}251 bool init) {}
279static inline void kasan_unpoison_pages(struct page *page, unsigned int order,252static inline void kasan_unpoison_pages(struct page *page, unsigned int order,
280 bool init) {}253 bool init) {}
281static inline void kasan_cache_create(struct kmem_cache *cache,
282 unsigned int *size,
283 slab_flags_t *flags) {}
284static inline void kasan_cache_create_kmalloc(struct kmem_cache *cache) {}254static inline void kasan_cache_create_kmalloc(struct kmem_cache *cache) {}
285static inline size_t kasan_metadata_size(struct kmem_cache *cache) { return 0; }
286static inline void kasan_poison_slab(struct slab *slab) {}255static inline void kasan_poison_slab(struct slab *slab) {}
287static inline void kasan_unpoison_object_data(struct kmem_cache *cache,256static inline void kasan_unpoison_object_data(struct kmem_cache *cache,
288 void *object) {}257 void *object) {}
@@ -333,6 +302,11 @@ static inline void kasan_unpoison_task_stack(struct task_struct *task) {} · 44 unmodified lines
333 302
334#ifdef CONFIG_KASAN_GENERIC303#ifdef CONFIG_KASAN_GENERIC
335 304
305size_t kasan_metadata_size(struct kmem_cache *cache);
306slab_flags_t kasan_never_merge(void);
307void kasan_cache_create(struct kmem_cache *cache, unsigned int *size,
308 slab_flags_t *flags);
309
336void kasan_cache_shrink(struct kmem_cache *cache);310void kasan_cache_shrink(struct kmem_cache *cache);
337void kasan_cache_shutdown(struct kmem_cache *cache);311void kasan_cache_shutdown(struct kmem_cache *cache);
338void kasan_record_aux_stack(void *ptr);312void kasan_record_aux_stack(void *ptr);
@@ -340,6 +314,21 @@ void kasan_record_aux_stack_noalloc(void *ptr); · 1 unmodified line
340 314
341#else /* CONFIG_KASAN_GENERIC */315#else /* CONFIG_KASAN_GENERIC */
342 316
317/* Tag-based KASAN modes do not use per-object metadata. */
318static inline size_t kasan_metadata_size(struct kmem_cache *cache)
319{
320 return 0;
321}
322/* And thus nothing prevents cache merging. */
323static inline slab_flags_t kasan_never_merge(void)
324{
325 return 0;
326}
327/* And no cache-related metadata initialization is required. */
328static inline void kasan_cache_create(struct kmem_cache *cache,
329 unsigned int *size,
330 slab_flags_t *flags) {}
331
343static inline void kasan_cache_shrink(struct kmem_cache *cache) {}332static inline void kasan_cache_shrink(struct kmem_cache *cache) {}
344static inline void kasan_cache_shutdown(struct kmem_cache *cache) {}333static inline void kasan_cache_shutdown(struct kmem_cache *cache) {}
345static inline void kasan_record_aux_stack(void *ptr) {}334static inline void kasan_record_aux_stack(void *ptr) {}
include/linux/khugepaged.h+8−5
@@ -16,11 +16,13 @@ extern void khugepaged_enter_vma(struct vm_area_struct *vma, · 15 unmodified lines
16 unsigned long vm_flags);16 unsigned long vm_flags);
17extern void khugepaged_min_free_kbytes_update(void);17extern void khugepaged_min_free_kbytes_update(void);
18#ifdef CONFIG_SHMEM18#ifdef CONFIG_SHMEM
19extern void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr);19extern int collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr,
20 bool install_pmd);
20#else21#else
21static inline void collapse_pte_mapped_thp(struct mm_struct *mm,22static inline int collapse_pte_mapped_thp(struct mm_struct *mm,
22 unsigned long addr)23 unsigned long addr, bool install_pmd)
23{24{
25 return 0;
24}26}
25#endif27#endif
26 28
@@ -46,9 +48,10 @@ static inline void khugepaged_enter_vma(struct vm_area_struct *vma, · 19 unmodified lines
46 unsigned long vm_flags)48 unsigned long vm_flags)
47{49{
48}50}
49static inline void collapse_pte_mapped_thp(struct mm_struct *mm,51static inline int collapse_pte_mapped_thp(struct mm_struct *mm,
50 unsigned long addr)52 unsigned long addr, bool install_pmd)
51{53{
54 return 0;
52}55}
53 56
54static inline void khugepaged_min_free_kbytes_update(void)57static inline void khugepaged_min_free_kbytes_update(void)
include/linux/kmsan-checks.h+83−0
@@ -0,0 +1,83 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * KMSAN checks to be used for one-off annotations in subsystems.
4 *
5 * Copyright (C) 2017-2022 Google LLC
6 * Author: Alexander Potapenko <glider@google.com>
7 *
8 */
9
10#ifndef _LINUX_KMSAN_CHECKS_H
11#define _LINUX_KMSAN_CHECKS_H
12
13#include <linux/types.h>
14
15#ifdef CONFIG_KMSAN
16
17/**
18 * kmsan_poison_memory() - Mark the memory range as uninitialized.
19 * @address: address to start with.
20 * @size: size of buffer to poison.
21 * @flags: GFP flags for allocations done by this function.
22 *
23 * Until other data is written to this range, KMSAN will treat it as
24 * uninitialized. Error reports for this memory will reference the call site of
25 * kmsan_poison_memory() as origin.
26 */
27void kmsan_poison_memory(const void *address, size_t size, gfp_t flags);
28
29/**
30 * kmsan_unpoison_memory() - Mark the memory range as initialized.
31 * @address: address to start with.
32 * @size: size of buffer to unpoison.
33 *
34 * Until other data is written to this range, KMSAN will treat it as
35 * initialized.
36 */
37void kmsan_unpoison_memory(const void *address, size_t size);
38
39/**
40 * kmsan_check_memory() - Check the memory range for being initialized.
41 * @address: address to start with.
42 * @size: size of buffer to check.
43 *
44 * If any piece of the given range is marked as uninitialized, KMSAN will report
45 * an error.
46 */
47void kmsan_check_memory(const void *address, size_t size);
48
49/**
50 * kmsan_copy_to_user() - Notify KMSAN about a data transfer to userspace.
51 * @to: destination address in the userspace.
52 * @from: source address in the kernel.
53 * @to_copy: number of bytes to copy.
54 * @left: number of bytes not copied.
55 *
56 * If this is a real userspace data transfer, KMSAN checks the bytes that were
57 * actually copied to ensure there was no information leak. If @to belongs to
58 * the kernel space (which is possible for compat syscalls), KMSAN just copies
59 * the metadata.
60 */
61void kmsan_copy_to_user(void __user *to, const void *from, size_t to_copy,
62 size_t left);
63
64#else
65
66static inline void kmsan_poison_memory(const void *address, size_t size,
67 gfp_t flags)
68{
69}
70static inline void kmsan_unpoison_memory(const void *address, size_t size)
71{
72}
73static inline void kmsan_check_memory(const void *address, size_t size)
74{
75}
76static inline void kmsan_copy_to_user(void __user *to, const void *from,
77 size_t to_copy, size_t left)
78{
79}
80
81#endif
82
83#endif /* _LINUX_KMSAN_CHECKS_H */
include/linux/kmsan.h+330−0
@@ -0,0 +1,330 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * KMSAN API for subsystems.
4 *
5 * Copyright (C) 2017-2022 Google LLC
6 * Author: Alexander Potapenko <glider@google.com>
7 *
8 */
9#ifndef _LINUX_KMSAN_H
10#define _LINUX_KMSAN_H
11
12#include <linux/dma-direction.h>
13#include <linux/gfp.h>
14#include <linux/kmsan-checks.h>
15#include <linux/types.h>
16
17struct page;
18struct kmem_cache;
19struct task_struct;
20struct scatterlist;
21struct urb;
22
23#ifdef CONFIG_KMSAN
24
25/**
26 * kmsan_task_create() - Initialize KMSAN state for the task.
27 * @task: task to initialize.
28 */
29void kmsan_task_create(struct task_struct *task);
30
31/**
32 * kmsan_task_exit() - Notify KMSAN that a task has exited.
33 * @task: task about to finish.
34 */
35void kmsan_task_exit(struct task_struct *task);
36
37/**
38 * kmsan_init_shadow() - Initialize KMSAN shadow at boot time.
39 *
40 * Allocate and initialize KMSAN metadata for early allocations.
41 */
42void __init kmsan_init_shadow(void);
43
44/**
45 * kmsan_init_runtime() - Initialize KMSAN state and enable KMSAN.
46 */
47void __init kmsan_init_runtime(void);
48
49/**
50 * kmsan_memblock_free_pages() - handle freeing of memblock pages.
51 * @page: struct page to free.
52 * @order: order of @page.
53 *
54 * Freed pages are either returned to buddy allocator or held back to be used
55 * as metadata pages.
56 */
57bool __init kmsan_memblock_free_pages(struct page *page, unsigned int order);
58
59/**
60 * kmsan_alloc_page() - Notify KMSAN about an alloc_pages() call.
61 * @page: struct page pointer returned by alloc_pages().
62 * @order: order of allocated struct page.
63 * @flags: GFP flags used by alloc_pages()
64 *
65 * KMSAN marks 1<<@order pages starting at @page as uninitialized, unless
66 * @flags contain __GFP_ZERO.
67 */
68void kmsan_alloc_page(struct page *page, unsigned int order, gfp_t flags);
69
70/**
71 * kmsan_free_page() - Notify KMSAN about a free_pages() call.
72 * @page: struct page pointer passed to free_pages().
73 * @order: order of deallocated struct page.
74 *
75 * KMSAN marks freed memory as uninitialized.
76 */
77void kmsan_free_page(struct page *page, unsigned int order);
78
79/**
80 * kmsan_copy_page_meta() - Copy KMSAN metadata between two pages.
81 * @dst: destination page.
82 * @src: source page.
83 *
84 * KMSAN copies the contents of metadata pages for @src into the metadata pages
85 * for @dst. If @dst has no associated metadata pages, nothing happens.
86 * If @src has no associated metadata pages, @dst metadata pages are unpoisoned.
87 */
88void kmsan_copy_page_meta(struct page *dst, struct page *src);
89
90/**
91 * kmsan_slab_alloc() - Notify KMSAN about a slab allocation.
92 * @s: slab cache the object belongs to.
93 * @object: object pointer.
94 * @flags: GFP flags passed to the allocator.
95 *
96 * Depending on cache flags and GFP flags, KMSAN sets up the metadata of the
97 * newly created object, marking it as initialized or uninitialized.
98 */
99void kmsan_slab_alloc(struct kmem_cache *s, void *object, gfp_t flags);
100
101/**
102 * kmsan_slab_free() - Notify KMSAN about a slab deallocation.
103 * @s: slab cache the object belongs to.
104 * @object: object pointer.
105 *
106 * KMSAN marks the freed object as uninitialized.
107 */
108void kmsan_slab_free(struct kmem_cache *s, void *object);
109
110/**
111 * kmsan_kmalloc_large() - Notify KMSAN about a large slab allocation.
112 * @ptr: object pointer.
113 * @size: object size.
114 * @flags: GFP flags passed to the allocator.
115 *
116 * Similar to kmsan_slab_alloc(), but for large allocations.
117 */
118void kmsan_kmalloc_large(const void *ptr, size_t size, gfp_t flags);
119
120/**
121 * kmsan_kfree_large() - Notify KMSAN about a large slab deallocation.
122 * @ptr: object pointer.
123 *
124 * Similar to kmsan_slab_free(), but for large allocations.
125 */
126void kmsan_kfree_large(const void *ptr);
127
128/**
129 * kmsan_map_kernel_range_noflush() - Notify KMSAN about a vmap.
130 * @start: start of vmapped range.
131 * @end: end of vmapped range.
132 * @prot: page protection flags used for vmap.
133 * @pages: array of pages.
134 * @page_shift: page_shift passed to vmap_range_noflush().
135 *
136 * KMSAN maps shadow and origin pages of @pages into contiguous ranges in
137 * vmalloc metadata address range.
138 */
139void kmsan_vmap_pages_range_noflush(unsigned long start, unsigned long end,
140 pgprot_t prot, struct page **pages,
141 unsigned int page_shift);
142
143/**
144 * kmsan_vunmap_kernel_range_noflush() - Notify KMSAN about a vunmap.
145 * @start: start of vunmapped range.
146 * @end: end of vunmapped range.
147 *
148 * KMSAN unmaps the contiguous metadata ranges created by
149 * kmsan_map_kernel_range_noflush().
150 */
151void kmsan_vunmap_range_noflush(unsigned long start, unsigned long end);
152
153/**
154 * kmsan_ioremap_page_range() - Notify KMSAN about a ioremap_page_range() call.
155 * @addr: range start.
156 * @end: range end.
157 * @phys_addr: physical range start.
158 * @prot: page protection flags used for ioremap_page_range().
159 * @page_shift: page_shift argument passed to vmap_range_noflush().
160 *
161 * KMSAN creates new metadata pages for the physical pages mapped into the
162 * virtual memory.
163 */
164void kmsan_ioremap_page_range(unsigned long addr, unsigned long end,
165 phys_addr_t phys_addr, pgprot_t prot,
166 unsigned int page_shift);
167
168/**
169 * kmsan_iounmap_page_range() - Notify KMSAN about a iounmap_page_range() call.
170 * @start: range start.
171 * @end: range end.
172 *
173 * KMSAN unmaps the metadata pages for the given range and, unlike for
174 * vunmap_page_range(), also deallocates them.
175 */
176void kmsan_iounmap_page_range(unsigned long start, unsigned long end);
177
178/**
179 * kmsan_handle_dma() - Handle a DMA data transfer.
180 * @page: first page of the buffer.
181 * @offset: offset of the buffer within the first page.
182 * @size: buffer size.
183 * @dir: one of possible dma_data_direction values.
184 *
185 * Depending on @direction, KMSAN:
186 * * checks the buffer, if it is copied to device;
187 * * initializes the buffer, if it is copied from device;
188 * * does both, if this is a DMA_BIDIRECTIONAL transfer.
189 */
190void kmsan_handle_dma(struct page *page, size_t offset, size_t size,
191 enum dma_data_direction dir);
192
193/**
194 * kmsan_handle_dma_sg() - Handle a DMA transfer using scatterlist.
195 * @sg: scatterlist holding DMA buffers.
196 * @nents: number of scatterlist entries.
197 * @dir: one of possible dma_data_direction values.
198 *
199 * Depending on @direction, KMSAN:
200 * * checks the buffers in the scatterlist, if they are copied to device;
201 * * initializes the buffers, if they are copied from device;
202 * * does both, if this is a DMA_BIDIRECTIONAL transfer.
203 */
204void kmsan_handle_dma_sg(struct scatterlist *sg, int nents,
205 enum dma_data_direction dir);
206
207/**
208 * kmsan_handle_urb() - Handle a USB data transfer.
209 * @urb: struct urb pointer.
210 * @is_out: data transfer direction (true means output to hardware).
211 *
212 * If @is_out is true, KMSAN checks the transfer buffer of @urb. Otherwise,
213 * KMSAN initializes the transfer buffer.
214 */
215void kmsan_handle_urb(const struct urb *urb, bool is_out);
216
217/**
218 * kmsan_unpoison_entry_regs() - Handle pt_regs in low-level entry code.
219 * @regs: struct pt_regs pointer received from assembly code.
220 *
221 * KMSAN unpoisons the contents of the passed pt_regs, preventing potential
222 * false positive reports. Unlike kmsan_unpoison_memory(),
223 * kmsan_unpoison_entry_regs() can be called from the regions where
224 * kmsan_in_runtime() returns true, which is the case in early entry code.
225 */
226void kmsan_unpoison_entry_regs(const struct pt_regs *regs);
227
228#else
229
230static inline void kmsan_init_shadow(void)
231{
232}
233
234static inline void kmsan_init_runtime(void)
235{
236}
237
238static inline bool kmsan_memblock_free_pages(struct page *page,
239 unsigned int order)
240{
241 return true;
242}
243
244static inline void kmsan_task_create(struct task_struct *task)
245{
246}
247
248static inline void kmsan_task_exit(struct task_struct *task)
249{
250}
251
252static inline int kmsan_alloc_page(struct page *page, unsigned int order,
253 gfp_t flags)
254{
255 return 0;
256}
257
258static inline void kmsan_free_page(struct page *page, unsigned int order)
259{
260}
261
262static inline void kmsan_copy_page_meta(struct page *dst, struct page *src)
263{
264}
265
266static inline void kmsan_slab_alloc(struct kmem_cache *s, void *object,
267 gfp_t flags)
268{
269}
270
271static inline void kmsan_slab_free(struct kmem_cache *s, void *object)
272{
273}
274
275static inline void kmsan_kmalloc_large(const void *ptr, size_t size,
276 gfp_t flags)
277{
278}
279
280static inline void kmsan_kfree_large(const void *ptr)
281{
282}
283
284static inline void kmsan_vmap_pages_range_noflush(unsigned long start,
285 unsigned long end,
286 pgprot_t prot,
287 struct page **pages,
288 unsigned int page_shift)
289{
290}
291
292static inline void kmsan_vunmap_range_noflush(unsigned long start,
293 unsigned long end)
294{
295}
296
297static inline void kmsan_ioremap_page_range(unsigned long start,
298 unsigned long end,
299 phys_addr_t phys_addr,
300 pgprot_t prot,
301 unsigned int page_shift)
302{
303}
304
305static inline void kmsan_iounmap_page_range(unsigned long start,
306 unsigned long end)
307{
308}
309
310static inline void kmsan_handle_dma(struct page *page, size_t offset,
311 size_t size, enum dma_data_direction dir)
312{
313}
314
315static inline void kmsan_handle_dma_sg(struct scatterlist *sg, int nents,
316 enum dma_data_direction dir)
317{
318}
319
320static inline void kmsan_handle_urb(const struct urb *urb, bool is_out)
321{
322}
323
324static inline void kmsan_unpoison_entry_regs(const struct pt_regs *regs)
325{
326}
327
328#endif
329
330#endif /* _LINUX_KMSAN_H */
include/linux/kmsan_types.h+35−0
@@ -0,0 +1,35 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * A minimal header declaring types added by KMSAN to existing kernel structs.
4 *
5 * Copyright (C) 2017-2022 Google LLC
6 * Author: Alexander Potapenko <glider@google.com>
7 *
8 */
9#ifndef _LINUX_KMSAN_TYPES_H
10#define _LINUX_KMSAN_TYPES_H
11
12/* These constants are defined in the MSan LLVM instrumentation pass. */
13#define KMSAN_RETVAL_SIZE 800
14#define KMSAN_PARAM_SIZE 800
15
16struct kmsan_context_state {
17 char param_tls[KMSAN_PARAM_SIZE];
18 char retval_tls[KMSAN_RETVAL_SIZE];
19 char va_arg_tls[KMSAN_PARAM_SIZE];
20 char va_arg_origin_tls[KMSAN_PARAM_SIZE];
21 u64 va_arg_overflow_size_tls;
22 char param_origin_tls[KMSAN_PARAM_SIZE];
23 u32 retval_origin_tls;
24};
25
26#undef KMSAN_PARAM_SIZE
27#undef KMSAN_RETVAL_SIZE
28
29struct kmsan_ctx {
30 struct kmsan_context_state cstate;
31 int kmsan_in_runtime;
32 bool allow_reporting;
33};
34
35#endif /* _LINUX_KMSAN_TYPES_H */
include/linux/ksm.h+0−3
@@ -15,9 +15,6 @@ · 14 unmodified lines
15#include <linux/sched.h>15#include <linux/sched.h>
16#include <linux/sched/coredump.h>16#include <linux/sched/coredump.h>
17 17
18struct stable_node;
19struct mem_cgroup;
20
21#ifdef CONFIG_KSM18#ifdef CONFIG_KSM
22int ksm_madvise(struct vm_area_struct *vma, unsigned long start,19int ksm_madvise(struct vm_area_struct *vma, unsigned long start,
23 unsigned long end, int advice, unsigned long *vm_flags);20 unsigned long end, int advice, unsigned long *vm_flags);
include/linux/maple_tree.h+685−0
@@ -0,0 +1,685 @@
1/* SPDX-License-Identifier: GPL-2.0+ */
2#ifndef _LINUX_MAPLE_TREE_H
3#define _LINUX_MAPLE_TREE_H
4/*
5 * Maple Tree - An RCU-safe adaptive tree for storing ranges
6 * Copyright (c) 2018-2022 Oracle
7 * Authors: Liam R. Howlett <Liam.Howlett@Oracle.com>
8 * Matthew Wilcox <willy@infradead.org>
9 */
10
11#include <linux/kernel.h>
12#include <linux/rcupdate.h>
13#include <linux/spinlock.h>
14/* #define CONFIG_MAPLE_RCU_DISABLED */
15/* #define CONFIG_DEBUG_MAPLE_TREE_VERBOSE */
16
17/*
18 * Allocated nodes are mutable until they have been inserted into the tree,
19 * at which time they cannot change their type until they have been removed
20 * from the tree and an RCU grace period has passed.
21 *
22 * Removed nodes have their ->parent set to point to themselves. RCU readers
23 * check ->parent before relying on the value that they loaded from the
24 * slots array. This lets us reuse the slots array for the RCU head.
25 *
26 * Nodes in the tree point to their parent unless bit 0 is set.
27 */
28#if defined(CONFIG_64BIT) || defined(BUILD_VDSO32_64)
29/* 64bit sizes */
30#define MAPLE_NODE_SLOTS 31 /* 256 bytes including ->parent */
31#define MAPLE_RANGE64_SLOTS 16 /* 256 bytes */
32#define MAPLE_ARANGE64_SLOTS 10 /* 240 bytes */
33#define MAPLE_ARANGE64_META_MAX 15 /* Out of range for metadata */
34#define MAPLE_ALLOC_SLOTS (MAPLE_NODE_SLOTS - 1)
35#else
36/* 32bit sizes */
37#define MAPLE_NODE_SLOTS 63 /* 256 bytes including ->parent */
38#define MAPLE_RANGE64_SLOTS 32 /* 256 bytes */
39#define MAPLE_ARANGE64_SLOTS 21 /* 240 bytes */
40#define MAPLE_ARANGE64_META_MAX 31 /* Out of range for metadata */
41#define MAPLE_ALLOC_SLOTS (MAPLE_NODE_SLOTS - 2)
42#endif /* defined(CONFIG_64BIT) || defined(BUILD_VDSO32_64) */
43
44#define MAPLE_NODE_MASK 255UL
45
46/*
47 * The node->parent of the root node has bit 0 set and the rest of the pointer
48 * is a pointer to the tree itself. No more bits are available in this pointer
49 * (on m68k, the data structure may only be 2-byte aligned).
50 *
51 * Internal non-root nodes can only have maple_range_* nodes as parents. The
52 * parent pointer is 256B aligned like all other tree nodes. When storing a 32
53 * or 64 bit values, the offset can fit into 4 bits. The 16 bit values need an
54 * extra bit to store the offset. This extra bit comes from a reuse of the last
55 * bit in the node type. This is possible by using bit 1 to indicate if bit 2
56 * is part of the type or the slot.
57 *
58 * Once the type is decided, the decision of an allocation range type or a range
59 * type is done by examining the immutable tree flag for the MAPLE_ALLOC_RANGE
60 * flag.
61 *
62 * Node types:
63 * 0x??1 = Root
64 * 0x?00 = 16 bit nodes
65 * 0x010 = 32 bit nodes
66 * 0x110 = 64 bit nodes
67 *
68 * Slot size and location in the parent pointer:
69 * type : slot location
70 * 0x??1 : Root
71 * 0x?00 : 16 bit values, type in 0-1, slot in 2-6
72 * 0x010 : 32 bit values, type in 0-2, slot in 3-6
73 * 0x110 : 64 bit values, type in 0-2, slot in 3-6
74 */
75
76/*
77 * This metadata is used to optimize the gap updating code and in reverse
78 * searching for gaps or any other code that needs to find the end of the data.
79 */
80struct maple_metadata {
81 unsigned char end;
82 unsigned char gap;
83};
84
85/*
86 * Leaf nodes do not store pointers to nodes, they store user data. Users may
87 * store almost any bit pattern. As noted above, the optimisation of storing an
88 * entry at 0 in the root pointer cannot be done for data which have the bottom
89 * two bits set to '10'. We also reserve values with the bottom two bits set to
90 * '10' which are below 4096 (ie 2, 6, 10 .. 4094) for internal use. Some APIs
91 * return errnos as a negative errno shifted right by two bits and the bottom
92 * two bits set to '10', and while choosing to store these values in the array
93 * is not an error, it may lead to confusion if you're testing for an error with
94 * mas_is_err().
95 *
96 * Non-leaf nodes store the type of the node pointed to (enum maple_type in bits
97 * 3-6), bit 2 is reserved. That leaves bits 0-1 unused for now.
98 *
99 * In regular B-Tree terms, pivots are called keys. The term pivot is used to
100 * indicate that the tree is specifying ranges, Pivots may appear in the
101 * subtree with an entry attached to the value whereas keys are unique to a
102 * specific position of a B-tree. Pivot values are inclusive of the slot with
103 * the same index.
104 */
105
106struct maple_range_64 {
107 struct maple_pnode *parent;
108 unsigned long pivot[MAPLE_RANGE64_SLOTS - 1];
109 union {
110 void __rcu *slot[MAPLE_RANGE64_SLOTS];
111 struct {
112 void __rcu *pad[MAPLE_RANGE64_SLOTS - 1];
113 struct maple_metadata meta;
114 };
115 };
116};
117
118/*
119 * At tree creation time, the user can specify that they're willing to trade off
120 * storing fewer entries in a tree in return for storing more information in
121 * each node.
122 *
123 * The maple tree supports recording the largest range of NULL entries available
124 * in this node, also called gaps. This optimises the tree for allocating a
125 * range.
126 */
127struct maple_arange_64 {
128 struct maple_pnode *parent;
129 unsigned long pivot[MAPLE_ARANGE64_SLOTS - 1];
130 void __rcu *slot[MAPLE_ARANGE64_SLOTS];
131 unsigned long gap[MAPLE_ARANGE64_SLOTS];
132 struct maple_metadata meta;
133};
134
135struct maple_alloc {
136 unsigned long total;
137 unsigned char node_count;
138 unsigned int request_count;
139 struct maple_alloc *slot[MAPLE_ALLOC_SLOTS];
140};
141
142struct maple_topiary {
143 struct maple_pnode *parent;
144 struct maple_enode *next; /* Overlaps the pivot */
145};
146
147enum maple_type {
148 maple_dense,
149 maple_leaf_64,
150 maple_range_64,
151 maple_arange_64,
152};
153
154
155/**
156 * DOC: Maple tree flags
157 *
158 * * MT_FLAGS_ALLOC_RANGE - Track gaps in this tree
159 * * MT_FLAGS_USE_RCU - Operate in RCU mode
160 * * MT_FLAGS_HEIGHT_OFFSET - The position of the tree height in the flags
161 * * MT_FLAGS_HEIGHT_MASK - The mask for the maple tree height value
162 * * MT_FLAGS_LOCK_MASK - How the mt_lock is used
163 * * MT_FLAGS_LOCK_IRQ - Acquired irq-safe
164 * * MT_FLAGS_LOCK_BH - Acquired bh-safe
165 * * MT_FLAGS_LOCK_EXTERN - mt_lock is not used
166 *
167 * MAPLE_HEIGHT_MAX The largest height that can be stored
168 */
169#define MT_FLAGS_ALLOC_RANGE 0x01
170#define MT_FLAGS_USE_RCU 0x02
171#define MT_FLAGS_HEIGHT_OFFSET 0x02
172#define MT_FLAGS_HEIGHT_MASK 0x7C
173#define MT_FLAGS_LOCK_MASK 0x300
174#define MT_FLAGS_LOCK_IRQ 0x100
175#define MT_FLAGS_LOCK_BH 0x200
176#define MT_FLAGS_LOCK_EXTERN 0x300
177
178#define MAPLE_HEIGHT_MAX 31
179
180
181#define MAPLE_NODE_TYPE_MASK 0x0F
182#define MAPLE_NODE_TYPE_SHIFT 0x03
183
184#define MAPLE_RESERVED_RANGE 4096
185
186#ifdef CONFIG_LOCKDEP
187typedef struct lockdep_map *lockdep_map_p;
188#define mt_lock_is_held(mt) lock_is_held(mt->ma_external_lock)
189#define mt_set_external_lock(mt, lock) \
190 (mt)->ma_external_lock = &(lock)->dep_map
191#else
192typedef struct { /* nothing */ } lockdep_map_p;
193#define mt_lock_is_held(mt) 1
194#define mt_set_external_lock(mt, lock) do { } while (0)
195#endif
196
197/*
198 * If the tree contains a single entry at index 0, it is usually stored in
199 * tree->ma_root. To optimise for the page cache, an entry which ends in '00',
200 * '01' or '11' is stored in the root, but an entry which ends in '10' will be
201 * stored in a node. Bits 3-6 are used to store enum maple_type.
202 *
203 * The flags are used both to store some immutable information about this tree
204 * (set at tree creation time) and dynamic information set under the spinlock.
205 *
206 * Another use of flags are to indicate global states of the tree. This is the
207 * case with the MAPLE_USE_RCU flag, which indicates the tree is currently in
208 * RCU mode. This mode was added to allow the tree to reuse nodes instead of
209 * re-allocating and RCU freeing nodes when there is a single user.
210 */
211struct maple_tree {
212 union {
213 spinlock_t ma_lock;
214 lockdep_map_p ma_external_lock;
215 };
216 void __rcu *ma_root;
217 unsigned int ma_flags;
218};
219
220/**
221 * MTREE_INIT() - Initialize a maple tree
222 * @name: The maple tree name
223 * @__flags: The maple tree flags
224 *
225 */
226#define MTREE_INIT(name, __flags) { \
227 .ma_lock = __SPIN_LOCK_UNLOCKED((name).ma_lock), \
228 .ma_flags = __flags, \
229 .ma_root = NULL, \
230}
231
232/**
233 * MTREE_INIT_EXT() - Initialize a maple tree with an external lock.
234 * @name: The tree name
235 * @__flags: The maple tree flags
236 * @__lock: The external lock
237 */
238#ifdef CONFIG_LOCKDEP
239#define MTREE_INIT_EXT(name, __flags, __lock) { \
240 .ma_external_lock = &(__lock).dep_map, \
241 .ma_flags = (__flags), \
242 .ma_root = NULL, \
243}
244#else
245#define MTREE_INIT_EXT(name, __flags, __lock) MTREE_INIT(name, __flags)
246#endif
247
248#define DEFINE_MTREE(name) \
249 struct maple_tree name = MTREE_INIT(name, 0)
250
251#define mtree_lock(mt) spin_lock((&(mt)->ma_lock))
252#define mtree_unlock(mt) spin_unlock((&(mt)->ma_lock))
253
254/*
255 * The Maple Tree squeezes various bits in at various points which aren't
256 * necessarily obvious. Usually, this is done by observing that pointers are
257 * N-byte aligned and thus the bottom log_2(N) bits are available for use. We
258 * don't use the high bits of pointers to store additional information because
259 * we don't know what bits are unused on any given architecture.
260 *
261 * Nodes are 256 bytes in size and are also aligned to 256 bytes, giving us 8
262 * low bits for our own purposes. Nodes are currently of 4 types:
263 * 1. Single pointer (Range is 0-0)
264 * 2. Non-leaf Allocation Range nodes
265 * 3. Non-leaf Range nodes
266 * 4. Leaf Range nodes All nodes consist of a number of node slots,
267 * pivots, and a parent pointer.
268 */
269
270struct maple_node {
271 union {
272 struct {
273 struct maple_pnode *parent;
274 void __rcu *slot[MAPLE_NODE_SLOTS];
275 };
276 struct {
277 void *pad;
278 struct rcu_head rcu;
279 struct maple_enode *piv_parent;
280 unsigned char parent_slot;
281 enum maple_type type;
282 unsigned char slot_len;
283 unsigned int ma_flags;
284 };
285 struct maple_range_64 mr64;
286 struct maple_arange_64 ma64;
287 struct maple_alloc alloc;
288 };
289};
290
291/*
292 * More complicated stores can cause two nodes to become one or three and
293 * potentially alter the height of the tree. Either half of the tree may need
294 * to be rebalanced against the other. The ma_topiary struct is used to track
295 * which nodes have been 'cut' from the tree so that the change can be done
296 * safely at a later date. This is done to support RCU.
297 */
298struct ma_topiary {
299 struct maple_enode *head;
300 struct maple_enode *tail;
301 struct maple_tree *mtree;
302};
303
304void *mtree_load(struct maple_tree *mt, unsigned long index);
305
306int mtree_insert(struct maple_tree *mt, unsigned long index,
307 void *entry, gfp_t gfp);
308int mtree_insert_range(struct maple_tree *mt, unsigned long first,
309 unsigned long last, void *entry, gfp_t gfp);
310int mtree_alloc_range(struct maple_tree *mt, unsigned long *startp,
311 void *entry, unsigned long size, unsigned long min,
312 unsigned long max, gfp_t gfp);
313int mtree_alloc_rrange(struct maple_tree *mt, unsigned long *startp,
314 void *entry, unsigned long size, unsigned long min,
315 unsigned long max, gfp_t gfp);
316
317int mtree_store_range(struct maple_tree *mt, unsigned long first,
318 unsigned long last, void *entry, gfp_t gfp);
319int mtree_store(struct maple_tree *mt, unsigned long index,
320 void *entry, gfp_t gfp);
321void *mtree_erase(struct maple_tree *mt, unsigned long index);
322
323void mtree_destroy(struct maple_tree *mt);
324void __mt_destroy(struct maple_tree *mt);
325
326/**
327 * mtree_empty() - Determine if a tree has any present entries.
328 * @mt: Maple Tree.
329 *
330 * Context: Any context.
331 * Return: %true if the tree contains only NULL pointers.
332 */
333static inline bool mtree_empty(const struct maple_tree *mt)
334{
335 return mt->ma_root == NULL;
336}
337
338/* Advanced API */
339
340/*
341 * The maple state is defined in the struct ma_state and is used to keep track
342 * of information during operations, and even between operations when using the
343 * advanced API.
344 *
345 * If state->node has bit 0 set then it references a tree location which is not
346 * a node (eg the root). If bit 1 is set, the rest of the bits are a negative
347 * errno. Bit 2 (the 'unallocated slots' bit) is clear. Bits 3-6 indicate the
348 * node type.
349 *
350 * state->alloc either has a request number of nodes or an allocated node. If
351 * stat->alloc has a requested number of nodes, the first bit will be set (0x1)
352 * and the remaining bits are the value. If state->alloc is a node, then the
353 * node will be of type maple_alloc. maple_alloc has MAPLE_NODE_SLOTS - 1 for
354 * storing more allocated nodes, a total number of nodes allocated, and the
355 * node_count in this node. node_count is the number of allocated nodes in this
356 * node. The scaling beyond MAPLE_NODE_SLOTS - 1 is handled by storing further
357 * nodes into state->alloc->slot[0]'s node. Nodes are taken from state->alloc
358 * by removing a node from the state->alloc node until state->alloc->node_count
359 * is 1, when state->alloc is returned and the state->alloc->slot[0] is promoted
360 * to state->alloc. Nodes are pushed onto state->alloc by putting the current
361 * state->alloc into the pushed node's slot[0].
362 *
363 * The state also contains the implied min/max of the state->node, the depth of
364 * this search, and the offset. The implied min/max are either from the parent
365 * node or are 0-oo for the root node. The depth is incremented or decremented
366 * every time a node is walked down or up. The offset is the slot/pivot of
367 * interest in the node - either for reading or writing.
368 *
369 * When returning a value the maple state index and last respectively contain
370 * the start and end of the range for the entry. Ranges are inclusive in the
371 * Maple Tree.
372 */
373struct ma_state {
374 struct maple_tree *tree; /* The tree we're operating in */
375 unsigned long index; /* The index we're operating on - range start */
376 unsigned long last; /* The last index we're operating on - range end */
377 struct maple_enode *node; /* The node containing this entry */
378 unsigned long min; /* The minimum index of this node - implied pivot min */
379 unsigned long max; /* The maximum index of this node - implied pivot max */
380 struct maple_alloc *alloc; /* Allocated nodes for this operation */
381 unsigned char depth; /* depth of tree descent during write */
382 unsigned char offset;
383 unsigned char mas_flags;
384};
385
386struct ma_wr_state {
387 struct ma_state *mas;
388 struct maple_node *node; /* Decoded mas->node */
389 unsigned long r_min; /* range min */
390 unsigned long r_max; /* range max */
391 enum maple_type type; /* mas->node type */
392 unsigned char offset_end; /* The offset where the write ends */
393 unsigned char node_end; /* mas->node end */
394 unsigned long *pivots; /* mas->node->pivots pointer */
395 unsigned long end_piv; /* The pivot at the offset end */
396 void __rcu **slots; /* mas->node->slots pointer */
397 void *entry; /* The entry to write */
398 void *content; /* The existing entry that is being overwritten */
399};
400
401#define mas_lock(mas) spin_lock(&((mas)->tree->ma_lock))
402#define mas_unlock(mas) spin_unlock(&((mas)->tree->ma_lock))
403
404
405/*
406 * Special values for ma_state.node.
407 * MAS_START means we have not searched the tree.
408 * MAS_ROOT means we have searched the tree and the entry we found lives in
409 * the root of the tree (ie it has index 0, length 1 and is the only entry in
410 * the tree).
411 * MAS_NONE means we have searched the tree and there is no node in the
412 * tree for this entry. For example, we searched for index 1 in an empty
413 * tree. Or we have a tree which points to a full leaf node and we
414 * searched for an entry which is larger than can be contained in that
415 * leaf node.
416 * MA_ERROR represents an errno. After dropping the lock and attempting
417 * to resolve the error, the walk would have to be restarted from the
418 * top of the tree as the tree may have been modified.
419 */
420#define MAS_START ((struct maple_enode *)1UL)
421#define MAS_ROOT ((struct maple_enode *)5UL)
422#define MAS_NONE ((struct maple_enode *)9UL)
423#define MAS_PAUSE ((struct maple_enode *)17UL)
424#define MA_ERROR(err) \
425 ((struct maple_enode *)(((unsigned long)err << 2) | 2UL))
426
427#define MA_STATE(name, mt, first, end) \
428 struct ma_state name = { \
429 .tree = mt, \
430 .index = first, \
431 .last = end, \
432 .node = MAS_START, \
433 .min = 0, \
434 .max = ULONG_MAX, \
435 .alloc = NULL, \
436 }
437
438#define MA_WR_STATE(name, ma_state, wr_entry) \
439 struct ma_wr_state name = { \
440 .mas = ma_state, \
441 .content = NULL, \
442 .entry = wr_entry, \
443 }
444
445#define MA_TOPIARY(name, tree) \
446 struct ma_topiary name = { \
447 .head = NULL, \
448 .tail = NULL, \
449 .mtree = tree, \
450 }
451
452void *mas_walk(struct ma_state *mas);
453void *mas_store(struct ma_state *mas, void *entry);
454void *mas_erase(struct ma_state *mas);
455int mas_store_gfp(struct ma_state *mas, void *entry, gfp_t gfp);
456void mas_store_prealloc(struct ma_state *mas, void *entry);
457void *mas_find(struct ma_state *mas, unsigned long max);
458void *mas_find_rev(struct ma_state *mas, unsigned long min);
459int mas_preallocate(struct ma_state *mas, void *entry, gfp_t gfp);
460bool mas_is_err(struct ma_state *mas);
461
462bool mas_nomem(struct ma_state *mas, gfp_t gfp);
463void mas_pause(struct ma_state *mas);
464void maple_tree_init(void);
465void mas_destroy(struct ma_state *mas);
466int mas_expected_entries(struct ma_state *mas, unsigned long nr_entries);
467
468void *mas_prev(struct ma_state *mas, unsigned long min);
469void *mas_next(struct ma_state *mas, unsigned long max);
470
471int mas_empty_area(struct ma_state *mas, unsigned long min, unsigned long max,
472 unsigned long size);
473
474/* Checks if a mas has not found anything */
475static inline bool mas_is_none(struct ma_state *mas)
476{
477 return mas->node == MAS_NONE;
478}
479
480/* Checks if a mas has been paused */
481static inline bool mas_is_paused(struct ma_state *mas)
482{
483 return mas->node == MAS_PAUSE;
484}
485
486void mas_dup_tree(struct ma_state *oldmas, struct ma_state *mas);
487void mas_dup_store(struct ma_state *mas, void *entry);
488
489/*
490 * This finds an empty area from the highest address to the lowest.
491 * AKA "Topdown" version,
492 */
493int mas_empty_area_rev(struct ma_state *mas, unsigned long min,
494 unsigned long max, unsigned long size);
495/**
496 * mas_reset() - Reset a Maple Tree operation state.
497 * @mas: Maple Tree operation state.
498 *
499 * Resets the error or walk state of the @mas so future walks of the
500 * array will start from the root. Use this if you have dropped the
501 * lock and want to reuse the ma_state.
502 *
503 * Context: Any context.
504 */
505static inline void mas_reset(struct ma_state *mas)
506{
507 mas->node = MAS_START;
508}
509
510/**
511 * mas_for_each() - Iterate over a range of the maple tree.
512 * @__mas: Maple Tree operation state (maple_state)
513 * @__entry: Entry retrieved from the tree
514 * @__max: maximum index to retrieve from the tree
515 *
516 * When returned, mas->index and mas->last will hold the entire range for the
517 * entry.
518 *
519 * Note: may return the zero entry.
520 *
521 */
522#define mas_for_each(__mas, __entry, __max) \
523 while (((__entry) = mas_find((__mas), (__max))) != NULL)
524
525
526/**
527 * mas_set_range() - Set up Maple Tree operation state for a different index.
528 * @mas: Maple Tree operation state.
529 * @start: New start of range in the Maple Tree.
530 * @last: New end of range in the Maple Tree.
531 *
532 * Move the operation state to refer to a different range. This will
533 * have the effect of starting a walk from the top; see mas_next()
534 * to move to an adjacent index.
535 */
536static inline
537void mas_set_range(struct ma_state *mas, unsigned long start, unsigned long last)
538{
539 mas->index = start;
540 mas->last = last;
541 mas->node = MAS_START;
542}
543
544/**
545 * mas_set() - Set up Maple Tree operation state for a different index.
546 * @mas: Maple Tree operation state.
547 * @index: New index into the Maple Tree.
548 *
549 * Move the operation state to refer to a different index. This will
550 * have the effect of starting a walk from the top; see mas_next()
551 * to move to an adjacent index.
552 */
553static inline void mas_set(struct ma_state *mas, unsigned long index)
554{
555
556 mas_set_range(mas, index, index);
557}
558
559static inline bool mt_external_lock(const struct maple_tree *mt)
560{
561 return (mt->ma_flags & MT_FLAGS_LOCK_MASK) == MT_FLAGS_LOCK_EXTERN;
562}
563
564/**
565 * mt_init_flags() - Initialise an empty maple tree with flags.
566 * @mt: Maple Tree
567 * @flags: maple tree flags.
568 *
569 * If you need to initialise a Maple Tree with special flags (eg, an
570 * allocation tree), use this function.
571 *
572 * Context: Any context.
573 */
574static inline void mt_init_flags(struct maple_tree *mt, unsigned int flags)
575{
576 mt->ma_flags = flags;
577 if (!mt_external_lock(mt))
578 spin_lock_init(&mt->ma_lock);
579 rcu_assign_pointer(mt->ma_root, NULL);
580}
581
582/**
583 * mt_init() - Initialise an empty maple tree.
584 * @mt: Maple Tree
585 *
586 * An empty Maple Tree.
587 *
588 * Context: Any context.
589 */
590static inline void mt_init(struct maple_tree *mt)
591{
592 mt_init_flags(mt, 0);
593}
594
595static inline bool mt_in_rcu(struct maple_tree *mt)
596{
597#ifdef CONFIG_MAPLE_RCU_DISABLED
598 return false;
599#endif
600 return mt->ma_flags & MT_FLAGS_USE_RCU;
601}
602
603/**
604 * mt_clear_in_rcu() - Switch the tree to non-RCU mode.
605 * @mt: The Maple Tree
606 */
607static inline void mt_clear_in_rcu(struct maple_tree *mt)
608{
609 if (!mt_in_rcu(mt))
610 return;
611
612 if (mt_external_lock(mt)) {
613 BUG_ON(!mt_lock_is_held(mt));
614 mt->ma_flags &= ~MT_FLAGS_USE_RCU;
615 } else {
616 mtree_lock(mt);
617 mt->ma_flags &= ~MT_FLAGS_USE_RCU;
618 mtree_unlock(mt);
619 }
620}
621
622/**
623 * mt_set_in_rcu() - Switch the tree to RCU safe mode.
624 * @mt: The Maple Tree
625 */
626static inline void mt_set_in_rcu(struct maple_tree *mt)
627{
628 if (mt_in_rcu(mt))
629 return;
630
631 if (mt_external_lock(mt)) {
632 BUG_ON(!mt_lock_is_held(mt));
633 mt->ma_flags |= MT_FLAGS_USE_RCU;
634 } else {
635 mtree_lock(mt);
636 mt->ma_flags |= MT_FLAGS_USE_RCU;
637 mtree_unlock(mt);
638 }
639}
640
641void *mt_find(struct maple_tree *mt, unsigned long *index, unsigned long max);
642void *mt_find_after(struct maple_tree *mt, unsigned long *index,
643 unsigned long max);
644void *mt_prev(struct maple_tree *mt, unsigned long index, unsigned long min);
645void *mt_next(struct maple_tree *mt, unsigned long index, unsigned long max);
646
647/**
648 * mt_for_each - Iterate over each entry starting at index until max.
649 * @__tree: The Maple Tree
650 * @__entry: The current entry
651 * @__index: The index to update to track the location in the tree
652 * @__max: The maximum limit for @index
653 *
654 * Note: Will not return the zero entry.
655 */
656#define mt_for_each(__tree, __entry, __index, __max) \
657 for (__entry = mt_find(__tree, &(__index), __max); \
658 __entry; __entry = mt_find_after(__tree, &(__index), __max))
659
660
661#ifdef CONFIG_DEBUG_MAPLE_TREE
662extern atomic_t maple_tree_tests_run;
663extern atomic_t maple_tree_tests_passed;
664
665void mt_dump(const struct maple_tree *mt);
666void mt_validate(struct maple_tree *mt);
667#define MT_BUG_ON(__tree, __x) do { \
668 atomic_inc(&maple_tree_tests_run); \
669 if (__x) { \
670 pr_info("BUG at %s:%d (%u)\n", \
671 __func__, __LINE__, __x); \
672 mt_dump(__tree); \
673 pr_info("Pass: %u Run:%u\n", \
674 atomic_read(&maple_tree_tests_passed), \
675 atomic_read(&maple_tree_tests_run)); \
676 dump_stack(); \
677 } else { \
678 atomic_inc(&maple_tree_tests_passed); \
679 } \
680} while (0)
681#else
682#define MT_BUG_ON(__tree, __x) BUG_ON(__x)
683#endif /* CONFIG_DEBUG_MAPLE_TREE */
684
685#endif /*_LINUX_MAPLE_TREE_H */
include/linux/memcontrol.h+49−50
@@ -80,29 +80,8 @@ enum mem_cgroup_events_target { · 79 unmodified lines
80 MEM_CGROUP_NTARGETS,80 MEM_CGROUP_NTARGETS,
81};81};
82 82
83struct memcg_vmstats_percpu {83struct memcg_vmstats_percpu;
84 /* Local (CPU and cgroup) page state & events */84struct memcg_vmstats;
85 long state[MEMCG_NR_STAT];
86 unsigned long events[NR_VM_EVENT_ITEMS];
87
88 /* Delta calculation for lockless upward propagation */
89 long state_prev[MEMCG_NR_STAT];
90 unsigned long events_prev[NR_VM_EVENT_ITEMS];
91
92 /* Cgroup1: threshold notifications & softlimit tree updates */
93 unsigned long nr_page_events;
94 unsigned long targets[MEM_CGROUP_NTARGETS];
95};
96
97struct memcg_vmstats {
98 /* Aggregated (CPU and subtree) page state & events */
99 long state[MEMCG_NR_STAT];
100 unsigned long events[NR_VM_EVENT_ITEMS];
101
102 /* Pending child counts during tree propagation */
103 long state_pending[MEMCG_NR_STAT];
104 unsigned long events_pending[NR_VM_EVENT_ITEMS];
105};
106 85
107struct mem_cgroup_reclaim_iter {86struct mem_cgroup_reclaim_iter {
108 struct mem_cgroup *position;87 struct mem_cgroup *position;
@@ -185,15 +164,6 @@ struct mem_cgroup_thresholds { · 76 unmodified lines
185 struct mem_cgroup_threshold_ary *spare;164 struct mem_cgroup_threshold_ary *spare;
186};165};
187 166
188#if defined(CONFIG_SMP)
189struct memcg_padding {
190 char x[0];
191} ____cacheline_internodealigned_in_smp;
192#define MEMCG_PADDING(name) struct memcg_padding name
193#else
194#define MEMCG_PADDING(name)
195#endif
196
197/*167/*
198 * Remember four most recent foreign writebacks with dirty pages in this168 * Remember four most recent foreign writebacks with dirty pages in this
199 * cgroup. Inode sharing is expected to be uncommon and, even if we miss169 * cgroup. Inode sharing is expected to be uncommon and, even if we miss
@@ -304,10 +274,10 @@ struct mem_cgroup { · 104 unmodified lines
304 spinlock_t move_lock;274 spinlock_t move_lock;
305 unsigned long move_lock_flags;275 unsigned long move_lock_flags;
306 276
307 MEMCG_PADDING(_pad1_);277 CACHELINE_PADDING(_pad1_);
308 278
309 /* memory.stat */279 /* memory.stat */
310 struct memcg_vmstats vmstats;280 struct memcg_vmstats *vmstats;
311 281
312 /* memory.events */282 /* memory.events */
313 atomic_long_t memory_events[MEMCG_NR_MEMORY_EVENTS];283 atomic_long_t memory_events[MEMCG_NR_MEMORY_EVENTS];
@@ -326,7 +296,7 @@ struct mem_cgroup { · 12 unmodified lines
326 struct list_head objcg_list;296 struct list_head objcg_list;
327#endif297#endif
328 298
329 MEMCG_PADDING(_pad2_);299 CACHELINE_PADDING(_pad2_);
330 300
331 /*301 /*
332 * set > 0 if pages under this cgroup are moving to other cgroup.302 * set > 0 if pages under this cgroup are moving to other cgroup.
@@ -350,14 +320,20 @@ struct mem_cgroup { · 17 unmodified lines
350 struct deferred_split deferred_split_queue;320 struct deferred_split deferred_split_queue;
351#endif321#endif
352 322
323#ifdef CONFIG_LRU_GEN
324 /* per-memcg mm_struct list */
325 struct lru_gen_mm_list mm_list;
326#endif
327
353 struct mem_cgroup_per_node *nodeinfo[];328 struct mem_cgroup_per_node *nodeinfo[];
354};329};
355 330
356/*331/*
357 * size of first charge trial. "32" comes from vmscan.c's magic value.332 * size of first charge trial.
358 * TODO: maybe necessary to use big numbers in big irons.333 * TODO: maybe necessary to use big numbers in big irons or dynamic based of the
334 * workload.
359 */335 */
360#define MEMCG_CHARGE_BATCH 32U336#define MEMCG_CHARGE_BATCH 64U
361 337
362extern struct mem_cgroup *root_mem_cgroup;338extern struct mem_cgroup *root_mem_cgroup;
363 339
@@ -444,6 +420,7 @@ static inline struct obj_cgroup *__folio_objcg(struct folio *folio) · 80 unmodified lines
444 * - LRU isolation420 * - LRU isolation
445 * - lock_page_memcg()421 * - lock_page_memcg()
446 * - exclusive reference422 * - exclusive reference
423 * - mem_cgroup_trylock_pages()
447 *424 *
448 * For a kmem folio a caller should hold an rcu read lock to protect memcg425 * For a kmem folio a caller should hold an rcu read lock to protect memcg
449 * associated with a kmem folio from being released.426 * associated with a kmem folio from being released.
@@ -505,6 +482,7 @@ static inline struct mem_cgroup *folio_memcg_rcu(struct folio *folio) · 55 unmodified lines
505 * - LRU isolation482 * - LRU isolation
506 * - lock_page_memcg()483 * - lock_page_memcg()
507 * - exclusive reference484 * - exclusive reference
485 * - mem_cgroup_trylock_pages()
508 *486 *
509 * For a kmem page a caller should hold an rcu read lock to protect memcg487 * For a kmem page a caller should hold an rcu read lock to protect memcg
510 * associated with a kmem page from being released.488 * associated with a kmem page from being released.
@@ -689,7 +667,7 @@ static inline int mem_cgroup_charge(struct folio *folio, struct mm_struct *mm, · 178 unmodified lines
689 return __mem_cgroup_charge(folio, mm, gfp);667 return __mem_cgroup_charge(folio, mm, gfp);
690}668}
691 669
692int mem_cgroup_swapin_charge_page(struct page *page, struct mm_struct *mm,670int mem_cgroup_swapin_charge_folio(struct folio *folio, struct mm_struct *mm,
693 gfp_t gfp, swp_entry_t entry);671 gfp_t gfp, swp_entry_t entry);
694void mem_cgroup_swapin_uncharge_swap(swp_entry_t entry);672void mem_cgroup_swapin_uncharge_swap(swp_entry_t entry);
695 673
@@ -959,6 +937,23 @@ void unlock_page_memcg(struct page *page); · 263 unmodified lines
959 937
960void __mod_memcg_state(struct mem_cgroup *memcg, int idx, int val);938void __mod_memcg_state(struct mem_cgroup *memcg, int idx, int val);
961 939
940/* try to stablize folio_memcg() for all the pages in a memcg */
941static inline bool mem_cgroup_trylock_pages(struct mem_cgroup *memcg)
942{
943 rcu_read_lock();
944
945 if (mem_cgroup_disabled() || !atomic_read(&memcg->moving_account))
946 return true;
947
948 rcu_read_unlock();
949 return false;
950}
951
952static inline void mem_cgroup_unlock_pages(void)
953{
954 rcu_read_unlock();
955}
956
962/* idx can be of type enum memcg_stat_item or node_stat_item */957/* idx can be of type enum memcg_stat_item or node_stat_item */
963static inline void mod_memcg_state(struct mem_cgroup *memcg,958static inline void mod_memcg_state(struct mem_cgroup *memcg,
964 int idx, int val)959 int idx, int val)
@@ -985,15 +980,7 @@ static inline void mod_memcg_page_state(struct page *page, · 20 unmodified lines
985 rcu_read_unlock();980 rcu_read_unlock();
986}981}
987 982
988static inline unsigned long memcg_page_state(struct mem_cgroup *memcg, int idx)983unsigned long memcg_page_state(struct mem_cgroup *memcg, int idx);
989{
990 long x = READ_ONCE(memcg->vmstats.state[idx]);
991#ifdef CONFIG_SMP
992 if (x < 0)
993 x = 0;
994#endif
995 return x;
996}
997 984
998static inline unsigned long lruvec_page_state(struct lruvec *lruvec,985static inline unsigned long lruvec_page_state(struct lruvec *lruvec,
999 enum node_stat_item idx)986 enum node_stat_item idx)
@@ -1238,7 +1225,7 @@ static inline int mem_cgroup_charge(struct folio *folio, · 238 unmodified lines
1238 return 0;1225 return 0;
1239}1226}
1240 1227
1241static inline int mem_cgroup_swapin_charge_page(struct page *page,1228static inline int mem_cgroup_swapin_charge_folio(struct folio *folio,
1242 struct mm_struct *mm, gfp_t gfp, swp_entry_t entry)1229 struct mm_struct *mm, gfp_t gfp, swp_entry_t entry)
1243{1230{
1244 return 0;1231 return 0;
@@ -1433,6 +1420,18 @@ static inline void folio_memcg_unlock(struct folio *folio) · 188 unmodified lines
1433{1420{
1434}1421}
1435 1422
1423static inline bool mem_cgroup_trylock_pages(struct mem_cgroup *memcg)
1424{
1425 /* to match folio_memcg_rcu() */
1426 rcu_read_lock();
1427 return true;
1428}
1429
1430static inline void mem_cgroup_unlock_pages(void)
1431{
1432 rcu_read_unlock();
1433}
1434
1436static inline void mem_cgroup_handle_over_high(void)1435static inline void mem_cgroup_handle_over_high(void)
1437{1436{
1438}1437}
@@ -1779,7 +1778,7 @@ static inline void count_objcg_event(struct obj_cgroup *objcg, · 340 unmodified lines
1779{1778{
1780 struct mem_cgroup *memcg;1779 struct mem_cgroup *memcg;
1781 1780
1782 if (mem_cgroup_kmem_disabled())1781 if (!memcg_kmem_enabled())
1783 return;1782 return;
1784 1783
1785 rcu_read_lock();1784 rcu_read_lock();
include/linux/memory-tiers.h+102−0
@@ -0,0 +1,102 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _LINUX_MEMORY_TIERS_H
3#define _LINUX_MEMORY_TIERS_H
4
5#include <linux/types.h>
6#include <linux/nodemask.h>
7#include <linux/kref.h>
8#include <linux/mmzone.h>
9/*
10 * Each tier cover a abstrace distance chunk size of 128
11 */
12#define MEMTIER_CHUNK_BITS 7
13#define MEMTIER_CHUNK_SIZE (1 << MEMTIER_CHUNK_BITS)
14/*
15 * Smaller abstract distance values imply faster (higher) memory tiers. Offset
16 * the DRAM adistance so that we can accommodate devices with a slightly lower
17 * adistance value (slightly faster) than default DRAM adistance to be part of
18 * the same memory tier.
19 */
20#define MEMTIER_ADISTANCE_DRAM ((4 * MEMTIER_CHUNK_SIZE) + (MEMTIER_CHUNK_SIZE >> 1))
21#define MEMTIER_HOTPLUG_PRIO 100
22
23struct memory_tier;
24struct memory_dev_type {
25 /* list of memory types that are part of same tier as this type */
26 struct list_head tier_sibiling;
27 /* abstract distance for this specific memory type */
28 int adistance;
29 /* Nodes of same abstract distance */
30 nodemask_t nodes;
31 struct kref kref;
32};
33
34#ifdef CONFIG_NUMA
35extern bool numa_demotion_enabled;
36struct memory_dev_type *alloc_memory_type(int adistance);
37void destroy_memory_type(struct memory_dev_type *memtype);
38void init_node_memory_type(int node, struct memory_dev_type *default_type);
39void clear_node_memory_type(int node, struct memory_dev_type *memtype);
40#ifdef CONFIG_MIGRATION
41int next_demotion_node(int node);
42void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t *targets);
43bool node_is_toptier(int node);
44#else
45static inline int next_demotion_node(int node)
46{
47 return NUMA_NO_NODE;
48}
49
50static inline void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t *targets)
51{
52 *targets = NODE_MASK_NONE;
53}
54
55static inline bool node_is_toptier(int node)
56{
57 return true;
58}
59#endif
60
61#else
62
63#define numa_demotion_enabled false
64/*
65 * CONFIG_NUMA implementation returns non NULL error.
66 */
67static inline struct memory_dev_type *alloc_memory_type(int adistance)
68{
69 return NULL;
70}
71
72static inline void destroy_memory_type(struct memory_dev_type *memtype)
73{
74
75}
76
77static inline void init_node_memory_type(int node, struct memory_dev_type *default_type)
78{
79
80}
81
82static inline void clear_node_memory_type(int node, struct memory_dev_type *memtype)
83{
84
85}
86
87static inline int next_demotion_node(int node)
88{
89 return NUMA_NO_NODE;
90}
91
92static inline void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t *targets)
93{
94 *targets = NODE_MASK_NONE;
95}
96
97static inline bool node_is_toptier(int node)
98{
99 return true;
100}
101#endif /* CONFIG_NUMA */
102#endif /* _LINUX_MEMORY_TIERS_H */
include/linux/memory_hotplug.h+20−10
@@ -11,7 +11,6 @@ struct page; · 10 unmodified lines
11struct zone;11struct zone;
12struct pglist_data;12struct pglist_data;
13struct mem_section;13struct mem_section;
14struct memory_block;
15struct memory_group;14struct memory_group;
16struct resource;15struct resource;
17struct vmem_altmap;16struct vmem_altmap;
@@ -44,11 +43,6 @@ extern void arch_refresh_nodedata(int nid, pg_data_t *pgdat); · 26 unmodified lines
44({ \43({ \
45 memblock_alloc(sizeof(*pgdat), SMP_CACHE_BYTES); \44 memblock_alloc(sizeof(*pgdat), SMP_CACHE_BYTES); \
46})45})
47/*
48 * This definition is just for error path in node hotadd.
49 * For node hotremove, we have to replace this.
50 */
51#define generic_free_nodedata(pgdat) kfree(pgdat)
52 46
53extern pg_data_t *node_data[];47extern pg_data_t *node_data[];
54static inline void arch_refresh_nodedata(int nid, pg_data_t *pgdat)48static inline void arch_refresh_nodedata(int nid, pg_data_t *pgdat)
@@ -64,9 +58,6 @@ static inline pg_data_t *generic_alloc_nodedata(int nid) · 9 unmodified lines
64 BUG();58 BUG();
65 return NULL;59 return NULL;
66}60}
67static inline void generic_free_nodedata(pg_data_t *pgdat)
68{
69}
70static inline void arch_refresh_nodedata(int nid, pg_data_t *pgdat)61static inline void arch_refresh_nodedata(int nid, pg_data_t *pgdat)
71{62{
72}63}
@@ -216,6 +207,22 @@ void put_online_mems(void); · 143 unmodified lines
216void mem_hotplug_begin(void);207void mem_hotplug_begin(void);
217void mem_hotplug_done(void);208void mem_hotplug_done(void);
218 209
210/* See kswapd_is_running() */
211static inline void pgdat_kswapd_lock(pg_data_t *pgdat)
212{
213 mutex_lock(&pgdat->kswapd_lock);
214}
215
216static inline void pgdat_kswapd_unlock(pg_data_t *pgdat)
217{
218 mutex_unlock(&pgdat->kswapd_lock);
219}
220
221static inline void pgdat_kswapd_lock_init(pg_data_t *pgdat)
222{
223 mutex_init(&pgdat->kswapd_lock);
224}
225
219#else /* ! CONFIG_MEMORY_HOTPLUG */226#else /* ! CONFIG_MEMORY_HOTPLUG */
220#define pfn_to_online_page(pfn) \227#define pfn_to_online_page(pfn) \
221({ \228({ \
@@ -252,6 +259,10 @@ static inline bool movable_node_is_enabled(void) · 30 unmodified lines
252{259{
253 return false;260 return false;
254}261}
262
263static inline void pgdat_kswapd_lock(pg_data_t *pgdat) {}
264static inline void pgdat_kswapd_unlock(pg_data_t *pgdat) {}
265static inline void pgdat_kswapd_lock_init(pg_data_t *pgdat) {}
255#endif /* ! CONFIG_MEMORY_HOTPLUG */266#endif /* ! CONFIG_MEMORY_HOTPLUG */
256 267
257/*268/*
@@ -333,7 +344,6 @@ extern void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn, · 75 unmodified lines
333extern void remove_pfn_range_from_zone(struct zone *zone,344extern void remove_pfn_range_from_zone(struct zone *zone,
334 unsigned long start_pfn,345 unsigned long start_pfn,
335 unsigned long nr_pages);346 unsigned long nr_pages);
336extern bool is_memblock_offlined(struct memory_block *mem);
337extern int sparse_add_section(int nid, unsigned long pfn,347extern int sparse_add_section(int nid, unsigned long pfn,
338 unsigned long nr_pages, struct vmem_altmap *altmap,348 unsigned long nr_pages, struct vmem_altmap *altmap,
339 struct dev_pagemap *pgmap);349 struct dev_pagemap *pgmap);
include/linux/mempolicy.h+1−12
@@ -151,13 +151,6 @@ extern bool mempolicy_in_oom_domain(struct task_struct *tsk, · 150 unmodified lines
151 const nodemask_t *mask);151 const nodemask_t *mask);
152extern nodemask_t *policy_nodemask(gfp_t gfp, struct mempolicy *policy);152extern nodemask_t *policy_nodemask(gfp_t gfp, struct mempolicy *policy);
153 153
154static inline nodemask_t *policy_nodemask_current(gfp_t gfp)
155{
156 struct mempolicy *mpol = get_task_policy(current);
157
158 return policy_nodemask(gfp, mpol);
159}
160
161extern unsigned int mempolicy_slab_node(void);154extern unsigned int mempolicy_slab_node(void);
162 155
163extern enum zone_type policy_zone;156extern enum zone_type policy_zone;
@@ -189,6 +182,7 @@ static inline bool mpol_is_preferred_many(struct mempolicy *pol) · 25 unmodified lines
189 return (pol->mode == MPOL_PREFERRED_MANY);182 return (pol->mode == MPOL_PREFERRED_MANY);
190}183}
191 184
185extern bool apply_policy_zone(struct mempolicy *policy, enum zone_type zone);
192 186
193#else187#else
194 188
@@ -294,11 +288,6 @@ static inline void mpol_put_task_policy(struct task_struct *task) · 99 unmodified lines
294{288{
295}289}
296 290
297static inline nodemask_t *policy_nodemask_current(gfp_t gfp)
298{
299 return NULL;
300}
301
302static inline bool mpol_is_preferred_many(struct mempolicy *pol)291static inline bool mpol_is_preferred_many(struct mempolicy *pol)
303{292{
304 return false;293 return false;
include/linux/migrate.h+0−15
@@ -100,21 +100,6 @@ static inline int migrate_huge_page_move_mapping(struct address_space *mapping, · 99 unmodified lines
100 100
101#endif /* CONFIG_MIGRATION */101#endif /* CONFIG_MIGRATION */
102 102
103#if defined(CONFIG_MIGRATION) && defined(CONFIG_NUMA)
104extern void set_migration_target_nodes(void);
105extern void migrate_on_reclaim_init(void);
106extern bool numa_demotion_enabled;
107extern int next_demotion_node(int node);
108#else
109static inline void set_migration_target_nodes(void) {}
110static inline void migrate_on_reclaim_init(void) {}
111static inline int next_demotion_node(int node)
112{
113 return NUMA_NO_NODE;
114}
115#define numa_demotion_enabled false
116#endif
117
118#ifdef CONFIG_COMPACTION103#ifdef CONFIG_COMPACTION
119bool PageMovable(struct page *page);104bool PageMovable(struct page *page);
120void __SetPageMovable(struct page *page, const struct movable_operations *ops);105void __SetPageMovable(struct page *page, const struct movable_operations *ops);
include/linux/mm.h+121−40
@@ -661,6 +661,38 @@ static inline bool vma_is_accessible(struct vm_area_struct *vma) · 660 unmodified lines
661 return vma->vm_flags & VM_ACCESS_FLAGS;661 return vma->vm_flags & VM_ACCESS_FLAGS;
662}662}
663 663
664static inline
665struct vm_area_struct *vma_find(struct vma_iterator *vmi, unsigned long max)
666{
667 return mas_find(&vmi->mas, max);
668}
669
670static inline struct vm_area_struct *vma_next(struct vma_iterator *vmi)
671{
672 /*
673 * Uses vma_find() to get the first VMA when the iterator starts.
674 * Calling mas_next() could skip the first entry.
675 */
676 return vma_find(vmi, ULONG_MAX);
677}
678
679static inline struct vm_area_struct *vma_prev(struct vma_iterator *vmi)
680{
681 return mas_prev(&vmi->mas, 0);
682}
683
684static inline unsigned long vma_iter_addr(struct vma_iterator *vmi)
685{
686 return vmi->mas.index;
687}
688
689#define for_each_vma(__vmi, __vma) \
690 while (((__vma) = vma_next(&(__vmi))) != NULL)
691
692/* The MM code likes to work with exclusive end addresses */
693#define for_each_vma_range(__vmi, __vma, __end) \
694 while (((__vma) = vma_find(&(__vmi), (__end) - 1)) != NULL)
695
664#ifdef CONFIG_SHMEM696#ifdef CONFIG_SHMEM
665/*697/*
666 * The vma_is_shmem is not inline because it is used only by slow698 * The vma_is_shmem is not inline because it is used only by slow
@@ -697,7 +729,9 @@ static inline unsigned int compound_order(struct page *page) · 30 unmodified lines
697 */729 */
698static inline unsigned int folio_order(struct folio *folio)730static inline unsigned int folio_order(struct folio *folio)
699{731{
700 return compound_order(&folio->page);732 if (!folio_test_large(folio))
733 return 0;
734 return folio->_folio_order;
701}735}
702 736
703#include <linux/huge_mm.h>737#include <linux/huge_mm.h>
@@ -1255,6 +1289,18 @@ static inline int folio_nid(const struct folio *folio) · 551 unmodified lines
1255}1289}
1256 1290
1257#ifdef CONFIG_NUMA_BALANCING1291#ifdef CONFIG_NUMA_BALANCING
1292/* page access time bits needs to hold at least 4 seconds */
1293#define PAGE_ACCESS_TIME_MIN_BITS 12
1294#if LAST_CPUPID_SHIFT < PAGE_ACCESS_TIME_MIN_BITS
1295#define PAGE_ACCESS_TIME_BUCKETS \
1296 (PAGE_ACCESS_TIME_MIN_BITS - LAST_CPUPID_SHIFT)
1297#else
1298#define PAGE_ACCESS_TIME_BUCKETS 0
1299#endif
1300
1301#define PAGE_ACCESS_TIME_MASK \
1302 (LAST_CPUPID_MASK << PAGE_ACCESS_TIME_BUCKETS)
1303
1258static inline int cpu_pid_to_cpupid(int cpu, int pid)1304static inline int cpu_pid_to_cpupid(int cpu, int pid)
1259{1305{
1260 return ((cpu & LAST__CPU_MASK) << LAST__PID_SHIFT) | (pid & LAST__PID_MASK);1306 return ((cpu & LAST__CPU_MASK) << LAST__PID_SHIFT) | (pid & LAST__PID_MASK);
@@ -1318,12 +1364,25 @@ static inline void page_cpupid_reset_last(struct page *page) · 57 unmodified lines
1318 page->flags |= LAST_CPUPID_MASK << LAST_CPUPID_PGSHIFT;1364 page->flags |= LAST_CPUPID_MASK << LAST_CPUPID_PGSHIFT;
1319}1365}
1320#endif /* LAST_CPUPID_NOT_IN_PAGE_FLAGS */1366#endif /* LAST_CPUPID_NOT_IN_PAGE_FLAGS */
1367
1368static inline int xchg_page_access_time(struct page *page, int time)
1369{
1370 int last_time;
1371
1372 last_time = page_cpupid_xchg_last(page, time >> PAGE_ACCESS_TIME_BUCKETS);
1373 return last_time << PAGE_ACCESS_TIME_BUCKETS;
1374}
1321#else /* !CONFIG_NUMA_BALANCING */1375#else /* !CONFIG_NUMA_BALANCING */
1322static inline int page_cpupid_xchg_last(struct page *page, int cpupid)1376static inline int page_cpupid_xchg_last(struct page *page, int cpupid)
1323{1377{
1324 return page_to_nid(page); /* XXX */1378 return page_to_nid(page); /* XXX */
1325}1379}
1326 1380
1381static inline int xchg_page_access_time(struct page *page, int time)
1382{
1383 return 0;
1384}
1385
1327static inline int page_cpupid_last(struct page *page)1386static inline int page_cpupid_last(struct page *page)
1328{1387{
1329 return page_to_nid(page); /* XXX */1388 return page_to_nid(page); /* XXX */
@@ -1465,6 +1524,11 @@ static inline unsigned long folio_pfn(struct folio *folio) · 135 unmodified lines
1465 return page_to_pfn(&folio->page);1524 return page_to_pfn(&folio->page);
1466}1525}
1467 1526
1527static inline struct folio *pfn_folio(unsigned long pfn)
1528{
1529 return page_folio(pfn_to_page(pfn));
1530}
1531
1468static inline atomic_t *folio_pincount_ptr(struct folio *folio)1532static inline atomic_t *folio_pincount_ptr(struct folio *folio)
1469{1533{
1470 return &folio_page(folio, 1)->compound_pincount;1534 return &folio_page(folio, 1)->compound_pincount;
@@ -1597,7 +1661,13 @@ static inline void set_page_links(struct page *page, enum zone_type zone, · 126 unmodified lines
1597 */1661 */
1598static inline long folio_nr_pages(struct folio *folio)1662static inline long folio_nr_pages(struct folio *folio)
1599{1663{
1600 return compound_nr(&folio->page);1664 if (!folio_test_large(folio))
1665 return 1;
1666#ifdef CONFIG_64BIT
1667 return folio->_folio_nr_pages;
1668#else
1669 return 1L << folio->_folio_order;
1670#endif
1601}1671}
1602 1672
1603/**1673/**
@@ -1776,7 +1846,11 @@ extern void pagefault_out_of_memory(void); · 172 unmodified lines
1776 */1846 */
1777#define SHOW_MEM_FILTER_NODES (0x0001u) /* disallowed nodes */1847#define SHOW_MEM_FILTER_NODES (0x0001u) /* disallowed nodes */
1778 1848
1779extern void show_free_areas(unsigned int flags, nodemask_t *nodemask);1849extern void __show_free_areas(unsigned int flags, nodemask_t *nodemask, int max_zone_idx);
1850static void __maybe_unused show_free_areas(unsigned int flags, nodemask_t *nodemask)
1851{
1852 __show_free_areas(flags, nodemask, MAX_NR_ZONES - 1);
1853}
1780 1854
1781#ifdef CONFIG_MMU1855#ifdef CONFIG_MMU
1782extern bool can_do_mlock(void);1856extern bool can_do_mlock(void);
@@ -1795,8 +1869,9 @@ void zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, · 12 unmodified lines
1795 unsigned long size);1869 unsigned long size);
1796void zap_page_range(struct vm_area_struct *vma, unsigned long address,1870void zap_page_range(struct vm_area_struct *vma, unsigned long address,
1797 unsigned long size);1871 unsigned long size);
1798void unmap_vmas(struct mmu_gather *tlb, struct vm_area_struct *start_vma,1872void unmap_vmas(struct mmu_gather *tlb, struct maple_tree *mt,
1799 unsigned long start, unsigned long end);1873 struct vm_area_struct *start_vma, unsigned long start,
1874 unsigned long end);
1800 1875
1801struct mmu_notifier_range;1876struct mmu_notifier_range;
1802 1877
@@ -2495,7 +2570,6 @@ extern unsigned long absent_pages_in_range(unsigned long start_pfn, · 692 unmodified lines
2495 unsigned long end_pfn);2570 unsigned long end_pfn);
2496extern void get_pfn_range_for_nid(unsigned int nid,2571extern void get_pfn_range_for_nid(unsigned int nid,
2497 unsigned long *start_pfn, unsigned long *end_pfn);2572 unsigned long *start_pfn, unsigned long *end_pfn);
2498extern unsigned long find_min_pfn_with_active_regions(void);
2499 2573
2500#ifndef CONFIG_NUMA2574#ifndef CONFIG_NUMA
2501static inline int early_pfn_to_nid(unsigned long pfn)2575static inline int early_pfn_to_nid(unsigned long pfn)
@@ -2516,7 +2590,12 @@ extern void calculate_min_free_kbytes(void); · 14 unmodified lines
2516extern int __meminit init_per_zone_wmark_min(void);2590extern int __meminit init_per_zone_wmark_min(void);
2517extern void mem_init(void);2591extern void mem_init(void);
2518extern void __init mmap_init(void);2592extern void __init mmap_init(void);
2519extern void show_mem(unsigned int flags, nodemask_t *nodemask);2593
2594extern void __show_mem(unsigned int flags, nodemask_t *nodemask, int max_zone_idx);
2595static inline void show_mem(unsigned int flags, nodemask_t *nodemask)
2596{
2597 __show_mem(flags, nodemask, MAX_NR_ZONES - 1);
2598}
2520extern long si_mem_available(void);2599extern long si_mem_available(void);
2521extern void si_meminfo(struct sysinfo * val);2600extern void si_meminfo(struct sysinfo * val);
2522extern void si_meminfo_node(struct sysinfo *val, int nid);2601extern void si_meminfo_node(struct sysinfo *val, int nid);
@@ -2593,14 +2672,15 @@ extern int __split_vma(struct mm_struct *, struct vm_area_struct *, · 70 unmodified lines
2593extern int split_vma(struct mm_struct *, struct vm_area_struct *,2672extern int split_vma(struct mm_struct *, struct vm_area_struct *,
2594 unsigned long addr, int new_below);2673 unsigned long addr, int new_below);
2595extern int insert_vm_struct(struct mm_struct *, struct vm_area_struct *);2674extern int insert_vm_struct(struct mm_struct *, struct vm_area_struct *);
2596extern void __vma_link_rb(struct mm_struct *, struct vm_area_struct *,
2597 struct rb_node **, struct rb_node *);
2598extern void unlink_file_vma(struct vm_area_struct *);2675extern void unlink_file_vma(struct vm_area_struct *);
2599extern struct vm_area_struct *copy_vma(struct vm_area_struct **,2676extern struct vm_area_struct *copy_vma(struct vm_area_struct **,
2600 unsigned long addr, unsigned long len, pgoff_t pgoff,2677 unsigned long addr, unsigned long len, pgoff_t pgoff,
2601 bool *need_rmap_locks);2678 bool *need_rmap_locks);
2602extern void exit_mmap(struct mm_struct *);2679extern void exit_mmap(struct mm_struct *);
2603 2680
2681void vma_mas_store(struct vm_area_struct *vma, struct ma_state *mas);
2682void vma_mas_remove(struct vm_area_struct *vma, struct ma_state *mas);
2683
2604static inline int check_data_rlimit(unsigned long rlim,2684static inline int check_data_rlimit(unsigned long rlim,
2605 unsigned long new,2685 unsigned long new,
2606 unsigned long start,2686 unsigned long start,
@@ -2648,8 +2728,9 @@ extern unsigned long mmap_region(struct file *file, unsigned long addr, · 41 unmodified lines
2648extern unsigned long do_mmap(struct file *file, unsigned long addr,2728extern unsigned long do_mmap(struct file *file, unsigned long addr,
2649 unsigned long len, unsigned long prot, unsigned long flags,2729 unsigned long len, unsigned long prot, unsigned long flags,
2650 unsigned long pgoff, unsigned long *populate, struct list_head *uf);2730 unsigned long pgoff, unsigned long *populate, struct list_head *uf);
2651extern int __do_munmap(struct mm_struct *, unsigned long, size_t,2731extern int do_mas_munmap(struct ma_state *mas, struct mm_struct *mm,
2652 struct list_head *uf, bool downgrade);2732 unsigned long start, size_t len, struct list_head *uf,
2733 bool downgrade);
2653extern int do_munmap(struct mm_struct *, unsigned long, size_t,2734extern int do_munmap(struct mm_struct *, unsigned long, size_t,
2654 struct list_head *uf);2735 struct list_head *uf);
2655extern int do_madvise(struct mm_struct *mm, unsigned long start, size_t len_in, int behavior);2736extern int do_madvise(struct mm_struct *mm, unsigned long start, size_t len_in, int behavior);
@@ -2716,26 +2797,12 @@ extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long add · 60 unmodified lines
2716extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,2797extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
2717 struct vm_area_struct **pprev);2798 struct vm_area_struct **pprev);
2718 2799
2719/**2800/*
2720 * find_vma_intersection() - Look up the first VMA which intersects the interval2801 * Look up the first VMA which intersects the interval [start_addr, end_addr)
2721 * @mm: The process address space.2802 * NULL if none. Assume start_addr < end_addr.
2722 * @start_addr: The inclusive start user address.
2723 * @end_addr: The exclusive end user address.
2724 *
2725 * Returns: The first VMA within the provided range, %NULL otherwise. Assumes
2726 * start_addr < end_addr.
2727 */2803 */
2728static inline
2729struct vm_area_struct *find_vma_intersection(struct mm_struct *mm,2804struct vm_area_struct *find_vma_intersection(struct mm_struct *mm,
2730 unsigned long start_addr,2805 unsigned long start_addr, unsigned long end_addr);
2731 unsigned long end_addr)
2732{
2733 struct vm_area_struct *vma = find_vma(mm, start_addr);
2734
2735 if (vma && end_addr <= vma->vm_start)
2736 vma = NULL;
2737 return vma;
2738}
2739 2806
2740/**2807/**
2741 * vma_lookup() - Find a VMA at a specific address2808 * vma_lookup() - Find a VMA at a specific address
@@ -2747,12 +2814,7 @@ struct vm_area_struct *find_vma_intersection(struct mm_struct *mm, · 5 unmodified lines
2747static inline2814static inline
2748struct vm_area_struct *vma_lookup(struct mm_struct *mm, unsigned long addr)2815struct vm_area_struct *vma_lookup(struct mm_struct *mm, unsigned long addr)
2749{2816{
2750 struct vm_area_struct *vma = find_vma(mm, addr);2817 return mtree_load(&mm->mm_mt, addr);
2751
2752 if (vma && addr < vma->vm_start)
2753 vma = NULL;
2754
2755 return vma;
2756}2818}
2757 2819
2758static inline unsigned long vm_start_gap(struct vm_area_struct *vma)2820static inline unsigned long vm_start_gap(struct vm_area_struct *vma)
@@ -2788,7 +2850,7 @@ static inline unsigned long vma_pages(struct vm_area_struct *vma) · 29 unmodified lines
2788static inline struct vm_area_struct *find_exact_vma(struct mm_struct *mm,2850static inline struct vm_area_struct *find_exact_vma(struct mm_struct *mm,
2789 unsigned long vm_start, unsigned long vm_end)2851 unsigned long vm_start, unsigned long vm_end)
2790{2852{
2791 struct vm_area_struct *vma = find_vma(mm, vm_start);2853 struct vm_area_struct *vma = vma_lookup(mm, vm_start);
2792 2854
2793 if (vma && (vma->vm_start != vm_start || vma->vm_end != vm_end))2855 if (vma && (vma->vm_start != vm_start || vma->vm_end != vm_end))
2794 vma = NULL;2856 vma = NULL;
@@ -2888,7 +2950,6 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, · 93 unmodified lines
2888 * and return without waiting upon it */2950 * and return without waiting upon it */
2889#define FOLL_NOFAULT 0x80 /* do not fault in pages */2951#define FOLL_NOFAULT 0x80 /* do not fault in pages */
2890#define FOLL_HWPOISON 0x100 /* check page is hwpoisoned */2952#define FOLL_HWPOISON 0x100 /* check page is hwpoisoned */
2891#define FOLL_NUMA 0x200 /* force NUMA hinting page fault */
2892#define FOLL_MIGRATION 0x400 /* wait for page to replace migration entry */2953#define FOLL_MIGRATION 0x400 /* wait for page to replace migration entry */
2893#define FOLL_TRIED 0x800 /* a retry, previous pass started an IO */2954#define FOLL_TRIED 0x800 /* a retry, previous pass started an IO */
2894#define FOLL_REMOTE 0x2000 /* we are working on non-current tsk/mm */2955#define FOLL_REMOTE 0x2000 /* we are working on non-current tsk/mm */
@@ -2975,8 +3036,8 @@ static inline int vm_fault_to_errno(vm_fault_t vm_fault, int foll_flags) · 80 unmodified lines
2975 * PageAnonExclusive() has to protect against concurrent GUP:3036 * PageAnonExclusive() has to protect against concurrent GUP:
2976 * * Ordinary GUP: Using the PT lock3037 * * Ordinary GUP: Using the PT lock
2977 * * GUP-fast and fork(): mm->write_protect_seq3038 * * GUP-fast and fork(): mm->write_protect_seq
2978 * * GUP-fast and KSM or temporary unmapping (swap, migration):3039 * * GUP-fast and KSM or temporary unmapping (swap, migration): see
2979 * clear/invalidate+flush of the page table entry3040 * page_try_share_anon_rmap()
2980 *3041 *
2981 * Must be called with the (sub)page that's actually referenced via the3042 * Must be called with the (sub)page that's actually referenced via the
2982 * page table entry, which might not necessarily be the head page for a3043 * page table entry, which might not necessarily be the head page for a
@@ -2997,6 +3058,11 @@ static inline bool gup_must_unshare(unsigned int flags, struct page *page) · 14 unmodified lines
2997 */3058 */
2998 if (!PageAnon(page))3059 if (!PageAnon(page))
2999 return false;3060 return false;
3061
3062 /* Paired with a memory barrier in page_try_share_anon_rmap(). */
3063 if (IS_ENABLED(CONFIG_HAVE_FAST_GUP))
3064 smp_rmb();
3065
3000 /*3066 /*
3001 * Note that PageKsm() pages cannot be exclusive, and consequently,3067 * Note that PageKsm() pages cannot be exclusive, and consequently,
3002 * cannot get pinned.3068 * cannot get pinned.
@@ -3004,6 +3070,21 @@ static inline bool gup_must_unshare(unsigned int flags, struct page *page) · 1 unmodified line
3004 return !PageAnonExclusive(page);3070 return !PageAnonExclusive(page);
3005}3071}
3006 3072
3073/*
3074 * Indicates whether GUP can follow a PROT_NONE mapped page, or whether
3075 * a (NUMA hinting) fault is required.
3076 */
3077static inline bool gup_can_follow_protnone(unsigned int flags)
3078{
3079 /*
3080 * FOLL_FORCE has to be able to make progress even if the VMA is
3081 * inaccessible. Further, FOLL_FORCE access usually does not represent
3082 * application behaviour and we should avoid triggering NUMA hinting
3083 * faults.
3084 */
3085 return flags & FOLL_FORCE;
3086}
3087
3007typedef int (*pte_fn_t)(pte_t *pte, unsigned long addr, void *data);3088typedef int (*pte_fn_t)(pte_t *pte, unsigned long addr, void *data);
3008extern int apply_to_page_range(struct mm_struct *mm, unsigned long address,3089extern int apply_to_page_range(struct mm_struct *mm, unsigned long address,
3009 unsigned long size, pte_fn_t fn, void *data);3090 unsigned long size, pte_fn_t fn, void *data);
@@ -3011,7 +3092,7 @@ extern int apply_to_existing_page_range(struct mm_struct *mm, · 1 unmodified line
3011 unsigned long address, unsigned long size,3092 unsigned long address, unsigned long size,
3012 pte_fn_t fn, void *data);3093 pte_fn_t fn, void *data);
3013 3094
3014extern void init_mem_debugging_and_hardening(void);3095extern void __init init_mem_debugging_and_hardening(void);
3015#ifdef CONFIG_PAGE_POISONING3096#ifdef CONFIG_PAGE_POISONING
3016extern void __kernel_poison_pages(struct page *page, int numpages);3097extern void __kernel_poison_pages(struct page *page, int numpages);
3017extern void __kernel_unpoison_pages(struct page *page, int numpages);3098extern void __kernel_unpoison_pages(struct page *page, int numpages);
include/linux/mm_inline.h+230−12
@@ -34,15 +34,25 @@ static inline int page_is_file_lru(struct page *page) · 33 unmodified lines
34 return folio_is_file_lru(page_folio(page));34 return folio_is_file_lru(page_folio(page));
35}35}
36 36
37static __always_inline void update_lru_size(struct lruvec *lruvec,37static __always_inline void __update_lru_size(struct lruvec *lruvec,
38 enum lru_list lru, enum zone_type zid,38 enum lru_list lru, enum zone_type zid,
39 long nr_pages)39 long nr_pages)
40{40{
41 struct pglist_data *pgdat = lruvec_pgdat(lruvec);41 struct pglist_data *pgdat = lruvec_pgdat(lruvec);
42 42
43 lockdep_assert_held(&lruvec->lru_lock);
44 WARN_ON_ONCE(nr_pages != (int)nr_pages);
45
43 __mod_lruvec_state(lruvec, NR_LRU_BASE + lru, nr_pages);46 __mod_lruvec_state(lruvec, NR_LRU_BASE + lru, nr_pages);
44 __mod_zone_page_state(&pgdat->node_zones[zid],47 __mod_zone_page_state(&pgdat->node_zones[zid],
45 NR_ZONE_LRU_BASE + lru, nr_pages);48 NR_ZONE_LRU_BASE + lru, nr_pages);
49}
50
51static __always_inline void update_lru_size(struct lruvec *lruvec,
52 enum lru_list lru, enum zone_type zid,
53 long nr_pages)
54{
55 __update_lru_size(lruvec, lru, zid, nr_pages);
46#ifdef CONFIG_MEMCG56#ifdef CONFIG_MEMCG
47 mem_cgroup_update_lru_size(lruvec, lru, zid, nr_pages);57 mem_cgroup_update_lru_size(lruvec, lru, zid, nr_pages);
48#endif58#endif
@@ -66,11 +76,6 @@ static __always_inline void __folio_clear_lru_flags(struct folio *folio) · 17 unmodified lines
66 __folio_clear_unevictable(folio);76 __folio_clear_unevictable(folio);
67}77}
68 78
69static __always_inline void __clear_page_lru_flags(struct page *page)
70{
71 __folio_clear_lru_flags(page_folio(page));
72}
73
74/**79/**
75 * folio_lru_list - Which LRU list should a folio be on?80 * folio_lru_list - Which LRU list should a folio be on?
76 * @folio: The folio to test.81 * @folio: The folio to test.
@@ -94,11 +99,224 @@ static __always_inline enum lru_list folio_lru_list(struct folio *folio) · 17 unmodified lines
94 return lru;99 return lru;
95}100}
96 101
102#ifdef CONFIG_LRU_GEN
103
104#ifdef CONFIG_LRU_GEN_ENABLED
105static inline bool lru_gen_enabled(void)
106{
107 DECLARE_STATIC_KEY_TRUE(lru_gen_caps[NR_LRU_GEN_CAPS]);
108
109 return static_branch_likely(&lru_gen_caps[LRU_GEN_CORE]);
110}
111#else
112static inline bool lru_gen_enabled(void)
113{
114 DECLARE_STATIC_KEY_FALSE(lru_gen_caps[NR_LRU_GEN_CAPS]);
115
116 return static_branch_unlikely(&lru_gen_caps[LRU_GEN_CORE]);
117}
118#endif
119
120static inline bool lru_gen_in_fault(void)
121{
122 return current->in_lru_fault;
123}
124
125static inline int lru_gen_from_seq(unsigned long seq)
126{
127 return seq % MAX_NR_GENS;
128}
129
130static inline int lru_hist_from_seq(unsigned long seq)
131{
132 return seq % NR_HIST_GENS;
133}
134
135static inline int lru_tier_from_refs(int refs)
136{
137 VM_WARN_ON_ONCE(refs > BIT(LRU_REFS_WIDTH));
138
139 /* see the comment in folio_lru_refs() */
140 return order_base_2(refs + 1);
141}
142
143static inline int folio_lru_refs(struct folio *folio)
144{
145 unsigned long flags = READ_ONCE(folio->flags);
146 bool workingset = flags & BIT(PG_workingset);
147
148 /*
149 * Return the number of accesses beyond PG_referenced, i.e., N-1 if the
150 * total number of accesses is N>1, since N=0,1 both map to the first
151 * tier. lru_tier_from_refs() will account for this off-by-one. Also see
152 * the comment on MAX_NR_TIERS.
153 */
154 return ((flags & LRU_REFS_MASK) >> LRU_REFS_PGOFF) + workingset;
155}
156
157static inline int folio_lru_gen(struct folio *folio)
158{
159 unsigned long flags = READ_ONCE(folio->flags);
160
161 return ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
162}
163
164static inline bool lru_gen_is_active(struct lruvec *lruvec, int gen)
165{
166 unsigned long max_seq = lruvec->lrugen.max_seq;
167
168 VM_WARN_ON_ONCE(gen >= MAX_NR_GENS);
169
170 /* see the comment on MIN_NR_GENS */
171 return gen == lru_gen_from_seq(max_seq) || gen == lru_gen_from_seq(max_seq - 1);
172}
173
174static inline void lru_gen_update_size(struct lruvec *lruvec, struct folio *folio,
175 int old_gen, int new_gen)
176{
177 int type = folio_is_file_lru(folio);
178 int zone = folio_zonenum(folio);
179 int delta = folio_nr_pages(folio);
180 enum lru_list lru = type * LRU_INACTIVE_FILE;
181 struct lru_gen_struct *lrugen = &lruvec->lrugen;
182
183 VM_WARN_ON_ONCE(old_gen != -1 && old_gen >= MAX_NR_GENS);
184 VM_WARN_ON_ONCE(new_gen != -1 && new_gen >= MAX_NR_GENS);
185 VM_WARN_ON_ONCE(old_gen == -1 && new_gen == -1);
186
187 if (old_gen >= 0)
188 WRITE_ONCE(lrugen->nr_pages[old_gen][type][zone],
189 lrugen->nr_pages[old_gen][type][zone] - delta);
190 if (new_gen >= 0)
191 WRITE_ONCE(lrugen->nr_pages[new_gen][type][zone],
192 lrugen->nr_pages[new_gen][type][zone] + delta);
193
194 /* addition */
195 if (old_gen < 0) {
196 if (lru_gen_is_active(lruvec, new_gen))
197 lru += LRU_ACTIVE;
198 __update_lru_size(lruvec, lru, zone, delta);
199 return;
200 }
201
202 /* deletion */
203 if (new_gen < 0) {
204 if (lru_gen_is_active(lruvec, old_gen))
205 lru += LRU_ACTIVE;
206 __update_lru_size(lruvec, lru, zone, -delta);
207 return;
208 }
209
210 /* promotion */
211 if (!lru_gen_is_active(lruvec, old_gen) && lru_gen_is_active(lruvec, new_gen)) {
212 __update_lru_size(lruvec, lru, zone, -delta);
213 __update_lru_size(lruvec, lru + LRU_ACTIVE, zone, delta);
214 }
215
216 /* demotion requires isolation, e.g., lru_deactivate_fn() */
217 VM_WARN_ON_ONCE(lru_gen_is_active(lruvec, old_gen) && !lru_gen_is_active(lruvec, new_gen));
218}
219
220static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
221{
222 unsigned long seq;
223 unsigned long flags;
224 int gen = folio_lru_gen(folio);
225 int type = folio_is_file_lru(folio);
226 int zone = folio_zonenum(folio);
227 struct lru_gen_struct *lrugen = &lruvec->lrugen;
228
229 VM_WARN_ON_ONCE_FOLIO(gen != -1, folio);
230
231 if (folio_test_unevictable(folio) || !lrugen->enabled)
232 return false;
233 /*
234 * There are three common cases for this page:
235 * 1. If it's hot, e.g., freshly faulted in or previously hot and
236 * migrated, add it to the youngest generation.
237 * 2. If it's cold but can't be evicted immediately, i.e., an anon page
238 * not in swapcache or a dirty page pending writeback, add it to the
239 * second oldest generation.
240 * 3. Everything else (clean, cold) is added to the oldest generation.
241 */
242 if (folio_test_active(folio))
243 seq = lrugen->max_seq;
244 else if ((type == LRU_GEN_ANON && !folio_test_swapcache(folio)) ||
245 (folio_test_reclaim(folio) &&
246 (folio_test_dirty(folio) || folio_test_writeback(folio))))
247 seq = lrugen->min_seq[type] + 1;
248 else
249 seq = lrugen->min_seq[type];
250
251 gen = lru_gen_from_seq(seq);
252 flags = (gen + 1UL) << LRU_GEN_PGOFF;
253 /* see the comment on MIN_NR_GENS about PG_active */
254 set_mask_bits(&folio->flags, LRU_GEN_MASK | BIT(PG_active), flags);
255
256 lru_gen_update_size(lruvec, folio, -1, gen);
257 /* for folio_rotate_reclaimable() */
258 if (reclaiming)
259 list_add_tail(&folio->lru, &lrugen->lists[gen][type][zone]);
260 else
261 list_add(&folio->lru, &lrugen->lists[gen][type][zone]);
262
263 return true;
264}
265
266static inline bool lru_gen_del_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
267{
268 unsigned long flags;
269 int gen = folio_lru_gen(folio);
270
271 if (gen < 0)
272 return false;
273
274 VM_WARN_ON_ONCE_FOLIO(folio_test_active(folio), folio);
275 VM_WARN_ON_ONCE_FOLIO(folio_test_unevictable(folio), folio);
276
277 /* for folio_migrate_flags() */
278 flags = !reclaiming && lru_gen_is_active(lruvec, gen) ? BIT(PG_active) : 0;
279 flags = set_mask_bits(&folio->flags, LRU_GEN_MASK, flags);
280 gen = ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
281
282 lru_gen_update_size(lruvec, folio, gen, -1);
283 list_del(&folio->lru);
284
285 return true;
286}
287
288#else /* !CONFIG_LRU_GEN */
289
290static inline bool lru_gen_enabled(void)
291{
292 return false;
293}
294
295static inline bool lru_gen_in_fault(void)
296{
297 return false;
298}
299
300static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
301{
302 return false;
303}
304
305static inline bool lru_gen_del_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
306{
307 return false;
308}
309
310#endif /* CONFIG_LRU_GEN */
311
97static __always_inline312static __always_inline
98void lruvec_add_folio(struct lruvec *lruvec, struct folio *folio)313void lruvec_add_folio(struct lruvec *lruvec, struct folio *folio)
99{314{
100 enum lru_list lru = folio_lru_list(folio);315 enum lru_list lru = folio_lru_list(folio);
101 316
317 if (lru_gen_add_folio(lruvec, folio, false))
318 return;
319
102 update_lru_size(lruvec, lru, folio_zonenum(folio),320 update_lru_size(lruvec, lru, folio_zonenum(folio),
103 folio_nr_pages(folio));321 folio_nr_pages(folio));
104 if (lru != LRU_UNEVICTABLE)322 if (lru != LRU_UNEVICTABLE)
@@ -116,23 +334,23 @@ void lruvec_add_folio_tail(struct lruvec *lruvec, struct folio *folio) · 11 unmodified lines
116{334{
117 enum lru_list lru = folio_lru_list(folio);335 enum lru_list lru = folio_lru_list(folio);
118 336
337 if (lru_gen_add_folio(lruvec, folio, true))
338 return;
339
119 update_lru_size(lruvec, lru, folio_zonenum(folio),340 update_lru_size(lruvec, lru, folio_zonenum(folio),
120 folio_nr_pages(folio));341 folio_nr_pages(folio));
121 /* This is not expected to be used on LRU_UNEVICTABLE */342 /* This is not expected to be used on LRU_UNEVICTABLE */
122 list_add_tail(&folio->lru, &lruvec->lists[lru]);343 list_add_tail(&folio->lru, &lruvec->lists[lru]);
123}344}
124 345
125static __always_inline void add_page_to_lru_list_tail(struct page *page,
126 struct lruvec *lruvec)
127{
128 lruvec_add_folio_tail(lruvec, page_folio(page));
129}
130
131static __always_inline346static __always_inline
132void lruvec_del_folio(struct lruvec *lruvec, struct folio *folio)347void lruvec_del_folio(struct lruvec *lruvec, struct folio *folio)
133{348{
134 enum lru_list lru = folio_lru_list(folio);349 enum lru_list lru = folio_lru_list(folio);
135 350
351 if (lru_gen_del_folio(lruvec, folio, false))
352 return;
353
136 if (lru != LRU_UNEVICTABLE)354 if (lru != LRU_UNEVICTABLE)
137 list_del(&folio->lru);355 list_del(&folio->lru);
138 update_lru_size(lruvec, lru, folio_zonenum(folio),356 update_lru_size(lruvec, lru, folio_zonenum(folio),
include/linux/mm_types.h+152−26
@@ -9,6 +9,7 @@ · 8 unmodified lines
9#include <linux/list.h>9#include <linux/list.h>
10#include <linux/spinlock.h>10#include <linux/spinlock.h>
11#include <linux/rbtree.h>11#include <linux/rbtree.h>
12#include <linux/maple_tree.h>
12#include <linux/rwsem.h>13#include <linux/rwsem.h>
13#include <linux/completion.h>14#include <linux/completion.h>
14#include <linux/cpumask.h>15#include <linux/cpumask.h>
@@ -223,6 +224,18 @@ struct page { · 208 unmodified lines
223 not kmapped, ie. highmem) */224 not kmapped, ie. highmem) */
224#endif /* WANT_PAGE_VIRTUAL */225#endif /* WANT_PAGE_VIRTUAL */
225 226
227#ifdef CONFIG_KMSAN
228 /*
229 * KMSAN metadata for this page:
230 * - shadow page: every bit indicates whether the corresponding
231 * bit of the original page is initialized (0) or not (1);
232 * - origin page: every 4 bytes contain an id of the stack trace
233 * where the uninitialized value was created.
234 */
235 struct page *kmsan_shadow;
236 struct page *kmsan_origin;
237#endif
238
226#ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS239#ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS
227 int _last_cpupid;240 int _last_cpupid;
228#endif241#endif
@@ -244,6 +257,13 @@ struct page { · 15 unmodified lines
244 * @_refcount: Do not access this member directly. Use folio_ref_count()257 * @_refcount: Do not access this member directly. Use folio_ref_count()
245 * to find how many references there are to this folio.258 * to find how many references there are to this folio.
246 * @memcg_data: Memory Control Group data.259 * @memcg_data: Memory Control Group data.
260 * @_flags_1: For large folios, additional page flags.
261 * @__head: Points to the folio. Do not use.
262 * @_folio_dtor: Which destructor to use for this folio.
263 * @_folio_order: Do not use directly, call folio_order().
264 * @_total_mapcount: Do not use directly, call folio_entire_mapcount().
265 * @_pincount: Do not use directly, call folio_maybe_dma_pinned().
266 * @_folio_nr_pages: Do not use directly, call folio_nr_pages().
247 *267 *
248 * A folio is a physically, virtually and logically contiguous set268 * A folio is a physically, virtually and logically contiguous set
249 * of bytes. It is a power-of-two in size, and it is aligned to that269 * of bytes. It is a power-of-two in size, and it is aligned to that
@@ -282,9 +302,17 @@ struct folio { · 32 unmodified lines
282 };302 };
283 struct page page;303 struct page page;
284 };304 };
305 unsigned long _flags_1;
306 unsigned long __head;
307 unsigned char _folio_dtor;
308 unsigned char _folio_order;
309 atomic_t _total_mapcount;
310 atomic_t _pincount;
311#ifdef CONFIG_64BIT
312 unsigned int _folio_nr_pages;
313#endif
285};314};
286 315
287static_assert(sizeof(struct page) == sizeof(struct folio));
288#define FOLIO_MATCH(pg, fl) \316#define FOLIO_MATCH(pg, fl) \
289 static_assert(offsetof(struct page, pg) == offsetof(struct folio, fl))317 static_assert(offsetof(struct page, pg) == offsetof(struct folio, fl))
290FOLIO_MATCH(flags, flags);318FOLIO_MATCH(flags, flags);
@@ -299,6 +327,19 @@ FOLIO_MATCH(_refcount, _refcount); · 8 unmodified lines
299FOLIO_MATCH(memcg_data, memcg_data);327FOLIO_MATCH(memcg_data, memcg_data);
300#endif328#endif
301#undef FOLIO_MATCH329#undef FOLIO_MATCH
330#define FOLIO_MATCH(pg, fl) \
331 static_assert(offsetof(struct folio, fl) == \
332 offsetof(struct page, pg) + sizeof(struct page))
333FOLIO_MATCH(flags, _flags_1);
334FOLIO_MATCH(compound_head, __head);
335FOLIO_MATCH(compound_dtor, _folio_dtor);
336FOLIO_MATCH(compound_order, _folio_order);
337FOLIO_MATCH(compound_mapcount, _total_mapcount);
338FOLIO_MATCH(compound_pincount, _pincount);
339#ifdef CONFIG_64BIT
340FOLIO_MATCH(compound_nr, _folio_nr_pages);
341#endif
342#undef FOLIO_MATCH
302 343
303static inline atomic_t *folio_mapcount_ptr(struct folio *folio)344static inline atomic_t *folio_mapcount_ptr(struct folio *folio)
304{345{
@@ -407,21 +448,6 @@ struct vm_area_struct { · 102 unmodified lines
407 unsigned long vm_end; /* The first byte after our end address448 unsigned long vm_end; /* The first byte after our end address
408 within vm_mm. */449 within vm_mm. */
409 450
410 /* linked list of VM areas per task, sorted by address */
411 struct vm_area_struct *vm_next, *vm_prev;
412
413 struct rb_node vm_rb;
414
415 /*
416 * Largest free memory gap in bytes to the left of this VMA.
417 * Either between this VMA and vma->vm_prev, or between one of the
418 * VMAs below us in the VMA rbtree and its ->vm_prev. This helps
419 * get_unmapped_area find a free area of the right size.
420 */
421 unsigned long rb_subtree_gap;
422
423 /* Second cache line starts here. */
424
425 struct mm_struct *vm_mm; /* The address space we belong to. */451 struct mm_struct *vm_mm; /* The address space we belong to. */
426 452
427 /*453 /*
@@ -485,9 +511,7 @@ struct vm_area_struct { · 57 unmodified lines
485struct kioctx_table;511struct kioctx_table;
486struct mm_struct {512struct mm_struct {
487 struct {513 struct {
488 struct vm_area_struct *mmap; /* list of VMAs */514 struct maple_tree mm_mt;
489 struct rb_root mm_rb;
490 u64 vmacache_seqnum; /* per-thread vmacache */
491#ifdef CONFIG_MMU515#ifdef CONFIG_MMU
492 unsigned long (*get_unmapped_area) (struct file *filp,516 unsigned long (*get_unmapped_area) (struct file *filp,
493 unsigned long addr, unsigned long len,517 unsigned long addr, unsigned long len,
@@ -501,7 +525,6 @@ struct mm_struct { · 7 unmodified lines
501 unsigned long mmap_compat_legacy_base;525 unsigned long mmap_compat_legacy_base;
502#endif526#endif
503 unsigned long task_size; /* size of task vm space */527 unsigned long task_size; /* size of task vm space */
504 unsigned long highest_vm_end; /* highest vma end address */
505 pgd_t * pgd;528 pgd_t * pgd;
506 529
507#ifdef CONFIG_MEMBARRIER530#ifdef CONFIG_MEMBARRIER
@@ -631,22 +654,22 @@ struct mm_struct { · 123 unmodified lines
631#endif654#endif
632#ifdef CONFIG_NUMA_BALANCING655#ifdef CONFIG_NUMA_BALANCING
633 /*656 /*
634 * numa_next_scan is the next time that the PTEs will be marked657 * numa_next_scan is the next time that PTEs will be remapped
635 * pte_numa. NUMA hinting faults will gather statistics and658 * PROT_NONE to trigger NUMA hinting faults; such faults gather
636 * migrate pages to new nodes if necessary.659 * statistics and migrate pages to new nodes if necessary.
637 */660 */
638 unsigned long numa_next_scan;661 unsigned long numa_next_scan;
639 662
640 /* Restart point for scanning and setting pte_numa */663 /* Restart point for scanning and remapping PTEs. */
641 unsigned long numa_scan_offset;664 unsigned long numa_scan_offset;
642 665
643 /* numa_scan_seq prevents two threads setting pte_numa */666 /* numa_scan_seq prevents two threads remapping PTEs. */
644 int numa_scan_seq;667 int numa_scan_seq;
645#endif668#endif
646 /*669 /*
647 * An operation with batched TLB flushing is going on. Anything670 * An operation with batched TLB flushing is going on. Anything
648 * that can move process memory needs to flush the TLB when671 * that can move process memory needs to flush the TLB when
649 * moving a PROT_NONE or PROT_NUMA mapped page.672 * moving a PROT_NONE mapped page.
650 */673 */
651 atomic_t tlb_flush_pending;674 atomic_t tlb_flush_pending;
652#ifdef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH675#ifdef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
@@ -671,7 +694,28 @@ struct mm_struct { · 18 unmodified lines
671 * merging.694 * merging.
672 */695 */
673 unsigned long ksm_merging_pages;696 unsigned long ksm_merging_pages;
697 /*
698 * Represent how many pages are checked for ksm merging
699 * including merged and not merged.
700 */
701 unsigned long ksm_rmap_items;
702#endif
703#ifdef CONFIG_LRU_GEN
704 struct {
705 /* this mm_struct is on lru_gen_mm_list */
706 struct list_head list;
707 /*
708 * Set when switching to this mm_struct, as a hint of
709 * whether it has been used since the last time per-node
710 * page table walkers cleared the corresponding bits.
711 */
712 unsigned long bitmap;
713#ifdef CONFIG_MEMCG
714 /* points to the memcg of "owner" above */
715 struct mem_cgroup *memcg;
674#endif716#endif
717 } lru_gen;
718#endif /* CONFIG_LRU_GEN */
675 } __randomize_layout;719 } __randomize_layout;
676 720
677 /*721 /*
@@ -681,6 +725,7 @@ struct mm_struct { · 3 unmodified lines
681 unsigned long cpu_bitmap[];725 unsigned long cpu_bitmap[];
682};726};
683 727
728#define MM_MT_FLAGS (MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN)
684extern struct mm_struct init_mm;729extern struct mm_struct init_mm;
685 730
686/* Pointer magic because the dynamic array size confuses some compilers. */731/* Pointer magic because the dynamic array size confuses some compilers. */
@@ -698,6 +743,87 @@ static inline cpumask_t *mm_cpumask(struct mm_struct *mm) · 11 unmodified lines
698 return (struct cpumask *)&mm->cpu_bitmap;743 return (struct cpumask *)&mm->cpu_bitmap;
699}744}
700 745
746#ifdef CONFIG_LRU_GEN
747
748struct lru_gen_mm_list {
749 /* mm_struct list for page table walkers */
750 struct list_head fifo;
751 /* protects the list above */
752 spinlock_t lock;
753};
754
755void lru_gen_add_mm(struct mm_struct *mm);
756void lru_gen_del_mm(struct mm_struct *mm);
757#ifdef CONFIG_MEMCG
758void lru_gen_migrate_mm(struct mm_struct *mm);
759#endif
760
761static inline void lru_gen_init_mm(struct mm_struct *mm)
762{
763 INIT_LIST_HEAD(&mm->lru_gen.list);
764 mm->lru_gen.bitmap = 0;
765#ifdef CONFIG_MEMCG
766 mm->lru_gen.memcg = NULL;
767#endif
768}
769
770static inline void lru_gen_use_mm(struct mm_struct *mm)
771{
772 /*
773 * When the bitmap is set, page reclaim knows this mm_struct has been
774 * used since the last time it cleared the bitmap. So it might be worth
775 * walking the page tables of this mm_struct to clear the accessed bit.
776 */
777 WRITE_ONCE(mm->lru_gen.bitmap, -1);
778}
779
780#else /* !CONFIG_LRU_GEN */
781
782static inline void lru_gen_add_mm(struct mm_struct *mm)
783{
784}
785
786static inline void lru_gen_del_mm(struct mm_struct *mm)
787{
788}
789
790#ifdef CONFIG_MEMCG
791static inline void lru_gen_migrate_mm(struct mm_struct *mm)
792{
793}
794#endif
795
796static inline void lru_gen_init_mm(struct mm_struct *mm)
797{
798}
799
800static inline void lru_gen_use_mm(struct mm_struct *mm)
801{
802}
803
804#endif /* CONFIG_LRU_GEN */
805
806struct vma_iterator {
807 struct ma_state mas;
808};
809
810#define VMA_ITERATOR(name, __mm, __addr) \
811 struct vma_iterator name = { \
812 .mas = { \
813 .tree = &(__mm)->mm_mt, \
814 .index = __addr, \
815 .node = MAS_START, \
816 }, \
817 }
818
819static inline void vma_iter_init(struct vma_iterator *vmi,
820 struct mm_struct *mm, unsigned long addr)
821{
822 vmi->mas.tree = &mm->mm_mt;
823 vmi->mas.index = addr;
824 vmi->mas.node = MAS_START;
825}
826
701struct mmu_gather;827struct mmu_gather;
702extern void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm);828extern void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm);
703extern void tlb_gather_mmu_fullmm(struct mmu_gather *tlb, struct mm_struct *mm);829extern void tlb_gather_mmu_fullmm(struct mmu_gather *tlb, struct mm_struct *mm);
include/linux/mm_types_task.h+0−12
@@ -24,18 +24,6 @@ · 23 unmodified lines
24 IS_ENABLED(CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK))24 IS_ENABLED(CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK))
25#define ALLOC_SPLIT_PTLOCKS (SPINLOCK_SIZE > BITS_PER_LONG/8)25#define ALLOC_SPLIT_PTLOCKS (SPINLOCK_SIZE > BITS_PER_LONG/8)
26 26
27/*
28 * The per task VMA cache array:
29 */
30#define VMACACHE_BITS 2
31#define VMACACHE_SIZE (1U << VMACACHE_BITS)
32#define VMACACHE_MASK (VMACACHE_SIZE - 1)
33
34struct vmacache {
35 u64 seqnum;
36 struct vm_area_struct *vmas[VMACACHE_SIZE];
37};
38
39/*27/*
40 * When updating this, please also update struct resident_page_types[] in28 * When updating this, please also update struct resident_page_types[] in
41 * kernel/fork.c29 * kernel/fork.c
include/linux/mmzone.h+246−35
@@ -24,10 +24,10 @@ · 23 unmodified lines
24#include <asm/page.h>24#include <asm/page.h>
25 25
26/* Free memory management - zoned buddy allocator. */26/* Free memory management - zoned buddy allocator. */
27#ifndef CONFIG_FORCE_MAX_ZONEORDER27#ifndef CONFIG_ARCH_FORCE_MAX_ORDER
28#define MAX_ORDER 1128#define MAX_ORDER 11
29#else29#else
30#define MAX_ORDER CONFIG_FORCE_MAX_ZONEORDER30#define MAX_ORDER CONFIG_ARCH_FORCE_MAX_ORDER
31#endif31#endif
32#define MAX_ORDER_NR_PAGES (1 << (MAX_ORDER - 1))32#define MAX_ORDER_NR_PAGES (1 << (MAX_ORDER - 1))
33 33
@@ -121,20 +121,6 @@ static inline bool free_area_empty(struct free_area *area, int migratetype) · 87 unmodified lines
121 121
122struct pglist_data;122struct pglist_data;
123 123
124/*
125 * Add a wild amount of padding here to ensure data fall into separate
126 * cachelines. There are very few zone structures in the machine, so space
127 * consumption is not a concern here.
128 */
129#if defined(CONFIG_SMP)
130struct zone_padding {
131 char x[0];
132} ____cacheline_internodealigned_in_smp;
133#define ZONE_PADDING(name) struct zone_padding name;
134#else
135#define ZONE_PADDING(name)
136#endif
137
138#ifdef CONFIG_NUMA124#ifdef CONFIG_NUMA
139enum numa_stat_item {125enum numa_stat_item {
140 NUMA_HIT, /* allocated in intended node */126 NUMA_HIT, /* allocated in intended node */
@@ -222,6 +208,7 @@ enum node_stat_item { · 81 unmodified lines
222#endif208#endif
223#ifdef CONFIG_NUMA_BALANCING209#ifdef CONFIG_NUMA_BALANCING
224 PGPROMOTE_SUCCESS, /* promote successfully */210 PGPROMOTE_SUCCESS, /* promote successfully */
211 PGPROMOTE_CANDIDATE, /* candidate pages to promote */
225#endif212#endif
226 NR_VM_NODE_STAT_ITEMS213 NR_VM_NODE_STAT_ITEMS
227};214};
@@ -307,6 +294,8 @@ static inline bool is_active_lru(enum lru_list lru) · 79 unmodified lines
307 return (lru == LRU_ACTIVE_ANON || lru == LRU_ACTIVE_FILE);294 return (lru == LRU_ACTIVE_ANON || lru == LRU_ACTIVE_FILE);
308}295}
309 296
297#define WORKINGSET_ANON 0
298#define WORKINGSET_FILE 1
310#define ANON_AND_FILE 2299#define ANON_AND_FILE 2
311 300
312enum lruvec_flags {301enum lruvec_flags {
@@ -315,6 +304,207 @@ enum lruvec_flags { · 2 unmodified lines
315 */304 */
316};305};
317 306
307#endif /* !__GENERATING_BOUNDS_H */
308
309/*
310 * Evictable pages are divided into multiple generations. The youngest and the
311 * oldest generation numbers, max_seq and min_seq, are monotonically increasing.
312 * They form a sliding window of a variable size [MIN_NR_GENS, MAX_NR_GENS]. An
313 * offset within MAX_NR_GENS, i.e., gen, indexes the LRU list of the
314 * corresponding generation. The gen counter in folio->flags stores gen+1 while
315 * a page is on one of lrugen->lists[]. Otherwise it stores 0.
316 *
317 * A page is added to the youngest generation on faulting. The aging needs to
318 * check the accessed bit at least twice before handing this page over to the
319 * eviction. The first check takes care of the accessed bit set on the initial
320 * fault; the second check makes sure this page hasn't been used since then.
321 * This process, AKA second chance, requires a minimum of two generations,
322 * hence MIN_NR_GENS. And to maintain ABI compatibility with the active/inactive
323 * LRU, e.g., /proc/vmstat, these two generations are considered active; the
324 * rest of generations, if they exist, are considered inactive. See
325 * lru_gen_is_active().
326 *
327 * PG_active is always cleared while a page is on one of lrugen->lists[] so that
328 * the aging needs not to worry about it. And it's set again when a page
329 * considered active is isolated for non-reclaiming purposes, e.g., migration.
330 * See lru_gen_add_folio() and lru_gen_del_folio().
331 *
332 * MAX_NR_GENS is set to 4 so that the multi-gen LRU can support twice the
333 * number of categories of the active/inactive LRU when keeping track of
334 * accesses through page tables. This requires order_base_2(MAX_NR_GENS+1) bits
335 * in folio->flags.
336 */
337#define MIN_NR_GENS 2U
338#define MAX_NR_GENS 4U
339
340/*
341 * Each generation is divided into multiple tiers. A page accessed N times
342 * through file descriptors is in tier order_base_2(N). A page in the first tier
343 * (N=0,1) is marked by PG_referenced unless it was faulted in through page
344 * tables or read ahead. A page in any other tier (N>1) is marked by
345 * PG_referenced and PG_workingset. This implies a minimum of two tiers is
346 * supported without using additional bits in folio->flags.
347 *
348 * In contrast to moving across generations which requires the LRU lock, moving
349 * across tiers only involves atomic operations on folio->flags and therefore
350 * has a negligible cost in the buffered access path. In the eviction path,
351 * comparisons of refaulted/(evicted+protected) from the first tier and the
352 * rest infer whether pages accessed multiple times through file descriptors
353 * are statistically hot and thus worth protecting.
354 *
355 * MAX_NR_TIERS is set to 4 so that the multi-gen LRU can support twice the
356 * number of categories of the active/inactive LRU when keeping track of
357 * accesses through file descriptors. This uses MAX_NR_TIERS-2 spare bits in
358 * folio->flags.
359 */
360#define MAX_NR_TIERS 4U
361
362#ifndef __GENERATING_BOUNDS_H
363
364struct lruvec;
365struct page_vma_mapped_walk;
366
367#define LRU_GEN_MASK ((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF)
368#define LRU_REFS_MASK ((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PGOFF)
369
370#ifdef CONFIG_LRU_GEN
371
372enum {
373 LRU_GEN_ANON,
374 LRU_GEN_FILE,
375};
376
377enum {
378 LRU_GEN_CORE,
379 LRU_GEN_MM_WALK,
380 LRU_GEN_NONLEAF_YOUNG,
381 NR_LRU_GEN_CAPS
382};
383
384#define MIN_LRU_BATCH BITS_PER_LONG
385#define MAX_LRU_BATCH (MIN_LRU_BATCH * 64)
386
387/* whether to keep historical stats from evicted generations */
388#ifdef CONFIG_LRU_GEN_STATS
389#define NR_HIST_GENS MAX_NR_GENS
390#else
391#define NR_HIST_GENS 1U
392#endif
393
394/*
395 * The youngest generation number is stored in max_seq for both anon and file
396 * types as they are aged on an equal footing. The oldest generation numbers are
397 * stored in min_seq[] separately for anon and file types as clean file pages
398 * can be evicted regardless of swap constraints.
399 *
400 * Normally anon and file min_seq are in sync. But if swapping is constrained,
401 * e.g., out of swap space, file min_seq is allowed to advance and leave anon
402 * min_seq behind.
403 *
404 * The number of pages in each generation is eventually consistent and therefore
405 * can be transiently negative when reset_batch_size() is pending.
406 */
407struct lru_gen_struct {
408 /* the aging increments the youngest generation number */
409 unsigned long max_seq;
410 /* the eviction increments the oldest generation numbers */
411 unsigned long min_seq[ANON_AND_FILE];
412 /* the birth time of each generation in jiffies */
413 unsigned long timestamps[MAX_NR_GENS];
414 /* the multi-gen LRU lists, lazily sorted on eviction */
415 struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
416 /* the multi-gen LRU sizes, eventually consistent */
417 long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
418 /* the exponential moving average of refaulted */
419 unsigned long avg_refaulted[ANON_AND_FILE][MAX_NR_TIERS];
420 /* the exponential moving average of evicted+protected */
421 unsigned long avg_total[ANON_AND_FILE][MAX_NR_TIERS];
422 /* the first tier doesn't need protection, hence the minus one */
423 unsigned long protected[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS - 1];
424 /* can be modified without holding the LRU lock */
425 atomic_long_t evicted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS];
426 atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS];
427 /* whether the multi-gen LRU is enabled */
428 bool enabled;
429};
430
431enum {
432 MM_LEAF_TOTAL, /* total leaf entries */
433 MM_LEAF_OLD, /* old leaf entries */
434 MM_LEAF_YOUNG, /* young leaf entries */
435 MM_NONLEAF_TOTAL, /* total non-leaf entries */
436 MM_NONLEAF_FOUND, /* non-leaf entries found in Bloom filters */
437 MM_NONLEAF_ADDED, /* non-leaf entries added to Bloom filters */
438 NR_MM_STATS
439};
440
441/* double-buffering Bloom filters */
442#define NR_BLOOM_FILTERS 2
443
444struct lru_gen_mm_state {
445 /* set to max_seq after each iteration */
446 unsigned long seq;
447 /* where the current iteration continues (inclusive) */
448 struct list_head *head;
449 /* where the last iteration ended (exclusive) */
450 struct list_head *tail;
451 /* to wait for the last page table walker to finish */
452 struct wait_queue_head wait;
453 /* Bloom filters flip after each iteration */
454 unsigned long *filters[NR_BLOOM_FILTERS];
455 /* the mm stats for debugging */
456 unsigned long stats[NR_HIST_GENS][NR_MM_STATS];
457 /* the number of concurrent page table walkers */
458 int nr_walkers;
459};
460
461struct lru_gen_mm_walk {
462 /* the lruvec under reclaim */
463 struct lruvec *lruvec;
464 /* unstable max_seq from lru_gen_struct */
465 unsigned long max_seq;
466 /* the next address within an mm to scan */
467 unsigned long next_addr;
468 /* to batch promoted pages */
469 int nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
470 /* to batch the mm stats */
471 int mm_stats[NR_MM_STATS];
472 /* total batched items */
473 int batched;
474 bool can_swap;
475 bool force_scan;
476};
477
478void lru_gen_init_lruvec(struct lruvec *lruvec);
479void lru_gen_look_around(struct page_vma_mapped_walk *pvmw);
480
481#ifdef CONFIG_MEMCG
482void lru_gen_init_memcg(struct mem_cgroup *memcg);
483void lru_gen_exit_memcg(struct mem_cgroup *memcg);
484#endif
485
486#else /* !CONFIG_LRU_GEN */
487
488static inline void lru_gen_init_lruvec(struct lruvec *lruvec)
489{
490}
491
492static inline void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
493{
494}
495
496#ifdef CONFIG_MEMCG
497static inline void lru_gen_init_memcg(struct mem_cgroup *memcg)
498{
499}
500
501static inline void lru_gen_exit_memcg(struct mem_cgroup *memcg)
502{
503}
504#endif
505
506#endif /* CONFIG_LRU_GEN */
507
318struct lruvec {508struct lruvec {
319 struct list_head lists[NR_LRU_LISTS];509 struct list_head lists[NR_LRU_LISTS];
320 /* per lruvec lru_lock for memcg */510 /* per lruvec lru_lock for memcg */
@@ -332,6 +522,12 @@ struct lruvec { · 11 unmodified lines
332 unsigned long refaults[ANON_AND_FILE];522 unsigned long refaults[ANON_AND_FILE];
333 /* Various lruvec state flags (enum lruvec_flags) */523 /* Various lruvec state flags (enum lruvec_flags) */
334 unsigned long flags;524 unsigned long flags;
525#ifdef CONFIG_LRU_GEN
526 /* evictable pages divided into generations */
527 struct lru_gen_struct lrugen;
528 /* to concurrently iterate lru_gen_mm_list */
529 struct lru_gen_mm_state mm_state;
530#endif
335#ifdef CONFIG_MEMCG531#ifdef CONFIG_MEMCG
336 struct pglist_data *pgdat;532 struct pglist_data *pgdat;
337#endif533#endif
@@ -369,13 +565,6 @@ enum zone_watermarks { · 31 unmodified lines
369#define NR_LOWORDER_PCP_LISTS (MIGRATE_PCPTYPES * (PAGE_ALLOC_COSTLY_ORDER + 1))565#define NR_LOWORDER_PCP_LISTS (MIGRATE_PCPTYPES * (PAGE_ALLOC_COSTLY_ORDER + 1))
370#define NR_PCP_LISTS (NR_LOWORDER_PCP_LISTS + NR_PCP_THP)566#define NR_PCP_LISTS (NR_LOWORDER_PCP_LISTS + NR_PCP_THP)
371 567
372/*
373 * Shift to encode migratetype and order in the same integer, with order
374 * in the least significant bits.
375 */
376#define NR_PCP_ORDER_WIDTH 8
377#define NR_PCP_ORDER_MASK ((1<<NR_PCP_ORDER_WIDTH) - 1)
378
379#define min_wmark_pages(z) (z->_watermark[WMARK_MIN] + z->watermark_boost)568#define min_wmark_pages(z) (z->_watermark[WMARK_MIN] + z->watermark_boost)
380#define low_wmark_pages(z) (z->_watermark[WMARK_LOW] + z->watermark_boost)569#define low_wmark_pages(z) (z->_watermark[WMARK_LOW] + z->watermark_boost)
381#define high_wmark_pages(z) (z->_watermark[WMARK_HIGH] + z->watermark_boost)570#define high_wmark_pages(z) (z->_watermark[WMARK_HIGH] + z->watermark_boost)
@@ -628,7 +817,7 @@ struct zone { · 246 unmodified lines
628 int initialized;817 int initialized;
629 818
630 /* Write-intensive fields used from the page allocator */819 /* Write-intensive fields used from the page allocator */
631 ZONE_PADDING(_pad1_)820 CACHELINE_PADDING(_pad1_);
632 821
633 /* free areas of different sizes */822 /* free areas of different sizes */
634 struct free_area free_area[MAX_ORDER];823 struct free_area free_area[MAX_ORDER];
@@ -640,7 +829,7 @@ struct zone { · 5 unmodified lines
640 spinlock_t lock;829 spinlock_t lock;
641 830
642 /* Write-intensive fields used by compaction and vmstats. */831 /* Write-intensive fields used by compaction and vmstats. */
643 ZONE_PADDING(_pad2_)832 CACHELINE_PADDING(_pad2_);
644 833
645 /*834 /*
646 * When free pages are below this point, additional steps are taken835 * When free pages are below this point, additional steps are taken
@@ -677,7 +866,7 @@ struct zone { · 30 unmodified lines
677 866
678 bool contiguous;867 bool contiguous;
679 868
680 ZONE_PADDING(_pad3_)869 CACHELINE_PADDING(_pad3_);
681 /* Zone statistics */870 /* Zone statistics */
682 atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];871 atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
683 atomic_long_t vm_numa_event[NR_VM_NUMA_EVENT_ITEMS];872 atomic_long_t vm_numa_event[NR_VM_NUMA_EVENT_ITEMS];
@@ -747,6 +936,8 @@ static inline bool zone_is_empty(struct zone *zone) · 63 unmodified lines
747#define ZONES_PGOFF (NODES_PGOFF - ZONES_WIDTH)936#define ZONES_PGOFF (NODES_PGOFF - ZONES_WIDTH)
748#define LAST_CPUPID_PGOFF (ZONES_PGOFF - LAST_CPUPID_WIDTH)937#define LAST_CPUPID_PGOFF (ZONES_PGOFF - LAST_CPUPID_WIDTH)
749#define KASAN_TAG_PGOFF (LAST_CPUPID_PGOFF - KASAN_TAG_WIDTH)938#define KASAN_TAG_PGOFF (LAST_CPUPID_PGOFF - KASAN_TAG_WIDTH)
939#define LRU_GEN_PGOFF (KASAN_TAG_PGOFF - LRU_GEN_WIDTH)
940#define LRU_REFS_PGOFF (LRU_GEN_PGOFF - LRU_REFS_WIDTH)
750 941
751/*942/*
752 * Define the bit shifts to access each section. For non-existent943 * Define the bit shifts to access each section. For non-existent
@@ -954,8 +1145,10 @@ typedef struct pglist_data { · 201 unmodified lines
954 atomic_t nr_writeback_throttled;/* nr of writeback-throttled tasks */1145 atomic_t nr_writeback_throttled;/* nr of writeback-throttled tasks */
955 unsigned long nr_reclaim_start; /* nr pages written while throttled1146 unsigned long nr_reclaim_start; /* nr pages written while throttled
956 * when throttling started. */1147 * when throttling started. */
957 struct task_struct *kswapd; /* Protected by1148#ifdef CONFIG_MEMORY_HOTPLUG
958 mem_hotplug_begin/done() */1149 struct mutex kswapd_lock;
1150#endif
1151 struct task_struct *kswapd; /* Protected by kswapd_lock */
959 int kswapd_order;1152 int kswapd_order;
960 enum zone_type kswapd_highest_zoneidx;1153 enum zone_type kswapd_highest_zoneidx;
961 1154
@@ -983,7 +1176,7 @@ typedef struct pglist_data { · 21 unmodified lines
983#endif /* CONFIG_NUMA */1176#endif /* CONFIG_NUMA */
984 1177
985 /* Write-intensive fields used by page reclaim */1178 /* Write-intensive fields used by page reclaim */
986 ZONE_PADDING(_pad1_)1179 CACHELINE_PADDING(_pad1_);
987 1180
988#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT1181#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
989 /*1182 /*
@@ -997,6 +1190,21 @@ typedef struct pglist_data { · 7 unmodified lines
997 struct deferred_split deferred_split_queue;1190 struct deferred_split deferred_split_queue;
998#endif1191#endif
999 1192
1193#ifdef CONFIG_NUMA_BALANCING
1194 /* start time in ms of current promote rate limit period */
1195 unsigned int nbp_rl_start;
1196 /* number of promote candidate pages at start time of current rate limit period */
1197 unsigned long nbp_rl_nr_cand;
1198 /* promote threshold in ms */
1199 unsigned int nbp_threshold;
1200 /* start time in ms of current promote threshold adjustment period */
1201 unsigned int nbp_th_start;
1202 /*
1203 * number of promote candidate pages at stat time of current promote
1204 * threshold adjustment period
1205 */
1206 unsigned long nbp_th_nr_cand;
1207#endif
1000 /* Fields commonly accessed by the page reclaim scanner */1208 /* Fields commonly accessed by the page reclaim scanner */
1001 1209
1002 /*1210 /*
@@ -1008,11 +1216,19 @@ typedef struct pglist_data { · 5 unmodified lines
1008 1216
1009 unsigned long flags;1217 unsigned long flags;
1010 1218
1011 ZONE_PADDING(_pad2_)1219#ifdef CONFIG_LRU_GEN
1220 /* kswap mm walk data */
1221 struct lru_gen_mm_walk mm_walk;
1222#endif
1223
1224 CACHELINE_PADDING(_pad2_);
1012 1225
1013 /* Per-node vmstats */1226 /* Per-node vmstats */
1014 struct per_cpu_nodestat __percpu *per_cpu_nodestats;1227 struct per_cpu_nodestat __percpu *per_cpu_nodestats;
1015 atomic_long_t vm_stat[NR_VM_NODE_STAT_ITEMS];1228 atomic_long_t vm_stat[NR_VM_NODE_STAT_ITEMS];
1229#ifdef CONFIG_NUMA
1230 struct memory_tier __rcu *memtier;
1231#endif
1016} pg_data_t;1232} pg_data_t;
1017 1233
1018#define node_present_pages(nid) (NODE_DATA(nid)->node_present_pages)1234#define node_present_pages(nid) (NODE_DATA(nid)->node_present_pages)
@@ -1026,11 +1242,6 @@ static inline unsigned long pgdat_end_pfn(pg_data_t *pgdat) · 7 unmodified lines
1026 return pgdat->node_start_pfn + pgdat->node_spanned_pages;1242 return pgdat->node_start_pfn + pgdat->node_spanned_pages;
1027}1243}
1028 1244
1029static inline bool pgdat_is_empty(pg_data_t *pgdat)
1030{
1031 return !pgdat->node_start_pfn && !pgdat->node_spanned_pages;
1032}
1033
1034#include <linux/memory_hotplug.h>1245#include <linux/memory_hotplug.h>
1035 1246
1036void build_all_zonelists(pg_data_t *pgdat);1247void build_all_zonelists(pg_data_t *pgdat);
include/linux/node.h+4−25
@@ -2,15 +2,15 @@ · 1 unmodified line
2/*2/*
3 * include/linux/node.h - generic node definition3 * include/linux/node.h - generic node definition
4 *4 *
5 * This is mainly for topological representation. We define the 5 * This is mainly for topological representation. We define the
6 * basic 'struct node' here, which can be embedded in per-arch 6 * basic 'struct node' here, which can be embedded in per-arch
7 * definitions of processors.7 * definitions of processors.
8 *8 *
9 * Basic handling of the devices is done in drivers/base/node.c9 * Basic handling of the devices is done in drivers/base/node.c
10 * and system devices are handled in drivers/base/sys.c. 10 * and system devices are handled in drivers/base/sys.c.
11 *11 *
12 * Nodes are exported via driverfs in the class/node/devices/12 * Nodes are exported via driverfs in the class/node/devices/
13 * directory. 13 * directory.
14 */14 */
15#ifndef _LINUX_NODE_H_15#ifndef _LINUX_NODE_H_
16#define _LINUX_NODE_H_16#define _LINUX_NODE_H_
@@ -18,7 +18,6 @@ · 1 unmodified line
18#include <linux/device.h>18#include <linux/device.h>
19#include <linux/cpumask.h>19#include <linux/cpumask.h>
20#include <linux/list.h>20#include <linux/list.h>
21#include <linux/workqueue.h>
22 21
23/**22/**
24 * struct node_hmem_attrs - heterogeneous memory performance attributes23 * struct node_hmem_attrs - heterogeneous memory performance attributes
@@ -84,10 +83,6 @@ static inline void node_set_perf_attrs(unsigned int nid, · 59 unmodified lines
84struct node {83struct node {
85 struct device dev;84 struct device dev;
86 struct list_head access_list;85 struct list_head access_list;
87
88#if defined(CONFIG_MEMORY_HOTPLUG) && defined(CONFIG_HUGETLBFS)
89 struct work_struct node_work;
90#endif
91#ifdef CONFIG_HMEM_REPORTING86#ifdef CONFIG_HMEM_REPORTING
92 struct list_head cache_attrs;87 struct list_head cache_attrs;
93 struct device *cache_dev;88 struct device *cache_dev;
@@ -96,7 +91,6 @@ struct node { · 2 unmodified lines
96 91
97struct memory_block;92struct memory_block;
98extern struct node *node_devices[];93extern struct node *node_devices[];
99typedef void (*node_registration_func_t)(struct node *);
100 94
101#if defined(CONFIG_MEMORY_HOTPLUG) && defined(CONFIG_NUMA)95#if defined(CONFIG_MEMORY_HOTPLUG) && defined(CONFIG_NUMA)
102void register_memory_blocks_under_node(int nid, unsigned long start_pfn,96void register_memory_blocks_under_node(int nid, unsigned long start_pfn,
@@ -144,11 +138,6 @@ extern void unregister_memory_block_under_nodes(struct memory_block *mem_blk); · 41 unmodified lines
144extern int register_memory_node_under_compute_node(unsigned int mem_nid,138extern int register_memory_node_under_compute_node(unsigned int mem_nid,
145 unsigned int cpu_nid,139 unsigned int cpu_nid,
146 unsigned access);140 unsigned access);
147
148#ifdef CONFIG_HUGETLBFS
149extern void register_hugetlbfs_with_node(node_registration_func_t doregister,
150 node_registration_func_t unregister);
151#endif
152#else141#else
153static inline void node_dev_init(void)142static inline void node_dev_init(void)
154{143{
@@ -176,18 +165,8 @@ static inline int unregister_cpu_under_node(unsigned int cpu, unsigned int nid) · 21 unmodified lines
176static inline void unregister_memory_block_under_nodes(struct memory_block *mem_blk)165static inline void unregister_memory_block_under_nodes(struct memory_block *mem_blk)
177{166{
178}167}
179
180static inline void register_hugetlbfs_with_node(node_registration_func_t reg,
181 node_registration_func_t unreg)
182{
183}
184#endif168#endif
185 169
186#define to_node(device) container_of(device, struct node, dev)170#define to_node(device) container_of(device, struct node, dev)
187 171
188static inline bool node_is_toptier(int node)
189{
190 return node_state(node, N_CPU);
191}
192
193#endif /* _LINUX_NODE_H_ */172#endif /* _LINUX_NODE_H_ */
include/linux/nodemask.h+12−2
@@ -493,6 +493,7 @@ static inline int num_node_state(enum node_states state) · 492 unmodified lines
493#define first_online_node 0493#define first_online_node 0
494#define first_memory_node 0494#define first_memory_node 0
495#define next_online_node(nid) (MAX_NUMNODES)495#define next_online_node(nid) (MAX_NUMNODES)
496#define next_memory_node(nid) (MAX_NUMNODES)
496#define nr_node_ids 1U497#define nr_node_ids 1U
497#define nr_online_nodes 1U498#define nr_online_nodes 1U
498 499
@@ -504,11 +505,20 @@ static inline int num_node_state(enum node_states state) · 5 unmodified lines
504static inline int node_random(const nodemask_t *maskp)505static inline int node_random(const nodemask_t *maskp)
505{506{
506#if defined(CONFIG_NUMA) && (MAX_NUMNODES > 1)507#if defined(CONFIG_NUMA) && (MAX_NUMNODES > 1)
507 int w, bit = NUMA_NO_NODE;508 int w, bit;
508 509
509 w = nodes_weight(*maskp);510 w = nodes_weight(*maskp);
510 if (w)511 switch (w) {
512 case 0:
513 bit = NUMA_NO_NODE;
514 break;
515 case 1:
516 bit = first_node(*maskp);
517 break;
518 default:
511 bit = find_nth_bit(maskp->bits, MAX_NUMNODES, get_random_int() % w);519 bit = find_nth_bit(maskp->bits, MAX_NUMNODES, get_random_int() % w);
520 break;
521 }
512 return bit;522 return bit;
513#else523#else
514 return 0;524 return 0;
include/linux/oom.h+0−11
@@ -77,15 +77,6 @@ static inline bool tsk_is_oom_victim(struct task_struct * tsk) · 76 unmodified lines
77 return tsk->signal->oom_mm;77 return tsk->signal->oom_mm;
78}78}
79 79
80/*
81 * Use this helper if tsk->mm != mm and the victim mm needs a special
82 * handling. This is guaranteed to stay true after once set.
83 */
84static inline bool mm_is_oom_victim(struct mm_struct *mm)
85{
86 return test_bit(MMF_OOM_VICTIM, &mm->flags);
87}
88
89/*80/*
90 * Checks whether a page fault on the given mm is still reliable.81 * Checks whether a page fault on the given mm is still reliable.
91 * This is no longer true if the oom reaper started to reap the82 * This is no longer true if the oom reaper started to reap the
@@ -106,8 +97,6 @@ static inline vm_fault_t check_stable_address_space(struct mm_struct *mm) · 14 unmodified lines
106 return 0;97 return 0;
107}98}
108 99
109bool __oom_reap_task_mm(struct mm_struct *mm);
110
111long oom_badness(struct task_struct *p,100long oom_badness(struct task_struct *p,
112 unsigned long totalpages);101 unsigned long totalpages);
113 102
include/linux/page-flags-layout.h+11−5
@@ -55,7 +55,8 @@ · 54 unmodified lines
55#define SECTIONS_WIDTH 055#define SECTIONS_WIDTH 0
56#endif56#endif
57 57
58#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_SHIFT <= BITS_PER_LONG - NR_PAGEFLAGS58#if ZONES_WIDTH + LRU_GEN_WIDTH + SECTIONS_WIDTH + NODES_SHIFT \
59 <= BITS_PER_LONG - NR_PAGEFLAGS
59#define NODES_WIDTH NODES_SHIFT60#define NODES_WIDTH NODES_SHIFT
60#elif defined(CONFIG_SPARSEMEM_VMEMMAP)61#elif defined(CONFIG_SPARSEMEM_VMEMMAP)
61#error "Vmemmap: No space for nodes field in page flags"62#error "Vmemmap: No space for nodes field in page flags"
@@ -89,8 +90,8 @@ · 27 unmodified lines
89#define LAST_CPUPID_SHIFT 090#define LAST_CPUPID_SHIFT 0
90#endif91#endif
91 92
92#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + KASAN_TAG_WIDTH + LAST_CPUPID_SHIFT \93#if ZONES_WIDTH + LRU_GEN_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + \
93 <= BITS_PER_LONG - NR_PAGEFLAGS94 KASAN_TAG_WIDTH + LAST_CPUPID_SHIFT <= BITS_PER_LONG - NR_PAGEFLAGS
94#define LAST_CPUPID_WIDTH LAST_CPUPID_SHIFT95#define LAST_CPUPID_WIDTH LAST_CPUPID_SHIFT
95#else96#else
96#define LAST_CPUPID_WIDTH 097#define LAST_CPUPID_WIDTH 0
@@ -100,10 +101,15 @@ · 3 unmodified lines
100#define LAST_CPUPID_NOT_IN_PAGE_FLAGS101#define LAST_CPUPID_NOT_IN_PAGE_FLAGS
101#endif102#endif
102 103
103#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + KASAN_TAG_WIDTH + LAST_CPUPID_WIDTH \104#if ZONES_WIDTH + LRU_GEN_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + \
104 > BITS_PER_LONG - NR_PAGEFLAGS105 KASAN_TAG_WIDTH + LAST_CPUPID_WIDTH > BITS_PER_LONG - NR_PAGEFLAGS
105#error "Not enough bits in page flags"106#error "Not enough bits in page flags"
106#endif107#endif
107 108
109/* see the comment on MAX_NR_TIERS */
110#define LRU_REFS_WIDTH min(__LRU_REFS_WIDTH, BITS_PER_LONG - NR_PAGEFLAGS - \
111 ZONES_WIDTH - LRU_GEN_WIDTH - SECTIONS_WIDTH - \
112 NODES_WIDTH - KASAN_TAG_WIDTH - LAST_CPUPID_WIDTH)
113
108#endif114#endif
109#endif /* _LINUX_PAGE_FLAGS_LAYOUT */115#endif /* _LINUX_PAGE_FLAGS_LAYOUT */
include/linux/page-flags.h+2−2
@@ -1058,7 +1058,7 @@ static __always_inline void __ClearPageAnonExclusive(struct page *page) · 1057 unmodified lines
1058 1UL << PG_private | 1UL << PG_private_2 | \1058 1UL << PG_private | 1UL << PG_private_2 | \
1059 1UL << PG_writeback | 1UL << PG_reserved | \1059 1UL << PG_writeback | 1UL << PG_reserved | \
1060 1UL << PG_slab | 1UL << PG_active | \1060 1UL << PG_slab | 1UL << PG_active | \
1061 1UL << PG_unevictable | __PG_MLOCKED)1061 1UL << PG_unevictable | __PG_MLOCKED | LRU_GEN_MASK)
1062 1062
1063/*1063/*
1064 * Flags checked when a page is prepped for return by the page allocator.1064 * Flags checked when a page is prepped for return by the page allocator.
@@ -1069,7 +1069,7 @@ static __always_inline void __ClearPageAnonExclusive(struct page *page) · 4 unmodified lines
1069 * alloc-free cycle to prevent from reusing the page.1069 * alloc-free cycle to prevent from reusing the page.
1070 */1070 */
1071#define PAGE_FLAGS_CHECK_AT_PREP \1071#define PAGE_FLAGS_CHECK_AT_PREP \
1072 (PAGEFLAGS_MASK & ~__PG_HWPOISON)1072 ((PAGEFLAGS_MASK & ~__PG_HWPOISON) | LRU_GEN_MASK | LRU_REFS_MASK)
1073 1073
1074#define PAGE_FLAGS_PRIVATE \1074#define PAGE_FLAGS_PRIVATE \
1075 (1UL << PG_private | 1UL << PG_private_2)1075 (1UL << PG_private | 1UL << PG_private_2)
include/linux/page_counter.h+14−12
@@ -3,15 +3,17 @@ · 2 unmodified lines
3#define _LINUX_PAGE_COUNTER_H3#define _LINUX_PAGE_COUNTER_H
4 4
5#include <linux/atomic.h>5#include <linux/atomic.h>
6#include <linux/cache.h>
6#include <linux/kernel.h>7#include <linux/kernel.h>
7#include <asm/page.h>8#include <asm/page.h>
8 9
9struct page_counter {10struct page_counter {
11 /*
12 * Make sure 'usage' does not share cacheline with any other field. The
13 * memcg->memory.usage is a hot member of struct mem_cgroup.
14 */
10 atomic_long_t usage;15 atomic_long_t usage;
11 unsigned long min;16 CACHELINE_PADDING(_pad1_);
12 unsigned long low;
13 unsigned long high;
14 unsigned long max;
15 17
16 /* effective memory.min and memory.min usage tracking */18 /* effective memory.min and memory.min usage tracking */
17 unsigned long emin;19 unsigned long emin;
@@ -23,18 +25,18 @@ struct page_counter { · 5 unmodified lines
23 atomic_long_t low_usage;25 atomic_long_t low_usage;
24 atomic_long_t children_low_usage;26 atomic_long_t children_low_usage;
25 27
26 /* legacy */
27 unsigned long watermark;28 unsigned long watermark;
28 unsigned long failcnt;29 unsigned long failcnt;
29 30
30 /*31 /* Keep all the read most fields in a separete cacheline. */
31 * 'parent' is placed here to be far from 'usage' to reduce32 CACHELINE_PADDING(_pad2_);
32 * cache false sharing, as 'usage' is written mostly while33
33 * parent is frequently read for cgroup's hierarchical34 unsigned long min;
34 * counting nature.35 unsigned long low;
35 */36 unsigned long high;
37 unsigned long max;
36 struct page_counter *parent;38 struct page_counter *parent;
37};39} ____cacheline_internodealigned_in_smp;
38 40
39#if BITS_PER_LONG == 3241#if BITS_PER_LONG == 32
40#define PAGE_COUNTER_MAX LONG_MAX42#define PAGE_COUNTER_MAX LONG_MAX
include/linux/page_ext.h+20−4
@@ -36,9 +36,15 @@ struct page_ext { · 35 unmodified lines
36 unsigned long flags;36 unsigned long flags;
37};37};
38 38
39extern bool early_page_ext;
39extern unsigned long page_ext_size;40extern unsigned long page_ext_size;
40extern void pgdat_page_ext_init(struct pglist_data *pgdat);41extern void pgdat_page_ext_init(struct pglist_data *pgdat);
41 42
43static inline bool early_page_ext_enabled(void)
44{
45 return early_page_ext;
46}
47
42#ifdef CONFIG_SPARSEMEM48#ifdef CONFIG_SPARSEMEM
43static inline void page_ext_init_flatmem(void)49static inline void page_ext_init_flatmem(void)
44{50{
@@ -55,7 +61,8 @@ static inline void page_ext_init(void) · 10 unmodified lines
55}61}
56#endif62#endif
57 63
58struct page_ext *lookup_page_ext(const struct page *page);64extern struct page_ext *page_ext_get(struct page *page);
65extern void page_ext_put(struct page_ext *page_ext);
59 66
60static inline struct page_ext *page_ext_next(struct page_ext *curr)67static inline struct page_ext *page_ext_next(struct page_ext *curr)
61{68{
@@ -67,13 +74,13 @@ static inline struct page_ext *page_ext_next(struct page_ext *curr) · 5 unmodified lines
67#else /* !CONFIG_PAGE_EXTENSION */74#else /* !CONFIG_PAGE_EXTENSION */
68struct page_ext;75struct page_ext;
69 76
70static inline void pgdat_page_ext_init(struct pglist_data *pgdat)77static inline bool early_page_ext_enabled(void)
71{78{
79 return false;
72}80}
73 81
74static inline struct page_ext *lookup_page_ext(const struct page *page)82static inline void pgdat_page_ext_init(struct pglist_data *pgdat)
75{83{
76 return NULL;
77}84}
78 85
79static inline void page_ext_init(void)86static inline void page_ext_init(void)
@@ -87,5 +94,14 @@ static inline void page_ext_init_flatmem_late(void) · 7 unmodified lines
87static inline void page_ext_init_flatmem(void)94static inline void page_ext_init_flatmem(void)
88{95{
89}96}
97
98static inline struct page_ext *page_ext_get(struct page *page)
99{
100 return NULL;
101}
102
103static inline void page_ext_put(struct page_ext *page_ext)
104{
105}
90#endif /* CONFIG_PAGE_EXTENSION */106#endif /* CONFIG_PAGE_EXTENSION */
91#endif /* __LINUX_PAGE_EXT_H */107#endif /* __LINUX_PAGE_EXT_H */
include/linux/page_idle.h+24−10
@@ -13,65 +13,79 @@ · 12 unmodified lines
13 * If there is not enough space to store Idle and Young bits in page flags, use13 * If there is not enough space to store Idle and Young bits in page flags, use
14 * page ext flags instead.14 * page ext flags instead.
15 */15 */
16
17static inline bool folio_test_young(struct folio *folio)16static inline bool folio_test_young(struct folio *folio)
18{17{
19 struct page_ext *page_ext = lookup_page_ext(&folio->page);18 struct page_ext *page_ext = page_ext_get(&folio->page);
19 bool page_young;
20 20
21 if (unlikely(!page_ext))21 if (unlikely(!page_ext))
22 return false;22 return false;
23 23
24 return test_bit(PAGE_EXT_YOUNG, &page_ext->flags);24 page_young = test_bit(PAGE_EXT_YOUNG, &page_ext->flags);
25 page_ext_put(page_ext);
26
27 return page_young;
25}28}
26 29
27static inline void folio_set_young(struct folio *folio)30static inline void folio_set_young(struct folio *folio)
28{31{
29 struct page_ext *page_ext = lookup_page_ext(&folio->page);32 struct page_ext *page_ext = page_ext_get(&folio->page);
30 33
31 if (unlikely(!page_ext))34 if (unlikely(!page_ext))
32 return;35 return;
33 36
34 set_bit(PAGE_EXT_YOUNG, &page_ext->flags);37 set_bit(PAGE_EXT_YOUNG, &page_ext->flags);
38 page_ext_put(page_ext);
35}39}
36 40
37static inline bool folio_test_clear_young(struct folio *folio)41static inline bool folio_test_clear_young(struct folio *folio)
38{42{
39 struct page_ext *page_ext = lookup_page_ext(&folio->page);43 struct page_ext *page_ext = page_ext_get(&folio->page);
44 bool page_young;
40 45
41 if (unlikely(!page_ext))46 if (unlikely(!page_ext))
42 return false;47 return false;
43 48
44 return test_and_clear_bit(PAGE_EXT_YOUNG, &page_ext->flags);49 page_young = test_and_clear_bit(PAGE_EXT_YOUNG, &page_ext->flags);
50 page_ext_put(page_ext);
51
52 return page_young;
45}53}
46 54
47static inline bool folio_test_idle(struct folio *folio)55static inline bool folio_test_idle(struct folio *folio)
48{56{
49 struct page_ext *page_ext = lookup_page_ext(&folio->page);57 struct page_ext *page_ext = page_ext_get(&folio->page);
58 bool page_idle;
50 59
51 if (unlikely(!page_ext))60 if (unlikely(!page_ext))
52 return false;61 return false;
53 62
54 return test_bit(PAGE_EXT_IDLE, &page_ext->flags);63 page_idle = test_bit(PAGE_EXT_IDLE, &page_ext->flags);
64 page_ext_put(page_ext);
65
66 return page_idle;
55}67}
56 68
57static inline void folio_set_idle(struct folio *folio)69static inline void folio_set_idle(struct folio *folio)
58{70{
59 struct page_ext *page_ext = lookup_page_ext(&folio->page);71 struct page_ext *page_ext = page_ext_get(&folio->page);
60 72
61 if (unlikely(!page_ext))73 if (unlikely(!page_ext))
62 return;74 return;
63 75
64 set_bit(PAGE_EXT_IDLE, &page_ext->flags);76 set_bit(PAGE_EXT_IDLE, &page_ext->flags);
77 page_ext_put(page_ext);
65}78}
66 79
67static inline void folio_clear_idle(struct folio *folio)80static inline void folio_clear_idle(struct folio *folio)
68{81{
69 struct page_ext *page_ext = lookup_page_ext(&folio->page);82 struct page_ext *page_ext = page_ext_get(&folio->page);
70 83
71 if (unlikely(!page_ext))84 if (unlikely(!page_ext))
72 return;85 return;
73 86
74 clear_bit(PAGE_EXT_IDLE, &page_ext->flags);87 clear_bit(PAGE_EXT_IDLE, &page_ext->flags);
88 page_ext_put(page_ext);
75}89}
76#endif /* !CONFIG_64BIT */90#endif /* !CONFIG_64BIT */
77 91
include/linux/pageblock-flags.h+4−0
@@ -53,6 +53,10 @@ extern unsigned int pageblock_order; · 52 unmodified lines
53#endif /* CONFIG_HUGETLB_PAGE */53#endif /* CONFIG_HUGETLB_PAGE */
54 54
55#define pageblock_nr_pages (1UL << pageblock_order)55#define pageblock_nr_pages (1UL << pageblock_order)
56#define pageblock_align(pfn) ALIGN((pfn), pageblock_nr_pages)
57#define pageblock_aligned(pfn) IS_ALIGNED((pfn), pageblock_nr_pages)
58#define pageblock_start_pfn(pfn) ALIGN_DOWN((pfn), pageblock_nr_pages)
59#define pageblock_end_pfn(pfn) ALIGN((pfn) + 1, pageblock_nr_pages)
56 60
57/* Forward declaration */61/* Forward declaration */
58struct page;62struct page;
include/linux/pagemap.h+5−9
@@ -718,8 +718,8 @@ static inline struct page *find_subpage(struct page *head, pgoff_t index) · 717 unmodified lines
718 718
719unsigned filemap_get_folios(struct address_space *mapping, pgoff_t *start,719unsigned filemap_get_folios(struct address_space *mapping, pgoff_t *start,
720 pgoff_t end, struct folio_batch *fbatch);720 pgoff_t end, struct folio_batch *fbatch);
721unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start,721unsigned filemap_get_folios_contig(struct address_space *mapping,
722 unsigned int nr_pages, struct page **pages);722 pgoff_t *start, pgoff_t end, struct folio_batch *fbatch);
723unsigned find_get_pages_range_tag(struct address_space *mapping, pgoff_t *index,723unsigned find_get_pages_range_tag(struct address_space *mapping, pgoff_t *index,
724 pgoff_t end, xa_mark_t tag, unsigned int nr_pages,724 pgoff_t end, xa_mark_t tag, unsigned int nr_pages,
725 struct page **pages);725 struct page **pages);
@@ -989,19 +989,16 @@ static inline int lock_page_killable(struct page *page) · 263 unmodified lines
989}989}
990 990
991/*991/*
992 * lock_page_or_retry - Lock the page, unless this would block and the992 * folio_lock_or_retry - Lock the folio, unless this would block and the
993 * caller indicated that it can handle a retry.993 * caller indicated that it can handle a retry.
994 *994 *
995 * Return value and mmap_lock implications depend on flags; see995 * Return value and mmap_lock implications depend on flags; see
996 * __folio_lock_or_retry().996 * __folio_lock_or_retry().
997 */997 */
998static inline bool lock_page_or_retry(struct page *page, struct mm_struct *mm,998static inline bool folio_lock_or_retry(struct folio *folio,
999 unsigned int flags)999 struct mm_struct *mm, unsigned int flags)
1000{1000{
1001 struct folio *folio;
1002 might_sleep();1001 might_sleep();
1003
1004 folio = page_folio(page);
1005 return folio_trylock(folio) || __folio_lock_or_retry(folio, mm, flags);1002 return folio_trylock(folio) || __folio_lock_or_retry(folio, mm, flags);
1006}1003}
1007 1004
@@ -1042,7 +1039,6 @@ static inline int wait_on_page_locked_killable(struct page *page) · 34 unmodified lines
1042 return folio_wait_locked_killable(page_folio(page));1039 return folio_wait_locked_killable(page_folio(page));
1043}1040}
1044 1041
1045int folio_put_wait_locked(struct folio *folio, int state);
1046void wait_on_page_writeback(struct page *page);1042void wait_on_page_writeback(struct page *page);
1047void folio_wait_writeback(struct folio *folio);1043void folio_wait_writeback(struct folio *folio);
1048int folio_wait_writeback_killable(struct folio *folio);1044int folio_wait_writeback_killable(struct folio *folio);
include/linux/pagewalk.h+5−5
@@ -15,12 +15,12 @@ struct mm_walk; · 14 unmodified lines
15 * this handler is required to be able to handle15 * this handler is required to be able to handle
16 * pmd_trans_huge() pmds. They may simply choose to16 * pmd_trans_huge() pmds. They may simply choose to
17 * split_huge_page() instead of handling it explicitly.17 * split_huge_page() instead of handling it explicitly.
18 * @pte_entry: if set, called for each non-empty PTE (lowest-level)18 * @pte_entry: if set, called for each PTE (lowest-level) entry,
19 * entry19 * including empty ones
20 * @pte_hole: if set, called for each hole at all levels,20 * @pte_hole: if set, called for each hole at all levels,
21 * depth is -1 if not known, 0:PGD, 1:P4D, 2:PUD, 3:PMD21 * depth is -1 if not known, 0:PGD, 1:P4D, 2:PUD, 3:PMD.
22 * 4:PTE. Any folded depths (where PTRS_PER_P?D is equal22 * Any folded depths (where PTRS_PER_P?D is equal to 1)
23 * to 1) are skipped.23 * are skipped.
24 * @hugetlb_entry: if set, called for each hugetlb entry24 * @hugetlb_entry: if set, called for each hugetlb entry
25 * @test_walk: caller specific callback function to determine whether25 * @test_walk: caller specific callback function to determine whether
26 * we walk over the current vma or not. Returning 0 means26 * we walk over the current vma or not. Returning 0 means
include/linux/pgtable.h+17−9
@@ -213,7 +213,7 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, · 212 unmodified lines
213#endif213#endif
214 214
215#ifndef __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG215#ifndef __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG
216#ifdef CONFIG_TRANSPARENT_HUGEPAGE216#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)
217static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,217static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
218 unsigned long address,218 unsigned long address,
219 pmd_t *pmdp)219 pmd_t *pmdp)
@@ -234,7 +234,7 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma, · 14 unmodified lines
234 BUILD_BUG();234 BUILD_BUG();
235 return 0;235 return 0;
236}236}
237#endif /* CONFIG_TRANSPARENT_HUGEPAGE */237#endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG */
238#endif238#endif
239 239
240#ifndef __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH240#ifndef __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
@@ -260,6 +260,19 @@ static inline int pmdp_clear_flush_young(struct vm_area_struct *vma, · 19 unmodified lines
260#endif /* CONFIG_TRANSPARENT_HUGEPAGE */260#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
261#endif261#endif
262 262
263#ifndef arch_has_hw_pte_young
264/*
265 * Return whether the accessed bit is supported on the local CPU.
266 *
267 * This stub assumes accessing through an old PTE triggers a page fault.
268 * Architectures that automatically set the access bit should overwrite it.
269 */
270static inline bool arch_has_hw_pte_young(void)
271{
272 return false;
273}
274#endif
275
263#ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR276#ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR
264static inline pte_t ptep_get_and_clear(struct mm_struct *mm,277static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
265 unsigned long address,278 unsigned long address,
@@ -1276,8 +1289,7 @@ static inline int pgd_devmap(pgd_t pgd) · 1010 unmodified lines
1276#endif1289#endif
1277 1290
1278#if !defined(CONFIG_TRANSPARENT_HUGEPAGE) || \1291#if !defined(CONFIG_TRANSPARENT_HUGEPAGE) || \
1279 (defined(CONFIG_TRANSPARENT_HUGEPAGE) && \1292 !defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
1280 !defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD))
1281static inline int pud_trans_huge(pud_t pud)1293static inline int pud_trans_huge(pud_t pud)
1282{1294{
1283 return 0;1295 return 0;
@@ -1598,11 +1610,7 @@ typedef unsigned int pgtbl_mod_mask; · 314 unmodified lines
1598#endif1610#endif
1599 1611
1600#ifndef has_transparent_hugepage1612#ifndef has_transparent_hugepage
1601#ifdef CONFIG_TRANSPARENT_HUGEPAGE1613#define has_transparent_hugepage() IS_BUILTIN(CONFIG_TRANSPARENT_HUGEPAGE)
1602#define has_transparent_hugepage() 1
1603#else
1604#define has_transparent_hugepage() 0
1605#endif
1606#endif1614#endif
1607 1615
1608/*1616/*
include/linux/rmap.h+62−11
@@ -166,7 +166,7 @@ static inline void anon_vma_merge(struct vm_area_struct *vma, · 165 unmodified lines
166 unlink_anon_vmas(next);166 unlink_anon_vmas(next);
167}167}
168 168
169struct anon_vma *page_get_anon_vma(struct page *page);169struct anon_vma *folio_get_anon_vma(struct folio *folio);
170 170
171/* RMAP flags, currently only relevant for some anon rmap operations. */171/* RMAP flags, currently only relevant for some anon rmap operations. */
172typedef int __bitwise rmap_t;172typedef int __bitwise rmap_t;
@@ -270,7 +270,7 @@ dup: · 97 unmodified lines
270 * @page: the exclusive anonymous page to try marking possibly shared270 * @page: the exclusive anonymous page to try marking possibly shared
271 *271 *
272 * The caller needs to hold the PT lock and has to have the page table entry272 * The caller needs to hold the PT lock and has to have the page table entry
273 * cleared/invalidated+flushed, to properly sync against GUP-fast.273 * cleared/invalidated.
274 *274 *
275 * This is similar to page_try_dup_anon_rmap(), however, not used during fork()275 * This is similar to page_try_dup_anon_rmap(), however, not used during fork()
276 * to duplicate a mapping, but instead to prepare for KSM or temporarily276 * to duplicate a mapping, but instead to prepare for KSM or temporarily
@@ -286,12 +286,68 @@ static inline int page_try_share_anon_rmap(struct page *page) · 9 unmodified lines
286{286{
287 VM_BUG_ON_PAGE(!PageAnon(page) || !PageAnonExclusive(page), page);287 VM_BUG_ON_PAGE(!PageAnon(page) || !PageAnonExclusive(page), page);
288 288
289 /* See page_try_dup_anon_rmap(). */289 /* device private pages cannot get pinned via GUP. */
290 if (likely(!is_device_private_page(page) &&290 if (unlikely(is_device_private_page(page))) {
291 unlikely(page_maybe_dma_pinned(page))))291 ClearPageAnonExclusive(page);
292 return -EBUSY;292 return 0;
293 }
294
295 /*
296 * We have to make sure that when we clear PageAnonExclusive, that
297 * the page is not pinned and that concurrent GUP-fast won't succeed in
298 * concurrently pinning the page.
299 *
300 * Conceptually, PageAnonExclusive clearing consists of:
301 * (A1) Clear PTE
302 * (A2) Check if the page is pinned; back off if so.
303 * (A3) Clear PageAnonExclusive
304 * (A4) Restore PTE (optional, but certainly not writable)
305 *
306 * When clearing PageAnonExclusive, we cannot possibly map the page
307 * writable again, because anon pages that may be shared must never
308 * be writable. So in any case, if the PTE was writable it cannot
309 * be writable anymore afterwards and there would be a PTE change. Only
310 * if the PTE wasn't writable, there might not be a PTE change.
311 *
312 * Conceptually, GUP-fast pinning of an anon page consists of:
313 * (B1) Read the PTE
314 * (B2) FOLL_WRITE: check if the PTE is not writable; back off if so.
315 * (B3) Pin the mapped page
316 * (B4) Check if the PTE changed by re-reading it; back off if so.
317 * (B5) If the original PTE is not writable, check if
318 * PageAnonExclusive is not set; back off if so.
319 *
320 * If the PTE was writable, we only have to make sure that GUP-fast
321 * observes a PTE change and properly backs off.
322 *
323 * If the PTE was not writable, we have to make sure that GUP-fast either
324 * detects a (temporary) PTE change or that PageAnonExclusive is cleared
325 * and properly backs off.
326 *
327 * Consequently, when clearing PageAnonExclusive(), we have to make
328 * sure that (A1), (A2)/(A3) and (A4) happen in the right memory
329 * order. In GUP-fast pinning code, we have to make sure that (B3),(B4)
330 * and (B5) happen in the right memory order.
331 *
332 * We assume that there might not be a memory barrier after
333 * clearing/invalidating the PTE (A1) and before restoring the PTE (A4),
334 * so we use explicit ones here.
335 */
293 336
337 /* Paired with the memory barrier in try_grab_folio(). */
338 if (IS_ENABLED(CONFIG_HAVE_FAST_GUP))
339 smp_mb();
340
341 if (unlikely(page_maybe_dma_pinned(page)))
342 return -EBUSY;
294 ClearPageAnonExclusive(page);343 ClearPageAnonExclusive(page);
344
345 /*
346 * This is conceptually a smp_wmb() paired with the smp_rmb() in
347 * gup_must_unshare().
348 */
349 if (IS_ENABLED(CONFIG_HAVE_FAST_GUP))
350 smp_mb__after_atomic();
295 return 0;351 return 0;
296}352}
297 353
@@ -405,13 +461,8 @@ struct rmap_walk_control { · 107 unmodified lines
405 461
406void rmap_walk(struct folio *folio, struct rmap_walk_control *rwc);462void rmap_walk(struct folio *folio, struct rmap_walk_control *rwc);
407void rmap_walk_locked(struct folio *folio, struct rmap_walk_control *rwc);463void rmap_walk_locked(struct folio *folio, struct rmap_walk_control *rwc);
408
409/*
410 * Called by memory-failure.c to kill processes.
411 */
412struct anon_vma *folio_lock_anon_vma_read(struct folio *folio,464struct anon_vma *folio_lock_anon_vma_read(struct folio *folio,
413 struct rmap_walk_control *rwc);465 struct rmap_walk_control *rwc);
414void page_unlock_anon_vma_read(struct anon_vma *anon_vma);
415 466
416#else /* !CONFIG_MMU */467#else /* !CONFIG_MMU */
417 468
include/linux/sched.h+13−1
@@ -14,6 +14,7 @@ · 13 unmodified lines
14#include <linux/pid.h>14#include <linux/pid.h>
15#include <linux/sem.h>15#include <linux/sem.h>
16#include <linux/shm.h>16#include <linux/shm.h>
17#include <linux/kmsan_types.h>
17#include <linux/mutex.h>18#include <linux/mutex.h>
18#include <linux/plist.h>19#include <linux/plist.h>
19#include <linux/hrtimer.h>20#include <linux/hrtimer.h>
@@ -870,7 +871,6 @@ struct task_struct { · 850 unmodified lines
870 struct mm_struct *active_mm;871 struct mm_struct *active_mm;
871 872
872 /* Per-thread vma caching: */873 /* Per-thread vma caching: */
873 struct vmacache vmacache;
874 874
875#ifdef SPLIT_RSS_COUNTING875#ifdef SPLIT_RSS_COUNTING
876 struct task_rss_stat rss_stat;876 struct task_rss_stat rss_stat;
@@ -923,6 +923,10 @@ struct task_struct { · 46 unmodified lines
923#ifdef CONFIG_MEMCG923#ifdef CONFIG_MEMCG
924 unsigned in_user_fault:1;924 unsigned in_user_fault:1;
925#endif925#endif
926#ifdef CONFIG_LRU_GEN
927 /* whether the LRU algorithm may apply to this access */
928 unsigned in_lru_fault:1;
929#endif
926#ifdef CONFIG_COMPAT_BRK930#ifdef CONFIG_COMPAT_BRK
927 unsigned brk_randomized:1;931 unsigned brk_randomized:1;
928#endif932#endif
@@ -953,6 +957,10 @@ struct task_struct { · 24 unmodified lines
953#ifdef CONFIG_CPU_SUP_INTEL957#ifdef CONFIG_CPU_SUP_INTEL
954 unsigned reported_split_lock:1;958 unsigned reported_split_lock:1;
955#endif959#endif
960#ifdef CONFIG_TASK_DELAY_ACCT
961 /* delay due to memory thrashing */
962 unsigned in_thrashing:1;
963#endif
956 964
957 unsigned long atomic_flags; /* Flags requiring atomic access. */965 unsigned long atomic_flags; /* Flags requiring atomic access. */
958 966
@@ -1364,6 +1372,10 @@ struct task_struct { · 405 unmodified lines
1364#endif1372#endif
1365#endif1373#endif
1366 1374
1375#ifdef CONFIG_KMSAN
1376 struct kmsan_ctx kmsan_ctx;
1377#endif
1378
1367#if IS_ENABLED(CONFIG_KUNIT)1379#if IS_ENABLED(CONFIG_KUNIT)
1368 struct kunit *kunit_test;1380 struct kunit *kunit_test;
1369#endif1381#endif
include/linux/sched/coredump.h+3−4
@@ -71,9 +71,8 @@ static inline int get_dumpable(struct mm_struct *mm) · 70 unmodified lines
71#define MMF_UNSTABLE 22 /* mm is unstable for copy_from_user */71#define MMF_UNSTABLE 22 /* mm is unstable for copy_from_user */
72#define MMF_HUGE_ZERO_PAGE 23 /* mm has ever used the global huge zero page */72#define MMF_HUGE_ZERO_PAGE 23 /* mm has ever used the global huge zero page */
73#define MMF_DISABLE_THP 24 /* disable THP for all VMAs */73#define MMF_DISABLE_THP 24 /* disable THP for all VMAs */
74#define MMF_OOM_VICTIM 25 /* mm is the oom victim */74#define MMF_OOM_REAP_QUEUED 25 /* mm was queued for oom_reaper */
75#define MMF_OOM_REAP_QUEUED 26 /* mm was queued for oom_reaper */75#define MMF_MULTIPROCESS 26 /* mm is shared between processes */
76#define MMF_MULTIPROCESS 27 /* mm is shared between processes */
77/*76/*
78 * MMF_HAS_PINNED: Whether this mm has pinned any pages. This can be either77 * MMF_HAS_PINNED: Whether this mm has pinned any pages. This can be either
79 * replaced in the future by mm.pinned_vm when it becomes stable, or grow into78 * replaced in the future by mm.pinned_vm when it becomes stable, or grow into
@@ -81,7 +80,7 @@ static inline int get_dumpable(struct mm_struct *mm) · 1 unmodified line
81 * pinned pages were unpinned later on, we'll still keep this bit set for the80 * pinned pages were unpinned later on, we'll still keep this bit set for the
82 * lifecycle of this mm, just for simplicity.81 * lifecycle of this mm, just for simplicity.
83 */82 */
84#define MMF_HAS_PINNED 28 /* FOLL_PIN has run, never cleared */83#define MMF_HAS_PINNED 27 /* FOLL_PIN has run, never cleared */
85#define MMF_DISABLE_THP_MASK (1 << MMF_DISABLE_THP)84#define MMF_DISABLE_THP_MASK (1 << MMF_DISABLE_THP)
86 85
87#define MMF_INIT_MASK (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK |\86#define MMF_INIT_MASK (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK |\
include/linux/sched/sysctl.h+1−0
@@ -27,6 +27,7 @@ enum sched_tunable_scaling { · 26 unmodified lines
27 27
28#ifdef CONFIG_NUMA_BALANCING28#ifdef CONFIG_NUMA_BALANCING
29extern int sysctl_numa_balancing_mode;29extern int sysctl_numa_balancing_mode;
30extern unsigned int sysctl_numa_balancing_promote_rate_limit;
30#else31#else
31#define sysctl_numa_balancing_mode 032#define sysctl_numa_balancing_mode 0
32#endif33#endif
include/linux/shmem_fs.h+9−7
@@ -92,17 +92,19 @@ extern struct page *shmem_read_mapping_page_gfp(struct address_space *mapping, · 91 unmodified lines
92extern void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end);92extern void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end);
93int shmem_unuse(unsigned int type);93int shmem_unuse(unsigned int type);
94 94
95extern bool shmem_is_huge(struct vm_area_struct *vma,95extern bool shmem_is_huge(struct vm_area_struct *vma, struct inode *inode,
96 struct inode *inode, pgoff_t index);96 pgoff_t index, bool shmem_huge_force);
97static inline bool shmem_huge_enabled(struct vm_area_struct *vma)97static inline bool shmem_huge_enabled(struct vm_area_struct *vma,
98 bool shmem_huge_force)
98{99{
99 return shmem_is_huge(vma, file_inode(vma->vm_file), vma->vm_pgoff);100 return shmem_is_huge(vma, file_inode(vma->vm_file), vma->vm_pgoff,
101 shmem_huge_force);
100}102}
101extern unsigned long shmem_swap_usage(struct vm_area_struct *vma);103extern unsigned long shmem_swap_usage(struct vm_area_struct *vma);
102extern unsigned long shmem_partial_swap_usage(struct address_space *mapping,104extern unsigned long shmem_partial_swap_usage(struct address_space *mapping,
103 pgoff_t start, pgoff_t end);105 pgoff_t start, pgoff_t end);
104 106
105/* Flag allocation requirements to shmem_getpage */107/* Flag allocation requirements to shmem_get_folio */
106enum sgp_type {108enum sgp_type {
107 SGP_READ, /* don't exceed i_size, don't allocate page */109 SGP_READ, /* don't exceed i_size, don't allocate page */
108 SGP_NOALLOC, /* similar, but fail on hole or use fallocated page */110 SGP_NOALLOC, /* similar, but fail on hole or use fallocated page */
@@ -111,8 +113,8 @@ enum sgp_type { · 2 unmodified lines
111 SGP_FALLOC, /* like SGP_WRITE, but make existing page Uptodate */113 SGP_FALLOC, /* like SGP_WRITE, but make existing page Uptodate */
112};114};
113 115
114extern int shmem_getpage(struct inode *inode, pgoff_t index,116int shmem_get_folio(struct inode *inode, pgoff_t index, struct folio **foliop,
115 struct page **pagep, enum sgp_type sgp);117 enum sgp_type sgp);
116 118
117static inline struct page *shmem_read_mapping_page(119static inline struct page *shmem_read_mapping_page(
118 struct address_space *mapping, pgoff_t index)120 struct address_space *mapping, pgoff_t index)
include/linux/slab.h+7−1
@@ -108,7 +108,7 @@ · 107 unmodified lines
108# define SLAB_ACCOUNT 0108# define SLAB_ACCOUNT 0
109#endif109#endif
110 110
111#ifdef CONFIG_KASAN111#ifdef CONFIG_KASAN_GENERIC
112#define SLAB_KASAN ((slab_flags_t __force)0x08000000U)112#define SLAB_KASAN ((slab_flags_t __force)0x08000000U)
113#else113#else
114#define SLAB_KASAN 0114#define SLAB_KASAN 0
@@ -121,6 +121,12 @@ · 6 unmodified lines
121 */121 */
122#define SLAB_NO_USER_FLAGS ((slab_flags_t __force)0x10000000U)122#define SLAB_NO_USER_FLAGS ((slab_flags_t __force)0x10000000U)
123 123
124#ifdef CONFIG_KFENCE
125#define SLAB_SKIP_KFENCE ((slab_flags_t __force)0x20000000U)
126#else
127#define SLAB_SKIP_KFENCE 0
128#endif
129
124/* The following flags affect the page allocator grouping pages by mobility */130/* The following flags affect the page allocator grouping pages by mobility */
125/* Objects are reclaimable */131/* Objects are reclaimable */
126#define SLAB_RECLAIM_ACCOUNT ((slab_flags_t __force)0x00020000U)132#define SLAB_RECLAIM_ACCOUNT ((slab_flags_t __force)0x00020000U)
include/linux/stackdepot.h+8−0
@@ -14,9 +14,15 @@ · 13 unmodified lines
14#include <linux/gfp.h>14#include <linux/gfp.h>
15 15
16typedef u32 depot_stack_handle_t;16typedef u32 depot_stack_handle_t;
17/*
18 * Number of bits in the handle that stack depot doesn't use. Users may store
19 * information in them.
20 */
21#define STACK_DEPOT_EXTRA_BITS 5
17 22
18depot_stack_handle_t __stack_depot_save(unsigned long *entries,23depot_stack_handle_t __stack_depot_save(unsigned long *entries,
19 unsigned int nr_entries,24 unsigned int nr_entries,
25 unsigned int extra_bits,
20 gfp_t gfp_flags, bool can_alloc);26 gfp_t gfp_flags, bool can_alloc);
21 27
22/*28/*
@@ -59,6 +65,8 @@ depot_stack_handle_t stack_depot_save(unsigned long *entries, · 36 unmodified lines
59unsigned int stack_depot_fetch(depot_stack_handle_t handle,65unsigned int stack_depot_fetch(depot_stack_handle_t handle,
60 unsigned long **entries);66 unsigned long **entries);
61 67
68unsigned int stack_depot_get_extra_bits(depot_stack_handle_t handle);
69
62int stack_depot_snprint(depot_stack_handle_t handle, char *buf, size_t size,70int stack_depot_snprint(depot_stack_handle_t handle, char *buf, size_t size,
63 int spaces);71 int spaces);
64 72
include/linux/swap.h+25−16
@@ -162,6 +162,10 @@ union swap_header { · 161 unmodified lines
162 */162 */
163struct reclaim_state {163struct reclaim_state {
164 unsigned long reclaimed_slab;164 unsigned long reclaimed_slab;
165#ifdef CONFIG_LRU_GEN
166 /* per-thread mm walk data */
167 struct lru_gen_mm_walk *mm_walk;
168#endif
165};169};
166 170
167#ifdef __KERNEL__171#ifdef __KERNEL__
@@ -351,6 +355,11 @@ static inline swp_entry_t folio_swap_entry(struct folio *folio) · 183 unmodified lines
351 return entry;355 return entry;
352}356}
353 357
358static inline void folio_set_swap_entry(struct folio *folio, swp_entry_t entry)
359{
360 folio->private = (void *)entry.val;
361}
362
354/* linux/mm/workingset.c */363/* linux/mm/workingset.c */
355void workingset_age_nonresident(struct lruvec *lruvec, unsigned long nr_pages);364void workingset_age_nonresident(struct lruvec *lruvec, unsigned long nr_pages);
356void *workingset_eviction(struct folio *folio, struct mem_cgroup *target_memcg);365void *workingset_eviction(struct folio *folio, struct mem_cgroup *target_memcg);
@@ -375,11 +384,11 @@ extern unsigned long totalreserve_pages; · 18 unmodified lines
375 384
376 385
377/* linux/mm/swap.c */386/* linux/mm/swap.c */
378extern void lru_note_cost(struct lruvec *lruvec, bool file,387void lru_note_cost(struct lruvec *lruvec, bool file, unsigned int nr_pages);
379 unsigned int nr_pages);388void lru_note_cost_folio(struct folio *);
380extern void lru_note_cost_folio(struct folio *);389void folio_add_lru(struct folio *);
381extern void folio_add_lru(struct folio *);390void folio_add_lru_vma(struct folio *, struct vm_area_struct *);
382extern void lru_cache_add(struct page *);391void lru_cache_add(struct page *);
383void mark_page_accessed(struct page *);392void mark_page_accessed(struct page *);
384void folio_mark_accessed(struct folio *);393void folio_mark_accessed(struct folio *);
385 394
@@ -481,7 +490,8 @@ static inline long get_nr_swap_pages(void) · 95 unmodified lines
481 490
482extern void si_swapinfo(struct sysinfo *);491extern void si_swapinfo(struct sysinfo *);
483swp_entry_t folio_alloc_swap(struct folio *folio);492swp_entry_t folio_alloc_swap(struct folio *folio);
484extern void put_swap_page(struct page *page, swp_entry_t entry);493bool folio_free_swap(struct folio *folio);
494void put_swap_folio(struct folio *folio, swp_entry_t entry);
485extern swp_entry_t get_swap_page_of_type(int);495extern swp_entry_t get_swap_page_of_type(int);
486extern int get_swap_pages(int n, swp_entry_t swp_entries[], int entry_size);496extern int get_swap_pages(int n, swp_entry_t swp_entries[], int entry_size);
487extern int add_swap_count_continuation(swp_entry_t, gfp_t);497extern int add_swap_count_continuation(swp_entry_t, gfp_t);
@@ -500,7 +510,6 @@ extern int __swp_swapcount(swp_entry_t entry); · 12 unmodified lines
500extern int swp_swapcount(swp_entry_t entry);510extern int swp_swapcount(swp_entry_t entry);
501extern struct swap_info_struct *page_swap_info(struct page *);511extern struct swap_info_struct *page_swap_info(struct page *);
502extern struct swap_info_struct *swp_swap_info(swp_entry_t entry);512extern struct swap_info_struct *swp_swap_info(swp_entry_t entry);
503extern int try_to_free_swap(struct page *);
504struct backing_dev_info;513struct backing_dev_info;
505extern int init_swap_address_space(unsigned int type, unsigned long nr_pages);514extern int init_swap_address_space(unsigned int type, unsigned long nr_pages);
506extern void exit_swap_address_space(unsigned int type);515extern void exit_swap_address_space(unsigned int type);
@@ -566,7 +575,7 @@ static inline void swap_free(swp_entry_t swp) · 59 unmodified lines
566{575{
567}576}
568 577
569static inline void put_swap_page(struct page *page, swp_entry_t swp)578static inline void put_swap_folio(struct folio *folio, swp_entry_t swp)
570{579{
571}580}
572 581
@@ -585,11 +594,6 @@ static inline int swp_swapcount(swp_entry_t entry) · 12 unmodified lines
585 return 0;594 return 0;
586}595}
587 596
588static inline int try_to_free_swap(struct page *page)
589{
590 return 0;
591}
592
593static inline swp_entry_t folio_alloc_swap(struct folio *folio)597static inline swp_entry_t folio_alloc_swap(struct folio *folio)
594{598{
595 swp_entry_t entry;599 swp_entry_t entry;
@@ -597,6 +601,11 @@ static inline swp_entry_t folio_alloc_swap(struct folio *folio) · 1 unmodified line
597 return entry;601 return entry;
598}602}
599 603
604static inline bool folio_free_swap(struct folio *folio)
605{
606 return false;
607}
608
600static inline int add_swap_extent(struct swap_info_struct *sis,609static inline int add_swap_extent(struct swap_info_struct *sis,
601 unsigned long start_page,610 unsigned long start_page,
602 unsigned long nr_pages, sector_t start_block)611 unsigned long nr_pages, sector_t start_block)
@@ -657,7 +666,7 @@ static inline void folio_throttle_swaprate(struct folio *folio, gfp_t gfp) · 54 unmodified lines
657 cgroup_throttle_swaprate(&folio->page, gfp);666 cgroup_throttle_swaprate(&folio->page, gfp);
658}667}
659 668
660#ifdef CONFIG_MEMCG_SWAP669#if defined(CONFIG_MEMCG) && defined(CONFIG_SWAP)
661void mem_cgroup_swapout(struct folio *folio, swp_entry_t entry);670void mem_cgroup_swapout(struct folio *folio, swp_entry_t entry);
662int __mem_cgroup_try_charge_swap(struct folio *folio, swp_entry_t entry);671int __mem_cgroup_try_charge_swap(struct folio *folio, swp_entry_t entry);
663static inline int mem_cgroup_try_charge_swap(struct folio *folio,672static inline int mem_cgroup_try_charge_swap(struct folio *folio,
@@ -677,7 +686,7 @@ static inline void mem_cgroup_uncharge_swap(swp_entry_t entry, unsigned int nr_p · 13 unmodified lines
677}686}
678 687
679extern long mem_cgroup_get_nr_swap_pages(struct mem_cgroup *memcg);688extern long mem_cgroup_get_nr_swap_pages(struct mem_cgroup *memcg);
680extern bool mem_cgroup_swap_full(struct page *page);689extern bool mem_cgroup_swap_full(struct folio *folio);
681#else690#else
682static inline void mem_cgroup_swapout(struct folio *folio, swp_entry_t entry)691static inline void mem_cgroup_swapout(struct folio *folio, swp_entry_t entry)
683{692{
@@ -699,7 +708,7 @@ static inline long mem_cgroup_get_nr_swap_pages(struct mem_cgroup *memcg) · 15 unmodified lines
699 return get_nr_swap_pages();708 return get_nr_swap_pages();
700}709}
701 710
702static inline bool mem_cgroup_swap_full(struct page *page)711static inline bool mem_cgroup_swap_full(struct folio *folio)
703{712{
704 return vm_swap_full();713 return vm_swap_full();
705}714}
include/linux/swap_cgroup.h+2−2
@@ -4,7 +4,7 @@ · 3 unmodified lines
4 4
5#include <linux/swap.h>5#include <linux/swap.h>
6 6
7#ifdef CONFIG_MEMCG_SWAP7#if defined(CONFIG_MEMCG) && defined(CONFIG_SWAP)
8 8
9extern unsigned short swap_cgroup_cmpxchg(swp_entry_t ent,9extern unsigned short swap_cgroup_cmpxchg(swp_entry_t ent,
10 unsigned short old, unsigned short new);10 unsigned short old, unsigned short new);
@@ -40,6 +40,6 @@ static inline void swap_cgroup_swapoff(int type) · 29 unmodified lines
40 return;40 return;
41}41}
42 42
43#endif /* CONFIG_MEMCG_SWAP */43#endif
44 44
45#endif /* __LINUX_SWAP_CGROUP_H */45#endif /* __LINUX_SWAP_CGROUP_H */
include/linux/swapfile.h+6−1
@@ -8,6 +8,11 @@ · 7 unmodified lines
8 */8 */
9extern struct swap_info_struct *swap_info[];9extern struct swap_info_struct *swap_info[];
10extern unsigned long generic_max_swapfile_size(void);10extern unsigned long generic_max_swapfile_size(void);
11extern unsigned long max_swapfile_size(void);11unsigned long arch_max_swapfile_size(void);
12
13/* Maximum swapfile size supported for the arch (not inclusive). */
14extern unsigned long swapfile_maximum_size;
15/* Whether swap migration entry supports storing A/D bits for the arch */
16extern bool swap_migration_ad_supported;
12 17
13#endif /* _LINUX_SWAPFILE_H */18#endif /* _LINUX_SWAPFILE_H */
include/linux/swapops.h+131−19
@@ -8,6 +8,10 @@ · 7 unmodified lines
8 8
9#ifdef CONFIG_MMU9#ifdef CONFIG_MMU
10 10
11#ifdef CONFIG_SWAP
12#include <linux/swapfile.h>
13#endif /* CONFIG_SWAP */
14
11/*15/*
12 * swapcache pages are stored in the swapper_space radix tree. We want to16 * swapcache pages are stored in the swapper_space radix tree. We want to
13 * get good packing density in that tree, so the index should be dense in17 * get good packing density in that tree, so the index should be dense in
@@ -23,6 +27,45 @@ · 9 unmodified lines
23#define SWP_TYPE_SHIFT (BITS_PER_XA_VALUE - MAX_SWAPFILES_SHIFT)27#define SWP_TYPE_SHIFT (BITS_PER_XA_VALUE - MAX_SWAPFILES_SHIFT)
24#define SWP_OFFSET_MASK ((1UL << SWP_TYPE_SHIFT) - 1)28#define SWP_OFFSET_MASK ((1UL << SWP_TYPE_SHIFT) - 1)
25 29
30/*
31 * Definitions only for PFN swap entries (see is_pfn_swap_entry()). To
32 * store PFN, we only need SWP_PFN_BITS bits. Each of the pfn swap entries
33 * can use the extra bits to store other information besides PFN.
34 */
35#ifdef MAX_PHYSMEM_BITS
36#define SWP_PFN_BITS (MAX_PHYSMEM_BITS - PAGE_SHIFT)
37#else /* MAX_PHYSMEM_BITS */
38#define SWP_PFN_BITS (BITS_PER_LONG - PAGE_SHIFT)
39#endif /* MAX_PHYSMEM_BITS */
40#define SWP_PFN_MASK (BIT(SWP_PFN_BITS) - 1)
41
42/**
43 * Migration swap entry specific bitfield definitions. Layout:
44 *
45 * |----------+--------------------|
46 * | swp_type | swp_offset |
47 * |----------+--------+-+-+-------|
48 * | | resv |D|A| PFN |
49 * |----------+--------+-+-+-------|
50 *
51 * @SWP_MIG_YOUNG_BIT: Whether the page used to have young bit set (bit A)
52 * @SWP_MIG_DIRTY_BIT: Whether the page used to have dirty bit set (bit D)
53 *
54 * Note: A/D bits will be stored in migration entries iff there're enough
55 * free bits in arch specific swp offset. By default we'll ignore A/D bits
56 * when migrating a page. Please refer to migration_entry_supports_ad()
57 * for more information. If there're more bits besides PFN and A/D bits,
58 * they should be reserved and always be zeros.
59 */
60#define SWP_MIG_YOUNG_BIT (SWP_PFN_BITS)
61#define SWP_MIG_DIRTY_BIT (SWP_PFN_BITS + 1)
62#define SWP_MIG_TOTAL_BITS (SWP_PFN_BITS + 2)
63
64#define SWP_MIG_YOUNG BIT(SWP_MIG_YOUNG_BIT)
65#define SWP_MIG_DIRTY BIT(SWP_MIG_DIRTY_BIT)
66
67static inline bool is_pfn_swap_entry(swp_entry_t entry);
68
26/* Clear all flags but only keep swp_entry_t related information */69/* Clear all flags but only keep swp_entry_t related information */
27static inline pte_t pte_swp_clear_flags(pte_t pte)70static inline pte_t pte_swp_clear_flags(pte_t pte)
28{71{
@@ -64,6 +107,17 @@ static inline pgoff_t swp_offset(swp_entry_t entry) · 35 unmodified lines
64 return entry.val & SWP_OFFSET_MASK;107 return entry.val & SWP_OFFSET_MASK;
65}108}
66 109
110/*
111 * This should only be called upon a pfn swap entry to get the PFN stored
112 * in the swap entry. Please refers to is_pfn_swap_entry() for definition
113 * of pfn swap entry.
114 */
115static inline unsigned long swp_offset_pfn(swp_entry_t entry)
116{
117 VM_BUG_ON(!is_pfn_swap_entry(entry));
118 return swp_offset(entry) & SWP_PFN_MASK;
119}
120
67/* check whether a pte points to a swap entry */121/* check whether a pte points to a swap entry */
68static inline int is_swap_pte(pte_t pte)122static inline int is_swap_pte(pte_t pte)
69{123{
@@ -240,6 +294,52 @@ static inline swp_entry_t make_writable_migration_entry(pgoff_t offset) · 170 unmodified lines
240 return swp_entry(SWP_MIGRATION_WRITE, offset);294 return swp_entry(SWP_MIGRATION_WRITE, offset);
241}295}
242 296
297/*
298 * Returns whether the host has large enough swap offset field to support
299 * carrying over pgtable A/D bits for page migrations. The result is
300 * pretty much arch specific.
301 */
302static inline bool migration_entry_supports_ad(void)
303{
304#ifdef CONFIG_SWAP
305 return swap_migration_ad_supported;
306#else /* CONFIG_SWAP */
307 return false;
308#endif /* CONFIG_SWAP */
309}
310
311static inline swp_entry_t make_migration_entry_young(swp_entry_t entry)
312{
313 if (migration_entry_supports_ad())
314 return swp_entry(swp_type(entry),
315 swp_offset(entry) | SWP_MIG_YOUNG);
316 return entry;
317}
318
319static inline bool is_migration_entry_young(swp_entry_t entry)
320{
321 if (migration_entry_supports_ad())
322 return swp_offset(entry) & SWP_MIG_YOUNG;
323 /* Keep the old behavior of aging page after migration */
324 return false;
325}
326
327static inline swp_entry_t make_migration_entry_dirty(swp_entry_t entry)
328{
329 if (migration_entry_supports_ad())
330 return swp_entry(swp_type(entry),
331 swp_offset(entry) | SWP_MIG_DIRTY);
332 return entry;
333}
334
335static inline bool is_migration_entry_dirty(swp_entry_t entry)
336{
337 if (migration_entry_supports_ad())
338 return swp_offset(entry) & SWP_MIG_DIRTY;
339 /* Keep the old behavior of clean page after migration */
340 return false;
341}
342
243extern void __migration_entry_wait(struct mm_struct *mm, pte_t *ptep,343extern void __migration_entry_wait(struct mm_struct *mm, pte_t *ptep,
244 spinlock_t *ptl);344 spinlock_t *ptl);
245extern void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,345extern void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd,
@@ -247,8 +347,8 @@ extern void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, · 1 unmodified line
247#ifdef CONFIG_HUGETLB_PAGE347#ifdef CONFIG_HUGETLB_PAGE
248extern void __migration_entry_wait_huge(pte_t *ptep, spinlock_t *ptl);348extern void __migration_entry_wait_huge(pte_t *ptep, spinlock_t *ptl);
249extern void migration_entry_wait_huge(struct vm_area_struct *vma, pte_t *pte);349extern void migration_entry_wait_huge(struct vm_area_struct *vma, pte_t *pte);
250#endif350#endif /* CONFIG_HUGETLB_PAGE */
251#else351#else /* CONFIG_MIGRATION */
252static inline swp_entry_t make_readable_migration_entry(pgoff_t offset)352static inline swp_entry_t make_readable_migration_entry(pgoff_t offset)
253{353{
254 return swp_entry(0, 0);354 return swp_entry(0, 0);
@@ -276,7 +376,7 @@ static inline void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, · 21 unmodified lines
276#ifdef CONFIG_HUGETLB_PAGE376#ifdef CONFIG_HUGETLB_PAGE
277static inline void __migration_entry_wait_huge(pte_t *ptep, spinlock_t *ptl) { }377static inline void __migration_entry_wait_huge(pte_t *ptep, spinlock_t *ptl) { }
278static inline void migration_entry_wait_huge(struct vm_area_struct *vma, pte_t *pte) { }378static inline void migration_entry_wait_huge(struct vm_area_struct *vma, pte_t *pte) { }
279#endif379#endif /* CONFIG_HUGETLB_PAGE */
280static inline int is_writable_migration_entry(swp_entry_t entry)380static inline int is_writable_migration_entry(swp_entry_t entry)
281{381{
282 return 0;382 return 0;
@@ -286,7 +386,26 @@ static inline int is_readable_migration_entry(swp_entry_t entry) · 3 unmodified lines
286 return 0;386 return 0;
287}387}
288 388
289#endif389static inline swp_entry_t make_migration_entry_young(swp_entry_t entry)
390{
391 return entry;
392}
393
394static inline bool is_migration_entry_young(swp_entry_t entry)
395{
396 return false;
397}
398
399static inline swp_entry_t make_migration_entry_dirty(swp_entry_t entry)
400{
401 return entry;
402}
403
404static inline bool is_migration_entry_dirty(swp_entry_t entry)
405{
406 return false;
407}
408#endif /* CONFIG_MIGRATION */
290 409
291typedef unsigned long pte_marker;410typedef unsigned long pte_marker;
292 411
@@ -369,7 +488,7 @@ static inline int pte_none_mostly(pte_t pte) · 76 unmodified lines
369 488
370static inline struct page *pfn_swap_entry_to_page(swp_entry_t entry)489static inline struct page *pfn_swap_entry_to_page(swp_entry_t entry)
371{490{
372 struct page *p = pfn_to_page(swp_offset(entry));491 struct page *p = pfn_to_page(swp_offset_pfn(entry));
373 492
374 /*493 /*
375 * Any use of migration entries may only occur while the494 * Any use of migration entries may only occur while the
@@ -387,6 +506,9 @@ static inline struct page *pfn_swap_entry_to_page(swp_entry_t entry) · 11 unmodified lines
387 */506 */
388static inline bool is_pfn_swap_entry(swp_entry_t entry)507static inline bool is_pfn_swap_entry(swp_entry_t entry)
389{508{
509 /* Make sure the swp offset can always store the needed fields */
510 BUILD_BUG_ON(SWP_TYPE_SHIFT < SWP_PFN_BITS);
511
390 return is_migration_entry(entry) || is_device_private_entry(entry) ||512 return is_migration_entry(entry) || is_device_private_entry(entry) ||
391 is_device_exclusive_entry(entry);513 is_device_exclusive_entry(entry);
392}514}
@@ -426,7 +548,7 @@ static inline int is_pmd_migration_entry(pmd_t pmd) · 33 unmodified lines
426{548{
427 return is_swap_pmd(pmd) && is_migration_entry(pmd_to_swp_entry(pmd));549 return is_swap_pmd(pmd) && is_migration_entry(pmd_to_swp_entry(pmd));
428}550}
429#else551#else /* CONFIG_ARCH_ENABLE_THP_MIGRATION */
430static inline int set_pmd_migration_entry(struct page_vma_mapped_walk *pvmw,552static inline int set_pmd_migration_entry(struct page_vma_mapped_walk *pvmw,
431 struct page *page)553 struct page *page)
432{554{
@@ -455,7 +577,7 @@ static inline int is_pmd_migration_entry(pmd_t pmd) · 22 unmodified lines
455{577{
456 return 0;578 return 0;
457}579}
458#endif580#endif /* CONFIG_ARCH_ENABLE_THP_MIGRATION */
459 581
460#ifdef CONFIG_MEMORY_FAILURE582#ifdef CONFIG_MEMORY_FAILURE
461 583
@@ -475,27 +597,17 @@ static inline int is_hwpoison_entry(swp_entry_t entry) · 13 unmodified lines
475 return swp_type(entry) == SWP_HWPOISON;597 return swp_type(entry) == SWP_HWPOISON;
476}598}
477 599
478static inline unsigned long hwpoison_entry_to_pfn(swp_entry_t entry)
479{
480 return swp_offset(entry);
481}
482
483static inline void num_poisoned_pages_inc(void)600static inline void num_poisoned_pages_inc(void)
484{601{
485 atomic_long_inc(&num_poisoned_pages);602 atomic_long_inc(&num_poisoned_pages);
486}603}
487 604
488static inline void num_poisoned_pages_dec(void)
489{
490 atomic_long_dec(&num_poisoned_pages);
491}
492
493static inline void num_poisoned_pages_sub(long i)605static inline void num_poisoned_pages_sub(long i)
494{606{
495 atomic_long_sub(i, &num_poisoned_pages);607 atomic_long_sub(i, &num_poisoned_pages);
496}608}
497 609
498#else610#else /* CONFIG_MEMORY_FAILURE */
499 611
500static inline swp_entry_t make_hwpoison_entry(struct page *page)612static inline swp_entry_t make_hwpoison_entry(struct page *page)
501{613{
@@ -514,7 +626,7 @@ static inline void num_poisoned_pages_inc(void) · 12 unmodified lines
514static inline void num_poisoned_pages_sub(long i)626static inline void num_poisoned_pages_sub(long i)
515{627{
516}628}
517#endif629#endif /* CONFIG_MEMORY_FAILURE */
518 630
519static inline int non_swap_entry(swp_entry_t entry)631static inline int non_swap_entry(swp_entry_t entry)
520{632{
include/linux/uaccess.h+14−5
@@ -58,20 +58,28 @@ · 57 unmodified lines
58static __always_inline __must_check unsigned long58static __always_inline __must_check unsigned long
59__copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)59__copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
60{60{
61 instrument_copy_from_user(to, from, n);61 unsigned long res;
62
63 instrument_copy_from_user_before(to, from, n);
62 check_object_size(to, n, false);64 check_object_size(to, n, false);
63 return raw_copy_from_user(to, from, n);65 res = raw_copy_from_user(to, from, n);
66 instrument_copy_from_user_after(to, from, n, res);
67 return res;
64}68}
65 69
66static __always_inline __must_check unsigned long70static __always_inline __must_check unsigned long
67__copy_from_user(void *to, const void __user *from, unsigned long n)71__copy_from_user(void *to, const void __user *from, unsigned long n)
68{72{
73 unsigned long res;
74
69 might_fault();75 might_fault();
76 instrument_copy_from_user_before(to, from, n);
70 if (should_fail_usercopy())77 if (should_fail_usercopy())
71 return n;78 return n;
72 instrument_copy_from_user(to, from, n);
73 check_object_size(to, n, false);79 check_object_size(to, n, false);
74 return raw_copy_from_user(to, from, n);80 res = raw_copy_from_user(to, from, n);
81 instrument_copy_from_user_after(to, from, n, res);
82 return res;
75}83}
76 84
77/**85/**
@@ -115,8 +123,9 @@ _copy_from_user(void *to, const void __user *from, unsigned long n) · 37 unmodified lines
115 unsigned long res = n;123 unsigned long res = n;
116 might_fault();124 might_fault();
117 if (!should_fail_usercopy() && likely(access_ok(from, n))) {125 if (!should_fail_usercopy() && likely(access_ok(from, n))) {
118 instrument_copy_from_user(to, from, n);126 instrument_copy_from_user_before(to, from, n);
119 res = raw_copy_from_user(to, from, n);127 res = raw_copy_from_user(to, from, n);
128 instrument_copy_from_user_after(to, from, n, res);
120 }129 }
121 if (unlikely(res))130 if (unlikely(res))
122 memset(to + (n - res), 0, res);131 memset(to + (n - res), 0, res);
include/linux/userfaultfd_k.h+3−4
@@ -175,9 +175,8 @@ extern bool userfaultfd_remove(struct vm_area_struct *vma, · 174 unmodified lines
175 unsigned long start,175 unsigned long start,
176 unsigned long end);176 unsigned long end);
177 177
178extern int userfaultfd_unmap_prep(struct vm_area_struct *vma,178extern int userfaultfd_unmap_prep(struct mm_struct *mm, unsigned long start,
179 unsigned long start, unsigned long end,179 unsigned long end, struct list_head *uf);
180 struct list_head *uf);
181extern void userfaultfd_unmap_complete(struct mm_struct *mm,180extern void userfaultfd_unmap_complete(struct mm_struct *mm,
182 struct list_head *uf);181 struct list_head *uf);
183 182
@@ -258,7 +257,7 @@ static inline bool userfaultfd_remove(struct vm_area_struct *vma, · 74 unmodified lines
258 return true;257 return true;
259}258}
260 259
261static inline int userfaultfd_unmap_prep(struct vm_area_struct *vma,260static inline int userfaultfd_unmap_prep(struct mm_struct *mm,
262 unsigned long start, unsigned long end,261 unsigned long start, unsigned long end,
263 struct list_head *uf)262 struct list_head *uf)
264{263{
include/linux/vm_event_item.h+0−4
@@ -129,10 +129,6 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, · 128 unmodified lines
129 NR_TLB_LOCAL_FLUSH_ALL,129 NR_TLB_LOCAL_FLUSH_ALL,
130 NR_TLB_LOCAL_FLUSH_ONE,130 NR_TLB_LOCAL_FLUSH_ONE,
131#endif /* CONFIG_DEBUG_TLBFLUSH */131#endif /* CONFIG_DEBUG_TLBFLUSH */
132#ifdef CONFIG_DEBUG_VM_VMACACHE
133 VMACACHE_FIND_CALLS,
134 VMACACHE_FIND_HITS,
135#endif
136#ifdef CONFIG_SWAP132#ifdef CONFIG_SWAP
137 SWAP_RA,133 SWAP_RA,
138 SWAP_RA_HIT,134 SWAP_RA_HIT,
include/linux/vmacache.h+0−28
@@ -1,28 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __LINUX_VMACACHE_H
3#define __LINUX_VMACACHE_H
4
5#include <linux/sched.h>
6#include <linux/mm.h>
7
8static inline void vmacache_flush(struct task_struct *tsk)
9{
10 memset(tsk->vmacache.vmas, 0, sizeof(tsk->vmacache.vmas));
11}
12
13extern void vmacache_update(unsigned long addr, struct vm_area_struct *newvma);
14extern struct vm_area_struct *vmacache_find(struct mm_struct *mm,
15 unsigned long addr);
16
17#ifndef CONFIG_MMU
18extern struct vm_area_struct *vmacache_find_exact(struct mm_struct *mm,
19 unsigned long start,
20 unsigned long end);
21#endif
22
23static inline void vmacache_invalidate(struct mm_struct *mm)
24{
25 mm->vmacache_seqnum++;
26}
27
28#endif /* __LINUX_VMACACHE_H */
include/linux/vmstat.h+0−6
@@ -125,12 +125,6 @@ static inline void vm_events_fold_cpu(int cpu) · 124 unmodified lines
125#define count_vm_tlb_events(x, y) do { (void)(y); } while (0)125#define count_vm_tlb_events(x, y) do { (void)(y); } while (0)
126#endif126#endif
127 127
128#ifdef CONFIG_DEBUG_VM_VMACACHE
129#define count_vm_vmacache_event(x) count_vm_event(x)
130#else
131#define count_vm_vmacache_event(x) do {} while (0)
132#endif
133
134#define __count_zid_vm_events(item, zid, delta) \128#define __count_zid_vm_events(item, zid, delta) \
135 __count_vm_events(item##_NORMAL - ZONE_NORMAL + zid, delta)129 __count_vm_events(item##_NORMAL - ZONE_NORMAL + zid, delta)
136 130
include/linux/writeback.h+0−8
@@ -17,20 +17,12 @@ struct bio; · 16 unmodified lines
17DECLARE_PER_CPU(int, dirty_throttle_leaks);17DECLARE_PER_CPU(int, dirty_throttle_leaks);
18 18
19/*19/*
20 * The 1/4 region under the global dirty thresh is for smooth dirty throttling:
21 *
22 * (thresh - thresh/DIRTY_FULL_SCOPE, thresh)
23 *
24 * Further beyond, all dirtier tasks will enter a loop waiting (possibly long
25 * time) for the dirty pages to drop, unless written enough pages.
26 *
27 * The global dirty threshold is normally equal to the global dirty limit,20 * The global dirty threshold is normally equal to the global dirty limit,
28 * except when the system suddenly allocates a lot of anonymous memory and21 * except when the system suddenly allocates a lot of anonymous memory and
29 * knocks down the global dirty threshold quickly, in which case the global22 * knocks down the global dirty threshold quickly, in which case the global
30 * dirty limit will follow down slowly to prevent livelocking all dirtier tasks.23 * dirty limit will follow down slowly to prevent livelocking all dirtier tasks.
31 */24 */
32#define DIRTY_SCOPE 825#define DIRTY_SCOPE 8
33#define DIRTY_FULL_SCOPE (DIRTY_SCOPE / 2)
34 26
35struct backing_dev_info;27struct backing_dev_info;
36 28
include/trace/events/huge_memory.h+37−0
@@ -11,11 +11,14 @@ · 10 unmodified lines
11 EM( SCAN_FAIL, "failed") \11 EM( SCAN_FAIL, "failed") \
12 EM( SCAN_SUCCEED, "succeeded") \12 EM( SCAN_SUCCEED, "succeeded") \
13 EM( SCAN_PMD_NULL, "pmd_null") \13 EM( SCAN_PMD_NULL, "pmd_null") \
14 EM( SCAN_PMD_NONE, "pmd_none") \
15 EM( SCAN_PMD_MAPPED, "page_pmd_mapped") \
14 EM( SCAN_EXCEED_NONE_PTE, "exceed_none_pte") \16 EM( SCAN_EXCEED_NONE_PTE, "exceed_none_pte") \
15 EM( SCAN_EXCEED_SWAP_PTE, "exceed_swap_pte") \17 EM( SCAN_EXCEED_SWAP_PTE, "exceed_swap_pte") \
16 EM( SCAN_EXCEED_SHARED_PTE, "exceed_shared_pte") \18 EM( SCAN_EXCEED_SHARED_PTE, "exceed_shared_pte") \
17 EM( SCAN_PTE_NON_PRESENT, "pte_non_present") \19 EM( SCAN_PTE_NON_PRESENT, "pte_non_present") \
18 EM( SCAN_PTE_UFFD_WP, "pte_uffd_wp") \20 EM( SCAN_PTE_UFFD_WP, "pte_uffd_wp") \
21 EM( SCAN_PTE_MAPPED_HUGEPAGE, "pte_mapped_hugepage") \
19 EM( SCAN_PAGE_RO, "no_writable_page") \22 EM( SCAN_PAGE_RO, "no_writable_page") \
20 EM( SCAN_LACK_REFERENCED_PAGE, "lack_referenced_page") \23 EM( SCAN_LACK_REFERENCED_PAGE, "lack_referenced_page") \
21 EM( SCAN_PAGE_NULL, "page_null") \24 EM( SCAN_PAGE_NULL, "page_null") \
@@ -166,5 +169,39 @@ TRACE_EVENT(mm_collapse_huge_page_swapin, · 144 unmodified lines
166 __entry->ret)169 __entry->ret)
167);170);
168 171
172TRACE_EVENT(mm_khugepaged_scan_file,
173
174 TP_PROTO(struct mm_struct *mm, struct page *page, const char *filename,
175 int present, int swap, int result),
176
177 TP_ARGS(mm, page, filename, present, swap, result),
178
179 TP_STRUCT__entry(
180 __field(struct mm_struct *, mm)
181 __field(unsigned long, pfn)
182 __string(filename, filename)
183 __field(int, present)
184 __field(int, swap)
185 __field(int, result)
186 ),
187
188 TP_fast_assign(
189 __entry->mm = mm;
190 __entry->pfn = page ? page_to_pfn(page) : -1;
191 __assign_str(filename, filename);
192 __entry->present = present;
193 __entry->swap = swap;
194 __entry->result = result;
195 ),
196
197 TP_printk("mm=%p, scan_pfn=0x%lx, filename=%s, present=%d, swap=%d, result=%s",
198 __entry->mm,
199 __entry->pfn,
200 __get_str(filename),
201 __entry->present,
202 __entry->swap,
203 __print_symbolic(__entry->result, SCAN_STATUS))
204);
205
169#endif /* __HUGE_MEMORY_H */206#endif /* __HUGE_MEMORY_H */
170#include <trace/define_trace.h>207#include <trace/define_trace.h>
include/trace/events/maple_tree.h+123−0
@@ -0,0 +1,123 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#undef TRACE_SYSTEM
3#define TRACE_SYSTEM maple_tree
4
5#if !defined(_TRACE_MM_H) || defined(TRACE_HEADER_MULTI_READ)
6#define _TRACE_MM_H
7
8
9#include <linux/tracepoint.h>
10
11struct ma_state;
12
13TRACE_EVENT(ma_op,
14
15 TP_PROTO(const char *fn, struct ma_state *mas),
16
17 TP_ARGS(fn, mas),
18
19 TP_STRUCT__entry(
20 __field(const char *, fn)
21 __field(unsigned long, min)
22 __field(unsigned long, max)
23 __field(unsigned long, index)
24 __field(unsigned long, last)
25 __field(void *, node)
26 ),
27
28 TP_fast_assign(
29 __entry->fn = fn;
30 __entry->min = mas->min;
31 __entry->max = mas->max;
32 __entry->index = mas->index;
33 __entry->last = mas->last;
34 __entry->node = mas->node;
35 ),
36
37 TP_printk("%s\tNode: %p (%lu %lu) range: %lu-%lu",
38 __entry->fn,
39 (void *) __entry->node,
40 (unsigned long) __entry->min,
41 (unsigned long) __entry->max,
42 (unsigned long) __entry->index,
43 (unsigned long) __entry->last
44 )
45)
46TRACE_EVENT(ma_read,
47
48 TP_PROTO(const char *fn, struct ma_state *mas),
49
50 TP_ARGS(fn, mas),
51
52 TP_STRUCT__entry(
53 __field(const char *, fn)
54 __field(unsigned long, min)
55 __field(unsigned long, max)
56 __field(unsigned long, index)
57 __field(unsigned long, last)
58 __field(void *, node)
59 ),
60
61 TP_fast_assign(
62 __entry->fn = fn;
63 __entry->min = mas->min;
64 __entry->max = mas->max;
65 __entry->index = mas->index;
66 __entry->last = mas->last;
67 __entry->node = mas->node;
68 ),
69
70 TP_printk("%s\tNode: %p (%lu %lu) range: %lu-%lu",
71 __entry->fn,
72 (void *) __entry->node,
73 (unsigned long) __entry->min,
74 (unsigned long) __entry->max,
75 (unsigned long) __entry->index,
76 (unsigned long) __entry->last
77 )
78)
79
80TRACE_EVENT(ma_write,
81
82 TP_PROTO(const char *fn, struct ma_state *mas, unsigned long piv,
83 void *val),
84
85 TP_ARGS(fn, mas, piv, val),
86
87 TP_STRUCT__entry(
88 __field(const char *, fn)
89 __field(unsigned long, min)
90 __field(unsigned long, max)
91 __field(unsigned long, index)
92 __field(unsigned long, last)
93 __field(unsigned long, piv)
94 __field(void *, val)
95 __field(void *, node)
96 ),
97
98 TP_fast_assign(
99 __entry->fn = fn;
100 __entry->min = mas->min;
101 __entry->max = mas->max;
102 __entry->index = mas->index;
103 __entry->last = mas->last;
104 __entry->piv = piv;
105 __entry->val = val;
106 __entry->node = mas->node;
107 ),
108
109 TP_printk("%s\tNode %p (%lu %lu) range:%lu-%lu piv (%lu) val %p",
110 __entry->fn,
111 (void *) __entry->node,
112 (unsigned long) __entry->min,
113 (unsigned long) __entry->max,
114 (unsigned long) __entry->index,
115 (unsigned long) __entry->last,
116 (unsigned long) __entry->piv,
117 (void *) __entry->val
118 )
119)
120#endif /* _TRACE_MM_H */
121
122/* This part must be outside protection */
123#include <trace/define_trace.h>
include/trace/events/mmap.h+73−0
@@ -42,6 +42,79 @@ TRACE_EVENT(vm_unmapped_area, · 41 unmodified lines
42 __entry->low_limit, __entry->high_limit, __entry->align_mask,42 __entry->low_limit, __entry->high_limit, __entry->align_mask,
43 __entry->align_offset)43 __entry->align_offset)
44);44);
45
46TRACE_EVENT(vma_mas_szero,
47 TP_PROTO(struct maple_tree *mt, unsigned long start,
48 unsigned long end),
49
50 TP_ARGS(mt, start, end),
51
52 TP_STRUCT__entry(
53 __field(struct maple_tree *, mt)
54 __field(unsigned long, start)
55 __field(unsigned long, end)
56 ),
57
58 TP_fast_assign(
59 __entry->mt = mt;
60 __entry->start = start;
61 __entry->end = end;
62 ),
63
64 TP_printk("mt_mod %p, (NULL), SNULL, %lu, %lu,",
65 __entry->mt,
66 (unsigned long) __entry->start,
67 (unsigned long) __entry->end
68 )
69);
70
71TRACE_EVENT(vma_store,
72 TP_PROTO(struct maple_tree *mt, struct vm_area_struct *vma),
73
74 TP_ARGS(mt, vma),
75
76 TP_STRUCT__entry(
77 __field(struct maple_tree *, mt)
78 __field(struct vm_area_struct *, vma)
79 __field(unsigned long, vm_start)
80 __field(unsigned long, vm_end)
81 ),
82
83 TP_fast_assign(
84 __entry->mt = mt;
85 __entry->vma = vma;
86 __entry->vm_start = vma->vm_start;
87 __entry->vm_end = vma->vm_end - 1;
88 ),
89
90 TP_printk("mt_mod %p, (%p), STORE, %lu, %lu,",
91 __entry->mt, __entry->vma,
92 (unsigned long) __entry->vm_start,
93 (unsigned long) __entry->vm_end
94 )
95);
96
97
98TRACE_EVENT(exit_mmap,
99 TP_PROTO(struct mm_struct *mm),
100
101 TP_ARGS(mm),
102
103 TP_STRUCT__entry(
104 __field(struct mm_struct *, mm)
105 __field(struct maple_tree *, mt)
106 ),
107
108 TP_fast_assign(
109 __entry->mm = mm;
110 __entry->mt = &mm->mm_mt;
111 ),
112
113 TP_printk("mt_mod %p, DESTROY\n",
114 __entry->mt
115 )
116);
117
45#endif118#endif
46 119
47/* This part must be outside protection */120/* This part must be outside protection */
include/uapi/asm-generic/hugetlb_encode.h+13−13
@@ -20,18 +20,18 @@ · 19 unmodified lines
20#define HUGETLB_FLAG_ENCODE_SHIFT 2620#define HUGETLB_FLAG_ENCODE_SHIFT 26
21#define HUGETLB_FLAG_ENCODE_MASK 0x3f21#define HUGETLB_FLAG_ENCODE_MASK 0x3f
22 22
23#define HUGETLB_FLAG_ENCODE_16KB (14 << HUGETLB_FLAG_ENCODE_SHIFT)23#define HUGETLB_FLAG_ENCODE_16KB (14U << HUGETLB_FLAG_ENCODE_SHIFT)
24#define HUGETLB_FLAG_ENCODE_64KB (16 << HUGETLB_FLAG_ENCODE_SHIFT)24#define HUGETLB_FLAG_ENCODE_64KB (16U << HUGETLB_FLAG_ENCODE_SHIFT)
25#define HUGETLB_FLAG_ENCODE_512KB (19 << HUGETLB_FLAG_ENCODE_SHIFT)25#define HUGETLB_FLAG_ENCODE_512KB (19U << HUGETLB_FLAG_ENCODE_SHIFT)
26#define HUGETLB_FLAG_ENCODE_1MB (20 << HUGETLB_FLAG_ENCODE_SHIFT)26#define HUGETLB_FLAG_ENCODE_1MB (20U << HUGETLB_FLAG_ENCODE_SHIFT)
27#define HUGETLB_FLAG_ENCODE_2MB (21 << HUGETLB_FLAG_ENCODE_SHIFT)27#define HUGETLB_FLAG_ENCODE_2MB (21U << HUGETLB_FLAG_ENCODE_SHIFT)
28#define HUGETLB_FLAG_ENCODE_8MB (23 << HUGETLB_FLAG_ENCODE_SHIFT)28#define HUGETLB_FLAG_ENCODE_8MB (23U << HUGETLB_FLAG_ENCODE_SHIFT)
29#define HUGETLB_FLAG_ENCODE_16MB (24 << HUGETLB_FLAG_ENCODE_SHIFT)29#define HUGETLB_FLAG_ENCODE_16MB (24U << HUGETLB_FLAG_ENCODE_SHIFT)
30#define HUGETLB_FLAG_ENCODE_32MB (25 << HUGETLB_FLAG_ENCODE_SHIFT)30#define HUGETLB_FLAG_ENCODE_32MB (25U << HUGETLB_FLAG_ENCODE_SHIFT)
31#define HUGETLB_FLAG_ENCODE_256MB (28 << HUGETLB_FLAG_ENCODE_SHIFT)31#define HUGETLB_FLAG_ENCODE_256MB (28U << HUGETLB_FLAG_ENCODE_SHIFT)
32#define HUGETLB_FLAG_ENCODE_512MB (29 << HUGETLB_FLAG_ENCODE_SHIFT)32#define HUGETLB_FLAG_ENCODE_512MB (29U << HUGETLB_FLAG_ENCODE_SHIFT)
33#define HUGETLB_FLAG_ENCODE_1GB (30 << HUGETLB_FLAG_ENCODE_SHIFT)33#define HUGETLB_FLAG_ENCODE_1GB (30U << HUGETLB_FLAG_ENCODE_SHIFT)
34#define HUGETLB_FLAG_ENCODE_2GB (31 << HUGETLB_FLAG_ENCODE_SHIFT)34#define HUGETLB_FLAG_ENCODE_2GB (31U << HUGETLB_FLAG_ENCODE_SHIFT)
35#define HUGETLB_FLAG_ENCODE_16GB (34 << HUGETLB_FLAG_ENCODE_SHIFT)35#define HUGETLB_FLAG_ENCODE_16GB (34U << HUGETLB_FLAG_ENCODE_SHIFT)
36 36
37#endif /* _ASM_GENERIC_HUGETLB_ENCODE_H_ */37#endif /* _ASM_GENERIC_HUGETLB_ENCODE_H_ */
include/uapi/asm-generic/mman-common.h+2−0
@@ -77,6 +77,8 @@ · 76 unmodified lines
77 77
78#define MADV_DONTNEED_LOCKED 24 /* like DONTNEED, but drop locked pages too */78#define MADV_DONTNEED_LOCKED 24 /* like DONTNEED, but drop locked pages too */
79 79
80#define MADV_COLLAPSE 25 /* Synchronous hugepage collapse */
81
80/* compatibility flags */82/* compatibility flags */
81#define MAP_FILE 083#define MAP_FILE 0
82 84
include/uapi/linux/userfaultfd.h+4−0
@@ -12,6 +12,10 @@ · 11 unmodified lines
12 12
13#include <linux/types.h>13#include <linux/types.h>
14 14
15/* ioctls for /dev/userfaultfd */
16#define USERFAULTFD_IOC 0xAA
17#define USERFAULTFD_IOC_NEW _IO(USERFAULTFD_IOC, 0x00)
18
15/*19/*
16 * If the UFFDIO_API is upgraded someday, the UFFDIO_UNREGISTER and20 * If the UFFDIO_API is upgraded someday, the UFFDIO_UNREGISTER and
17 * UFFDIO_WAKE ioctls should be defined as _IOW and not as _IOR. In21 * UFFDIO_WAKE ioctls should be defined as _IOW and not as _IOR. In
init/Kconfig+0−5
@@ -969,11 +969,6 @@ config MEMCG · 968 unmodified lines
969 help969 help
970 Provides control over the memory footprint of tasks in a cgroup.970 Provides control over the memory footprint of tasks in a cgroup.
971 971
972config MEMCG_SWAP
973 bool
974 depends on MEMCG && SWAP
975 default y
976
977config MEMCG_KMEM972config MEMCG_KMEM
978 bool973 bool
979 depends on MEMCG && !SLOB974 depends on MEMCG && !SLOB
init/main.c+10−1
@@ -34,6 +34,7 @@ · 33 unmodified lines
34#include <linux/percpu.h>34#include <linux/percpu.h>
35#include <linux/kmod.h>35#include <linux/kmod.h>
36#include <linux/kprobes.h>36#include <linux/kprobes.h>
37#include <linux/kmsan.h>
37#include <linux/vmalloc.h>38#include <linux/vmalloc.h>
38#include <linux/kernel_stat.h>39#include <linux/kernel_stat.h>
39#include <linux/start_kernel.h>40#include <linux/start_kernel.h>
@@ -117,6 +118,7 @@ static int kernel_init(void *); · 77 unmodified lines
117 118
118extern void init_IRQ(void);119extern void init_IRQ(void);
119extern void radix_tree_init(void);120extern void radix_tree_init(void);
121extern void maple_tree_init(void);
120 122
121/*123/*
122 * Debug helper: via this flag we know that we are in 'early bootup code'124 * Debug helper: via this flag we know that we are in 'early bootup code'
@@ -836,6 +838,7 @@ static void __init mm_init(void) · 713 unmodified lines
836 init_mem_debugging_and_hardening();838 init_mem_debugging_and_hardening();
837 kfence_alloc_pool();839 kfence_alloc_pool();
838 report_meminit();840 report_meminit();
841 kmsan_init_shadow();
839 stack_depot_early_init();842 stack_depot_early_init();
840 mem_init();843 mem_init();
841 mem_init_print_info();844 mem_init_print_info();
@@ -849,10 +852,14 @@ static void __init mm_init(void) · 7 unmodified lines
849 pgtable_init();852 pgtable_init();
850 debug_objects_mem_init();853 debug_objects_mem_init();
851 vmalloc_init();854 vmalloc_init();
855 /* Should be run after vmap initialization */
856 if (early_page_ext_enabled())
857 page_ext_init();
852 /* Should be run before the first non-init thread is created */858 /* Should be run before the first non-init thread is created */
853 init_espfix_bsp();859 init_espfix_bsp();
854 /* Should be run after espfix64 is set up. */860 /* Should be run after espfix64 is set up. */
855 pti_init();861 pti_init();
862 kmsan_init_runtime();
856}863}
857 864
858#ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET865#ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET
@@ -1005,6 +1012,7 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void) · 146 unmodified lines
1005 "Interrupts were enabled *very* early, fixing it\n"))1012 "Interrupts were enabled *very* early, fixing it\n"))
1006 local_irq_disable();1013 local_irq_disable();
1007 radix_tree_init();1014 radix_tree_init();
1015 maple_tree_init();
1008 1016
1009 /*1017 /*
1010 * Set up housekeeping before setting up workqueues to allow the unbound1018 * Set up housekeeping before setting up workqueues to allow the unbound
@@ -1617,7 +1625,8 @@ static noinline void __init kernel_init_freeable(void) · 606 unmodified lines
1617 padata_init();1625 padata_init();
1618 page_alloc_init_late();1626 page_alloc_init_late();
1619 /* Initialize page ext after all struct pages are initialized. */1627 /* Initialize page ext after all struct pages are initialized. */
1620 page_ext_init();1628 if (!early_page_ext_enabled())
1629 page_ext_init();
1621 1630
1622 do_basic_setup();1631 do_basic_setup();
1623 1632
ipc/shm.c+10−11
@@ -1721,7 +1721,7 @@ long ksys_shmdt(char __user *shmaddr) · 1720 unmodified lines
1721#ifdef CONFIG_MMU1721#ifdef CONFIG_MMU
1722 loff_t size = 0;1722 loff_t size = 0;
1723 struct file *file;1723 struct file *file;
1724 struct vm_area_struct *next;1724 VMA_ITERATOR(vmi, mm, addr);
1725#endif1725#endif
1726 1726
1727 if (addr & ~PAGE_MASK)1727 if (addr & ~PAGE_MASK)
@@ -1751,12 +1751,9 @@ long ksys_shmdt(char __user *shmaddr) · 23 unmodified lines
1751 * match the usual checks anyway. So assume all vma's are1751 * match the usual checks anyway. So assume all vma's are
1752 * above the starting address given.1752 * above the starting address given.
1753 */1753 */
1754 vma = find_vma(mm, addr);
1755 1754
1756#ifdef CONFIG_MMU1755#ifdef CONFIG_MMU
1757 while (vma) {1756 for_each_vma(vmi, vma) {
1758 next = vma->vm_next;
1759
1760 /*1757 /*
1761 * Check if the starting address would match, i.e. it's1758 * Check if the starting address would match, i.e. it's
1762 * a fragment created by mprotect() and/or munmap(), or it1759 * a fragment created by mprotect() and/or munmap(), or it
@@ -1774,6 +1771,7 @@ long ksys_shmdt(char __user *shmaddr) · 11 unmodified lines
1774 file = vma->vm_file;1771 file = vma->vm_file;
1775 size = i_size_read(file_inode(vma->vm_file));1772 size = i_size_read(file_inode(vma->vm_file));
1776 do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start, NULL);1773 do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start, NULL);
1774 mas_pause(&vmi.mas);
1777 /*1775 /*
1778 * We discovered the size of the shm segment, so1776 * We discovered the size of the shm segment, so
1779 * break out of here and fall through to the next1777 * break out of here and fall through to the next
@@ -1781,10 +1779,9 @@ long ksys_shmdt(char __user *shmaddr) · 1 unmodified line
1781 * searching for matching vma's.1779 * searching for matching vma's.
1782 */1780 */
1783 retval = 0;1781 retval = 0;
1784 vma = next;1782 vma = vma_next(&vmi);
1785 break;1783 break;
1786 }1784 }
1787 vma = next;
1788 }1785 }
1789 1786
1790 /*1787 /*
@@ -1794,17 +1791,19 @@ long ksys_shmdt(char __user *shmaddr) · 3 unmodified lines
1794 */1791 */
1795 size = PAGE_ALIGN(size);1792 size = PAGE_ALIGN(size);
1796 while (vma && (loff_t)(vma->vm_end - addr) <= size) {1793 while (vma && (loff_t)(vma->vm_end - addr) <= size) {
1797 next = vma->vm_next;
1798
1799 /* finding a matching vma now does not alter retval */1794 /* finding a matching vma now does not alter retval */
1800 if ((vma->vm_ops == &shm_vm_ops) &&1795 if ((vma->vm_ops == &shm_vm_ops) &&
1801 ((vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff) &&1796 ((vma->vm_start - addr)/PAGE_SIZE == vma->vm_pgoff) &&
1802 (vma->vm_file == file))1797 (vma->vm_file == file)) {
1803 do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start, NULL);1798 do_munmap(mm, vma->vm_start, vma->vm_end - vma->vm_start, NULL);
1804 vma = next;1799 mas_pause(&vmi.mas);
1800 }
1801
1802 vma = vma_next(&vmi);
1805 }1803 }
1806 1804
1807#else /* CONFIG_MMU */1805#else /* CONFIG_MMU */
1806 vma = vma_lookup(mm, addr);
1808 /* under NOMMU conditions, the exact address to be destroyed must be1807 /* under NOMMU conditions, the exact address to be destroyed must be
1809 * given1808 * given
1810 */1809 */
kernel/Makefile+1−0
@@ -38,6 +38,7 @@ KCOV_INSTRUMENT_kcov.o := n · 37 unmodified lines
38KASAN_SANITIZE_kcov.o := n38KASAN_SANITIZE_kcov.o := n
39KCSAN_SANITIZE_kcov.o := n39KCSAN_SANITIZE_kcov.o := n
40UBSAN_SANITIZE_kcov.o := n40UBSAN_SANITIZE_kcov.o := n
41KMSAN_SANITIZE_kcov.o := n
41CFLAGS_kcov.o := $(call cc-option, -fno-conserve-stack) -fno-stack-protector42CFLAGS_kcov.o := $(call cc-option, -fno-conserve-stack) -fno-stack-protector
42 43
43# Don't instrument error handlers44# Don't instrument error handlers
kernel/acct.c+5−6
@@ -555,15 +555,14 @@ void acct_collect(long exitcode, int group_dead) · 554 unmodified lines
555 unsigned long vsize = 0;555 unsigned long vsize = 0;
556 556
557 if (group_dead && current->mm) {557 if (group_dead && current->mm) {
558 struct mm_struct *mm = current->mm;
559 VMA_ITERATOR(vmi, mm, 0);
558 struct vm_area_struct *vma;560 struct vm_area_struct *vma;
559 561
560 mmap_read_lock(current->mm);562 mmap_read_lock(mm);
561 vma = current->mm->mmap;563 for_each_vma(vmi, vma)
562 while (vma) {
563 vsize += vma->vm_end - vma->vm_start;564 vsize += vma->vm_end - vma->vm_start;
564 vma = vma->vm_next;565 mmap_read_unlock(mm);
565 }
566 mmap_read_unlock(current->mm);
567 }566 }
568 567
569 spin_lock_irq(&current->sighand->siglock);568 spin_lock_irq(&current->sighand->siglock);
kernel/bounds.c+7−0
@@ -22,6 +22,13 @@ int main(void) · 21 unmodified lines
22 DEFINE(NR_CPUS_BITS, ilog2(CONFIG_NR_CPUS));22 DEFINE(NR_CPUS_BITS, ilog2(CONFIG_NR_CPUS));
23#endif23#endif
24 DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t));24 DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t));
25#ifdef CONFIG_LRU_GEN
26 DEFINE(LRU_GEN_WIDTH, order_base_2(MAX_NR_GENS + 1));
27 DEFINE(__LRU_REFS_WIDTH, MAX_NR_TIERS - 2);
28#else
29 DEFINE(LRU_GEN_WIDTH, 0);
30 DEFINE(__LRU_REFS_WIDTH, 0);
31#endif
25 /* End of constants */32 /* End of constants */
26 33
27 return 0;34 return 0;
kernel/bpf/core.c+1−1
@@ -2007,7 +2007,7 @@ out: · 2006 unmodified lines
2007static unsigned int PROG_NAME(stack_size)(const void *ctx, const struct bpf_insn *insn) \2007static unsigned int PROG_NAME(stack_size)(const void *ctx, const struct bpf_insn *insn) \
2008{ \2008{ \
2009 u64 stack[stack_size / sizeof(u64)]; \2009 u64 stack[stack_size / sizeof(u64)]; \
2010 u64 regs[MAX_BPF_EXT_REG]; \2010 u64 regs[MAX_BPF_EXT_REG] = {}; \
2011\2011\
2012 FP = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)]; \2012 FP = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)]; \
2013 ARG1 = (u64) (unsigned long) ctx; \2013 ARG1 = (u64) (unsigned long) ctx; \
kernel/bpf/task_iter.c+5−5
@@ -445,8 +445,8 @@ struct bpf_iter_seq_task_vma_info { · 444 unmodified lines
445};445};
446 446
447enum bpf_task_vma_iter_find_op {447enum bpf_task_vma_iter_find_op {
448 task_vma_iter_first_vma, /* use mm->mmap */448 task_vma_iter_first_vma, /* use find_vma() with addr 0 */
449 task_vma_iter_next_vma, /* use curr_vma->vm_next */449 task_vma_iter_next_vma, /* use vma_next() with curr_vma */
450 task_vma_iter_find_vma, /* use find_vma() to find next vma */450 task_vma_iter_find_vma, /* use find_vma() to find next vma */
451};451};
452 452
@@ -544,10 +544,10 @@ again: · 91 unmodified lines
544 544
545 switch (op) {545 switch (op) {
546 case task_vma_iter_first_vma:546 case task_vma_iter_first_vma:
547 curr_vma = curr_task->mm->mmap;547 curr_vma = find_vma(curr_task->mm, 0);
548 break;548 break;
549 case task_vma_iter_next_vma:549 case task_vma_iter_next_vma:
550 curr_vma = curr_vma->vm_next;550 curr_vma = find_vma(curr_task->mm, curr_vma->vm_end);
551 break;551 break;
552 case task_vma_iter_find_vma:552 case task_vma_iter_find_vma:
553 /* We dropped mmap_lock so it is necessary to use find_vma553 /* We dropped mmap_lock so it is necessary to use find_vma
@@ -561,7 +561,7 @@ again: · 7 unmodified lines
561 if (curr_vma &&561 if (curr_vma &&
562 curr_vma->vm_start == info->prev_vm_start &&562 curr_vma->vm_start == info->prev_vm_start &&
563 curr_vma->vm_end == info->prev_vm_end)563 curr_vma->vm_end == info->prev_vm_end)
564 curr_vma = curr_vma->vm_next;564 curr_vma = find_vma(curr_task->mm, curr_vma->vm_end);
565 break;565 break;
566 }566 }
567 if (!curr_vma) {567 if (!curr_vma) {
kernel/cgroup/cgroup-internal.h+0−1
@@ -164,7 +164,6 @@ struct cgroup_mgctx { · 163 unmodified lines
164#define DEFINE_CGROUP_MGCTX(name) \164#define DEFINE_CGROUP_MGCTX(name) \
165 struct cgroup_mgctx name = CGROUP_MGCTX_INIT(name)165 struct cgroup_mgctx name = CGROUP_MGCTX_INIT(name)
166 166
167extern struct mutex cgroup_mutex;
168extern spinlock_t css_set_lock;167extern spinlock_t css_set_lock;
169extern struct cgroup_subsys *cgroup_subsys[];168extern struct cgroup_subsys *cgroup_subsys[];
170extern struct list_head cgroup_roots;169extern struct list_head cgroup_roots;
kernel/debug/debug_core.c+0−12
@@ -50,7 +50,6 @@ · 49 unmodified lines
50#include <linux/pid.h>50#include <linux/pid.h>
51#include <linux/smp.h>51#include <linux/smp.h>
52#include <linux/mm.h>52#include <linux/mm.h>
53#include <linux/vmacache.h>
54#include <linux/rcupdate.h>53#include <linux/rcupdate.h>
55#include <linux/irq.h>54#include <linux/irq.h>
56#include <linux/security.h>55#include <linux/security.h>
@@ -283,17 +282,6 @@ static void kgdb_flush_swbreak_addr(unsigned long addr) · 226 unmodified lines
283 if (!CACHE_FLUSH_IS_SAFE)282 if (!CACHE_FLUSH_IS_SAFE)
284 return;283 return;
285 284
286 if (current->mm) {
287 int i;
288
289 for (i = 0; i < VMACACHE_SIZE; i++) {
290 if (!current->vmacache.vmas[i])
291 continue;
292 flush_cache_range(current->vmacache.vmas[i],
293 addr, addr + BREAK_INSTR_SIZE);
294 }
295 }
296
297 /* Force flush instruction cache if it was outside the mm */285 /* Force flush instruction cache if it was outside the mm */
298 flush_icache_range(addr, addr + BREAK_INSTR_SIZE);286 flush_icache_range(addr, addr + BREAK_INSTR_SIZE);
299}287}
kernel/delayacct.c+11−2
@@ -214,13 +214,22 @@ void __delayacct_freepages_end(void) · 213 unmodified lines
214 &current->delays->freepages_count);214 &current->delays->freepages_count);
215}215}
216 216
217void __delayacct_thrashing_start(void)217void __delayacct_thrashing_start(bool *in_thrashing)
218{218{
219 *in_thrashing = !!current->in_thrashing;
220 if (*in_thrashing)
221 return;
222
223 current->in_thrashing = 1;
219 current->delays->thrashing_start = local_clock();224 current->delays->thrashing_start = local_clock();
220}225}
221 226
222void __delayacct_thrashing_end(void)227void __delayacct_thrashing_end(bool *in_thrashing)
223{228{
229 if (*in_thrashing)
230 return;
231
232 current->in_thrashing = 0;
224 delayacct_end(&current->delays->lock,233 delayacct_end(&current->delays->lock,
225 &current->delays->thrashing_start,234 &current->delays->thrashing_start,
226 &current->delays->thrashing_delay,235 &current->delays->thrashing_delay,
kernel/dma/mapping.c+7−3
@@ -10,6 +10,7 @@ · 9 unmodified lines
10#include <linux/dma-map-ops.h>10#include <linux/dma-map-ops.h>
11#include <linux/export.h>11#include <linux/export.h>
12#include <linux/gfp.h>12#include <linux/gfp.h>
13#include <linux/kmsan.h>
13#include <linux/of_device.h>14#include <linux/of_device.h>
14#include <linux/slab.h>15#include <linux/slab.h>
15#include <linux/vmalloc.h>16#include <linux/vmalloc.h>
@@ -156,6 +157,7 @@ dma_addr_t dma_map_page_attrs(struct device *dev, struct page *page, · 140 unmodified lines
156 addr = dma_direct_map_page(dev, page, offset, size, dir, attrs);157 addr = dma_direct_map_page(dev, page, offset, size, dir, attrs);
157 else158 else
158 addr = ops->map_page(dev, page, offset, size, dir, attrs);159 addr = ops->map_page(dev, page, offset, size, dir, attrs);
160 kmsan_handle_dma(page, offset, size, dir);
159 debug_dma_map_page(dev, page, offset, size, dir, addr, attrs);161 debug_dma_map_page(dev, page, offset, size, dir, addr, attrs);
160 162
161 return addr;163 return addr;
@@ -194,11 +196,13 @@ static int __dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, · 32 unmodified lines
194 else196 else
195 ents = ops->map_sg(dev, sg, nents, dir, attrs);197 ents = ops->map_sg(dev, sg, nents, dir, attrs);
196 198
197 if (ents > 0)199 if (ents > 0) {
200 kmsan_handle_dma_sg(sg, nents, dir);
198 debug_dma_map_sg(dev, sg, nents, ents, dir, attrs);201 debug_dma_map_sg(dev, sg, nents, ents, dir, attrs);
199 else if (WARN_ON_ONCE(ents != -EINVAL && ents != -ENOMEM &&202 } else if (WARN_ON_ONCE(ents != -EINVAL && ents != -ENOMEM &&
200 ents != -EIO && ents != -EREMOTEIO))203 ents != -EIO && ents != -EREMOTEIO)) {
201 return -EIO;204 return -EIO;
205 }
202 206
203 return ents;207 return ents;
204}208}
kernel/entry/common.c+5−0
@@ -5,6 +5,7 @@ · 4 unmodified lines
5#include <linux/resume_user_mode.h>5#include <linux/resume_user_mode.h>
6#include <linux/highmem.h>6#include <linux/highmem.h>
7#include <linux/jump_label.h>7#include <linux/jump_label.h>
8#include <linux/kmsan.h>
8#include <linux/livepatch.h>9#include <linux/livepatch.h>
9#include <linux/audit.h>10#include <linux/audit.h>
10#include <linux/tick.h>11#include <linux/tick.h>
@@ -24,6 +25,7 @@ static __always_inline void __enter_from_user_mode(struct pt_regs *regs) · 13 unmodified lines
24 user_exit_irqoff();25 user_exit_irqoff();
25 26
26 instrumentation_begin();27 instrumentation_begin();
28 kmsan_unpoison_entry_regs(regs);
27 trace_hardirqs_off_finish();29 trace_hardirqs_off_finish();
28 instrumentation_end();30 instrumentation_end();
29}31}
@@ -352,6 +354,7 @@ noinstr irqentry_state_t irqentry_enter(struct pt_regs *regs) · 322 unmodified lines
352 lockdep_hardirqs_off(CALLER_ADDR0);354 lockdep_hardirqs_off(CALLER_ADDR0);
353 ct_irq_enter();355 ct_irq_enter();
354 instrumentation_begin();356 instrumentation_begin();
357 kmsan_unpoison_entry_regs(regs);
355 trace_hardirqs_off_finish();358 trace_hardirqs_off_finish();
356 instrumentation_end();359 instrumentation_end();
357 360
@@ -367,6 +370,7 @@ noinstr irqentry_state_t irqentry_enter(struct pt_regs *regs) · 9 unmodified lines
367 */370 */
368 lockdep_hardirqs_off(CALLER_ADDR0);371 lockdep_hardirqs_off(CALLER_ADDR0);
369 instrumentation_begin();372 instrumentation_begin();
373 kmsan_unpoison_entry_regs(regs);
370 rcu_irq_enter_check_tick();374 rcu_irq_enter_check_tick();
371 trace_hardirqs_off_finish();375 trace_hardirqs_off_finish();
372 instrumentation_end();376 instrumentation_end();
@@ -452,6 +456,7 @@ irqentry_state_t noinstr irqentry_nmi_enter(struct pt_regs *regs) · 79 unmodified lines
452 ct_nmi_enter();456 ct_nmi_enter();
453 457
454 instrumentation_begin();458 instrumentation_begin();
459 kmsan_unpoison_entry_regs(regs);
455 trace_hardirqs_off_finish();460 trace_hardirqs_off_finish();
456 ftrace_nmi_enter();461 ftrace_nmi_enter();
457 instrumentation_end();462 instrumentation_end();
kernel/events/core.c+2−1
@@ -10270,8 +10270,9 @@ static void perf_addr_filter_apply(struct perf_addr_filter *filter, · 10269 unmodified lines
10270 struct perf_addr_filter_range *fr)10270 struct perf_addr_filter_range *fr)
10271{10271{
10272 struct vm_area_struct *vma;10272 struct vm_area_struct *vma;
10273 VMA_ITERATOR(vmi, mm, 0);
10273 10274
10274 for (vma = mm->mmap; vma; vma = vma->vm_next) {10275 for_each_vma(vmi, vma) {
10275 if (!vma->vm_file)10276 if (!vma->vm_file)
10276 continue;10277 continue;
10277 10278
kernel/events/uprobes.c+22−17
@@ -19,7 +19,7 @@ · 18 unmodified lines
19#include <linux/export.h>19#include <linux/export.h>
20#include <linux/rmap.h> /* anon_vma_prepare */20#include <linux/rmap.h> /* anon_vma_prepare */
21#include <linux/mmu_notifier.h> /* set_pte_at_notify */21#include <linux/mmu_notifier.h> /* set_pte_at_notify */
22#include <linux/swap.h> /* try_to_free_swap */22#include <linux/swap.h> /* folio_free_swap */
23#include <linux/ptrace.h> /* user_enable_single_step */23#include <linux/ptrace.h> /* user_enable_single_step */
24#include <linux/kdebug.h> /* notifier mechanism */24#include <linux/kdebug.h> /* notifier mechanism */
25#include "../../mm/internal.h" /* munlock_vma_page */25#include "../../mm/internal.h" /* munlock_vma_page */
@@ -154,8 +154,10 @@ static loff_t vaddr_to_offset(struct vm_area_struct *vma, unsigned long vaddr) · 128 unmodified lines
154static int __replace_page(struct vm_area_struct *vma, unsigned long addr,154static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
155 struct page *old_page, struct page *new_page)155 struct page *old_page, struct page *new_page)
156{156{
157 struct folio *old_folio = page_folio(old_page);
158 struct folio *new_folio;
157 struct mm_struct *mm = vma->vm_mm;159 struct mm_struct *mm = vma->vm_mm;
158 DEFINE_FOLIO_VMA_WALK(pvmw, page_folio(old_page), vma, addr, 0);160 DEFINE_FOLIO_VMA_WALK(pvmw, old_folio, vma, addr, 0);
159 int err;161 int err;
160 struct mmu_notifier_range range;162 struct mmu_notifier_range range;
161 163
@@ -163,14 +165,14 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr, · 1 unmodified line
163 addr + PAGE_SIZE);165 addr + PAGE_SIZE);
164 166
165 if (new_page) {167 if (new_page) {
166 err = mem_cgroup_charge(page_folio(new_page), vma->vm_mm,168 new_folio = page_folio(new_page);
167 GFP_KERNEL);169 err = mem_cgroup_charge(new_folio, vma->vm_mm, GFP_KERNEL);
168 if (err)170 if (err)
169 return err;171 return err;
170 }172 }
171 173
172 /* For try_to_free_swap() below */174 /* For folio_free_swap() below */
173 lock_page(old_page);175 folio_lock(old_folio);
174 176
175 mmu_notifier_invalidate_range_start(&range);177 mmu_notifier_invalidate_range_start(&range);
176 err = -EAGAIN;178 err = -EAGAIN;
@@ -179,14 +181,14 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr, · 2 unmodified lines
179 VM_BUG_ON_PAGE(addr != pvmw.address, old_page);181 VM_BUG_ON_PAGE(addr != pvmw.address, old_page);
180 182
181 if (new_page) {183 if (new_page) {
182 get_page(new_page);184 folio_get(new_folio);
183 page_add_new_anon_rmap(new_page, vma, addr);185 page_add_new_anon_rmap(new_page, vma, addr);
184 lru_cache_add_inactive_or_unevictable(new_page, vma);186 folio_add_lru_vma(new_folio, vma);
185 } else187 } else
186 /* no new page, just dec_mm_counter for old_page */188 /* no new page, just dec_mm_counter for old_page */
187 dec_mm_counter(mm, MM_ANONPAGES);189 dec_mm_counter(mm, MM_ANONPAGES);
188 190
189 if (!PageAnon(old_page)) {191 if (!folio_test_anon(old_folio)) {
190 dec_mm_counter(mm, mm_counter_file(old_page));192 dec_mm_counter(mm, mm_counter_file(old_page));
191 inc_mm_counter(mm, MM_ANONPAGES);193 inc_mm_counter(mm, MM_ANONPAGES);
192 }194 }
@@ -198,15 +200,15 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr, · 5 unmodified lines
198 mk_pte(new_page, vma->vm_page_prot));200 mk_pte(new_page, vma->vm_page_prot));
199 201
200 page_remove_rmap(old_page, vma, false);202 page_remove_rmap(old_page, vma, false);
201 if (!page_mapped(old_page))203 if (!folio_mapped(old_folio))
202 try_to_free_swap(old_page);204 folio_free_swap(old_folio);
203 page_vma_mapped_walk_done(&pvmw);205 page_vma_mapped_walk_done(&pvmw);
204 put_page(old_page);206 folio_put(old_folio);
205 207
206 err = 0;208 err = 0;
207 unlock:209 unlock:
208 mmu_notifier_invalidate_range_end(&range);210 mmu_notifier_invalidate_range_end(&range);
209 unlock_page(old_page);211 folio_unlock(old_folio);
210 return err;212 return err;
211}213}
212 214
@@ -349,9 +351,10 @@ static bool valid_ref_ctr_vma(struct uprobe *uprobe, · 136 unmodified lines
349static struct vm_area_struct *351static struct vm_area_struct *
350find_ref_ctr_vma(struct uprobe *uprobe, struct mm_struct *mm)352find_ref_ctr_vma(struct uprobe *uprobe, struct mm_struct *mm)
351{353{
354 VMA_ITERATOR(vmi, mm, 0);
352 struct vm_area_struct *tmp;355 struct vm_area_struct *tmp;
353 356
354 for (tmp = mm->mmap; tmp; tmp = tmp->vm_next)357 for_each_vma(vmi, tmp)
355 if (valid_ref_ctr_vma(uprobe, tmp))358 if (valid_ref_ctr_vma(uprobe, tmp))
356 return tmp;359 return tmp;
357 360
@@ -552,7 +555,7 @@ put_old: · 194 unmodified lines
552 555
553 /* try collapse pmd for compound page */556 /* try collapse pmd for compound page */
554 if (!ret && orig_page_huge)557 if (!ret && orig_page_huge)
555 collapse_pte_mapped_thp(mm, vaddr);558 collapse_pte_mapped_thp(mm, vaddr, false);
556 559
557 return ret;560 return ret;
558}561}
@@ -1231,11 +1234,12 @@ int uprobe_apply(struct inode *inode, loff_t offset, · 672 unmodified lines
1231 1234
1232static int unapply_uprobe(struct uprobe *uprobe, struct mm_struct *mm)1235static int unapply_uprobe(struct uprobe *uprobe, struct mm_struct *mm)
1233{1236{
1237 VMA_ITERATOR(vmi, mm, 0);
1234 struct vm_area_struct *vma;1238 struct vm_area_struct *vma;
1235 int err = 0;1239 int err = 0;
1236 1240
1237 mmap_read_lock(mm);1241 mmap_read_lock(mm);
1238 for (vma = mm->mmap; vma; vma = vma->vm_next) {1242 for_each_vma(vmi, vma) {
1239 unsigned long vaddr;1243 unsigned long vaddr;
1240 loff_t offset;1244 loff_t offset;
1241 1245
@@ -1983,9 +1987,10 @@ bool uprobe_deny_signal(void) · 741 unmodified lines
1983 1987
1984static void mmf_recalc_uprobes(struct mm_struct *mm)1988static void mmf_recalc_uprobes(struct mm_struct *mm)
1985{1989{
1990 VMA_ITERATOR(vmi, mm, 0);
1986 struct vm_area_struct *vma;1991 struct vm_area_struct *vma;
1987 1992
1988 for (vma = mm->mmap; vma; vma = vma->vm_next) {1993 for_each_vma(vmi, vma) {
1989 if (!valid_vma(vma, false))1994 if (!valid_vma(vma, false))
1990 continue;1995 continue;
1991 /*1996 /*
kernel/exit.c+3−0
@@ -60,6 +60,7 @@ · 59 unmodified lines
60#include <linux/writeback.h>60#include <linux/writeback.h>
61#include <linux/shm.h>61#include <linux/shm.h>
62#include <linux/kcov.h>62#include <linux/kcov.h>
63#include <linux/kmsan.h>
63#include <linux/random.h>64#include <linux/random.h>
64#include <linux/rcuwait.h>65#include <linux/rcuwait.h>
65#include <linux/compat.h>66#include <linux/compat.h>
@@ -466,6 +467,7 @@ assign_new_owner: · 400 unmodified lines
466 goto retry;467 goto retry;
467 }468 }
468 WRITE_ONCE(mm->owner, c);469 WRITE_ONCE(mm->owner, c);
470 lru_gen_migrate_mm(mm);
469 task_unlock(c);471 task_unlock(c);
470 put_task_struct(c);472 put_task_struct(c);
471}473}
@@ -759,6 +761,7 @@ void __noreturn do_exit(long code) · 287 unmodified lines
759 WARN_ON(tsk->plug);761 WARN_ON(tsk->plug);
760 762
761 kcov_task_exit(tsk);763 kcov_task_exit(tsk);
764 kmsan_task_exit(tsk);
762 765
763 coredump_task_exit(tsk);766 coredump_task_exit(tsk);
764 ptrace_event(PTRACE_EVENT_EXIT, code);767 ptrace_event(PTRACE_EVENT_EXIT, code);
kernel/fork.c+43−36
@@ -37,13 +37,13 @@ · 36 unmodified lines
37#include <linux/fdtable.h>37#include <linux/fdtable.h>
38#include <linux/iocontext.h>38#include <linux/iocontext.h>
39#include <linux/key.h>39#include <linux/key.h>
40#include <linux/kmsan.h>
40#include <linux/binfmts.h>41#include <linux/binfmts.h>
41#include <linux/mman.h>42#include <linux/mman.h>
42#include <linux/mmu_notifier.h>43#include <linux/mmu_notifier.h>
43#include <linux/fs.h>44#include <linux/fs.h>
44#include <linux/mm.h>45#include <linux/mm.h>
45#include <linux/mm_inline.h>46#include <linux/mm_inline.h>
46#include <linux/vmacache.h>
47#include <linux/nsproxy.h>47#include <linux/nsproxy.h>
48#include <linux/capability.h>48#include <linux/capability.h>
49#include <linux/cpu.h>49#include <linux/cpu.h>
@@ -475,7 +475,6 @@ struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig) · 425 unmodified lines
475 */475 */
476 *new = data_race(*orig);476 *new = data_race(*orig);
477 INIT_LIST_HEAD(&new->anon_vma_chain);477 INIT_LIST_HEAD(&new->anon_vma_chain);
478 new->vm_next = new->vm_prev = NULL;
479 dup_anon_vma_name(orig, new);478 dup_anon_vma_name(orig, new);
480 }479 }
481 return new;480 return new;
@@ -580,11 +579,12 @@ static void dup_mm_exe_file(struct mm_struct *mm, struct mm_struct *oldmm) · 98 unmodified lines
580static __latent_entropy int dup_mmap(struct mm_struct *mm,579static __latent_entropy int dup_mmap(struct mm_struct *mm,
581 struct mm_struct *oldmm)580 struct mm_struct *oldmm)
582{581{
583 struct vm_area_struct *mpnt, *tmp, *prev, **pprev;582 struct vm_area_struct *mpnt, *tmp;
584 struct rb_node **rb_link, *rb_parent;
585 int retval;583 int retval;
586 unsigned long charge;584 unsigned long charge = 0;
587 LIST_HEAD(uf);585 LIST_HEAD(uf);
586 MA_STATE(old_mas, &oldmm->mm_mt, 0, 0);
587 MA_STATE(mas, &mm->mm_mt, 0, 0);
588 588
589 uprobe_start_dup_mmap();589 uprobe_start_dup_mmap();
590 if (mmap_write_lock_killable(oldmm)) {590 if (mmap_write_lock_killable(oldmm)) {
@@ -606,16 +606,16 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, · 15 unmodified lines
606 mm->exec_vm = oldmm->exec_vm;606 mm->exec_vm = oldmm->exec_vm;
607 mm->stack_vm = oldmm->stack_vm;607 mm->stack_vm = oldmm->stack_vm;
608 608
609 rb_link = &mm->mm_rb.rb_node;
610 rb_parent = NULL;
611 pprev = &mm->mmap;
612 retval = ksm_fork(mm, oldmm);609 retval = ksm_fork(mm, oldmm);
613 if (retval)610 if (retval)
614 goto out;611 goto out;
615 khugepaged_fork(mm, oldmm);612 khugepaged_fork(mm, oldmm);
616 613
617 prev = NULL;614 retval = mas_expected_entries(&mas, oldmm->map_count);
618 for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) {615 if (retval)
616 goto out;
617
618 mas_for_each(&old_mas, mpnt, ULONG_MAX) {
619 struct file *file;619 struct file *file;
620 620
621 if (mpnt->vm_flags & VM_DONTCOPY) {621 if (mpnt->vm_flags & VM_DONTCOPY) {
@@ -629,7 +629,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, · 7 unmodified lines
629 */629 */
630 if (fatal_signal_pending(current)) {630 if (fatal_signal_pending(current)) {
631 retval = -EINTR;631 retval = -EINTR;
632 goto out;632 goto loop_out;
633 }633 }
634 if (mpnt->vm_flags & VM_ACCOUNT) {634 if (mpnt->vm_flags & VM_ACCOUNT) {
635 unsigned long len = vma_pages(mpnt);635 unsigned long len = vma_pages(mpnt);
@@ -675,24 +675,17 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, · 39 unmodified lines
675 }675 }
676 676
677 /*677 /*
678 * Clear hugetlb-related page reserves for children. This only678 * Copy/update hugetlb private vma information.
679 * affects MAP_PRIVATE mappings. Faults generated by the child
680 * are not guaranteed to succeed, even if read-only
681 */679 */
682 if (is_vm_hugetlb_page(tmp))680 if (is_vm_hugetlb_page(tmp))
683 reset_vma_resv_huge_pages(tmp);681 hugetlb_dup_vma_private(tmp);
684
685 /*
686 * Link in the new vma and copy the page table entries.
687 */
688 *pprev = tmp;
689 pprev = &tmp->vm_next;
690 tmp->vm_prev = prev;
691 prev = tmp;
692 682
693 __vma_link_rb(mm, tmp, rb_link, rb_parent);683 /* Link the vma into the MT */
694 rb_link = &tmp->vm_rb.rb_right;684 mas.index = tmp->vm_start;
695 rb_parent = &tmp->vm_rb;685 mas.last = tmp->vm_end - 1;
686 mas_store(&mas, tmp);
687 if (mas_is_err(&mas))
688 goto fail_nomem_mas_store;
696 689
697 mm->map_count++;690 mm->map_count++;
698 if (!(tmp->vm_flags & VM_WIPEONFORK))691 if (!(tmp->vm_flags & VM_WIPEONFORK))
@@ -702,10 +695,12 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, · 3 unmodified lines
702 tmp->vm_ops->open(tmp);695 tmp->vm_ops->open(tmp);
703 696
704 if (retval)697 if (retval)
705 goto out;698 goto loop_out;
706 }699 }
707 /* a new mm has just been created */700 /* a new mm has just been created */
708 retval = arch_dup_mmap(oldmm, mm);701 retval = arch_dup_mmap(oldmm, mm);
702loop_out:
703 mas_destroy(&mas);
709out:704out:
710 mmap_write_unlock(mm);705 mmap_write_unlock(mm);
711 flush_tlb_mm(oldmm);706 flush_tlb_mm(oldmm);
@@ -714,6 +709,9 @@ out: · 2 unmodified lines
714fail_uprobe_end:709fail_uprobe_end:
715 uprobe_end_dup_mmap();710 uprobe_end_dup_mmap();
716 return retval;711 return retval;
712
713fail_nomem_mas_store:
714 unlink_anon_vmas(tmp);
717fail_nomem_anon_vma_fork:715fail_nomem_anon_vma_fork:
718 mpol_put(vma_policy(tmp));716 mpol_put(vma_policy(tmp));
719fail_nomem_policy:717fail_nomem_policy:
@@ -721,7 +719,7 @@ fail_nomem_policy: · 1 unmodified line
721fail_nomem:719fail_nomem:
722 retval = -ENOMEM;720 retval = -ENOMEM;
723 vm_unacct_memory(charge);721 vm_unacct_memory(charge);
724 goto out;722 goto loop_out;
725}723}
726 724
727static inline int mm_alloc_pgd(struct mm_struct *mm)725static inline int mm_alloc_pgd(struct mm_struct *mm)
@@ -1026,6 +1024,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node) · 298 unmodified lines
1026 tsk->worker_private = NULL;1024 tsk->worker_private = NULL;
1027 1025
1028 kcov_task_init(tsk);1026 kcov_task_init(tsk);
1027 kmsan_task_create(tsk);
1029 kmap_local_fork(tsk);1028 kmap_local_fork(tsk);
1030 1029
1031#ifdef CONFIG_FAULT_INJECTION1030#ifdef CONFIG_FAULT_INJECTION
@@ -1109,9 +1108,8 @@ static void mm_init_uprobes_state(struct mm_struct *mm) · 77 unmodified lines
1109static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,1108static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
1110 struct user_namespace *user_ns)1109 struct user_namespace *user_ns)
1111{1110{
1112 mm->mmap = NULL;1111 mt_init_flags(&mm->mm_mt, MM_MT_FLAGS);
1113 mm->mm_rb = RB_ROOT;1112 mt_set_external_lock(&mm->mm_mt, &mm->mmap_lock);
1114 mm->vmacache_seqnum = 0;
1115 atomic_set(&mm->mm_users, 1);1113 atomic_set(&mm->mm_users, 1);
1116 atomic_set(&mm->mm_count, 1);1114 atomic_set(&mm->mm_count, 1);
1117 seqcount_init(&mm->write_protect_seq);1115 seqcount_init(&mm->write_protect_seq);
@@ -1152,6 +1150,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p, · 34 unmodified lines
1152 goto fail_nocontext;1150 goto fail_nocontext;
1153 1151
1154 mm->user_ns = get_user_ns(user_ns);1152 mm->user_ns = get_user_ns(user_ns);
1153 lru_gen_init_mm(mm);
1155 return mm;1154 return mm;
1156 1155
1157fail_nocontext:1156fail_nocontext:
@@ -1194,6 +1193,7 @@ static inline void __mmput(struct mm_struct *mm) · 36 unmodified lines
1194 }1193 }
1195 if (mm->binfmt)1194 if (mm->binfmt)
1196 module_put(mm->binfmt->module);1195 module_put(mm->binfmt->module);
1196 lru_gen_del_mm(mm);
1197 mmdrop(mm);1197 mmdrop(mm);
1198}1198}
1199 1199
@@ -1285,13 +1285,16 @@ int replace_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file) · 85 unmodified lines
1285 /* Forbid mm->exe_file change if old file still mapped. */1285 /* Forbid mm->exe_file change if old file still mapped. */
1286 old_exe_file = get_mm_exe_file(mm);1286 old_exe_file = get_mm_exe_file(mm);
1287 if (old_exe_file) {1287 if (old_exe_file) {
1288 VMA_ITERATOR(vmi, mm, 0);
1288 mmap_read_lock(mm);1289 mmap_read_lock(mm);
1289 for (vma = mm->mmap; vma && !ret; vma = vma->vm_next) {1290 for_each_vma(vmi, vma) {
1290 if (!vma->vm_file)1291 if (!vma->vm_file)
1291 continue;1292 continue;
1292 if (path_equal(&vma->vm_file->f_path,1293 if (path_equal(&vma->vm_file->f_path,
1293 &old_exe_file->f_path))1294 &old_exe_file->f_path)) {
1294 ret = -EBUSY;1295 ret = -EBUSY;
1296 break;
1297 }
1295 }1298 }
1296 mmap_read_unlock(mm);1299 mmap_read_unlock(mm);
1297 fput(old_exe_file);1300 fput(old_exe_file);
@@ -1566,9 +1569,6 @@ static int copy_mm(unsigned long clone_flags, struct task_struct *tsk) · 268 unmodified lines
1566 if (!oldmm)1569 if (!oldmm)
1567 return 0;1570 return 0;
1568 1571
1569 /* initialize the new vmacache entries */
1570 vmacache_flush(tsk);
1571
1572 if (clone_flags & CLONE_VM) {1572 if (clone_flags & CLONE_VM) {
1573 mmget(oldmm);1573 mmget(oldmm);
1574 mm = oldmm;1574 mm = oldmm;
@@ -2693,6 +2693,13 @@ pid_t kernel_clone(struct kernel_clone_args *args) · 1118 unmodified lines
2693 get_task_struct(p);2693 get_task_struct(p);
2694 }2694 }
2695 2695
2696 if (IS_ENABLED(CONFIG_LRU_GEN) && !(clone_flags & CLONE_VM)) {
2697 /* lock the task to synchronize with memcg migration */
2698 task_lock(p);
2699 lru_gen_add_mm(p->mm);
2700 task_unlock(p);
2701 }
2702
2696 wake_up_new_task(p);2703 wake_up_new_task(p);
2697 2704
2698 /* forking complete and child started to run, tell ptracer */2705 /* forking complete and child started to run, tell ptracer */
kernel/kcov.c+7−0
@@ -11,6 +11,7 @@ · 10 unmodified lines
11#include <linux/fs.h>11#include <linux/fs.h>
12#include <linux/hashtable.h>12#include <linux/hashtable.h>
13#include <linux/init.h>13#include <linux/init.h>
14#include <linux/kmsan-checks.h>
14#include <linux/mm.h>15#include <linux/mm.h>
15#include <linux/preempt.h>16#include <linux/preempt.h>
16#include <linux/printk.h>17#include <linux/printk.h>
@@ -152,6 +153,12 @@ static void kcov_remote_area_put(struct kcov_remote_area *area, · 135 unmodified lines
152 INIT_LIST_HEAD(&area->list);153 INIT_LIST_HEAD(&area->list);
153 area->size = size;154 area->size = size;
154 list_add(&area->list, &kcov_remote_areas);155 list_add(&area->list, &kcov_remote_areas);
156 /*
157 * KMSAN doesn't instrument this file, so it may not know area->list
158 * is initialized. Unpoison it explicitly to avoid reports in
159 * kcov_remote_area_get().
160 */
161 kmsan_unpoison_memory(&area->list, sizeof(area->list));
155}162}
156 163
157static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_struct *t)164static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_struct *t)
kernel/locking/Makefile+2−1
@@ -5,8 +5,9 @@ KCOV_INSTRUMENT := n · 4 unmodified lines
5 5
6obj-y += mutex.o semaphore.o rwsem.o percpu-rwsem.o6obj-y += mutex.o semaphore.o rwsem.o percpu-rwsem.o
7 7
8# Avoid recursion lockdep -> KCSAN -> ... -> lockdep.8# Avoid recursion lockdep -> sanitizer -> ... -> lockdep.
9KCSAN_SANITIZE_lockdep.o := n9KCSAN_SANITIZE_lockdep.o := n
10KMSAN_SANITIZE_lockdep.o := n
10 11
11ifdef CONFIG_FUNCTION_TRACER12ifdef CONFIG_FUNCTION_TRACER
12CFLAGS_REMOVE_lockdep.o = $(CC_FLAGS_FTRACE)13CFLAGS_REMOVE_lockdep.o = $(CC_FLAGS_FTRACE)
kernel/sched/core.c+15−0
@@ -4389,6 +4389,17 @@ void set_numabalancing_state(bool enabled) · 4388 unmodified lines
4389}4389}
4390 4390
4391#ifdef CONFIG_PROC_SYSCTL4391#ifdef CONFIG_PROC_SYSCTL
4392static void reset_memory_tiering(void)
4393{
4394 struct pglist_data *pgdat;
4395
4396 for_each_online_pgdat(pgdat) {
4397 pgdat->nbp_threshold = 0;
4398 pgdat->nbp_th_nr_cand = node_page_state(pgdat, PGPROMOTE_CANDIDATE);
4399 pgdat->nbp_th_start = jiffies_to_msecs(jiffies);
4400 }
4401}
4402
4392int sysctl_numa_balancing(struct ctl_table *table, int write,4403int sysctl_numa_balancing(struct ctl_table *table, int write,
4393 void *buffer, size_t *lenp, loff_t *ppos)4404 void *buffer, size_t *lenp, loff_t *ppos)
4394{4405{
@@ -4405,6 +4416,9 @@ int sysctl_numa_balancing(struct ctl_table *table, int write, · 10 unmodified lines
4405 if (err < 0)4416 if (err < 0)
4406 return err;4417 return err;
4407 if (write) {4418 if (write) {
4419 if (!(sysctl_numa_balancing_mode & NUMA_BALANCING_MEMORY_TIERING) &&
4420 (state & NUMA_BALANCING_MEMORY_TIERING))
4421 reset_memory_tiering();
4408 sysctl_numa_balancing_mode = state;4422 sysctl_numa_balancing_mode = state;
4409 __set_numabalancing_state(state);4423 __set_numabalancing_state(state);
4410 }4424 }
@@ -5159,6 +5173,7 @@ context_switch(struct rq *rq, struct task_struct *prev, · 748 unmodified lines
5159 * finish_task_switch()'s mmdrop().5173 * finish_task_switch()'s mmdrop().
5160 */5174 */
5161 switch_mm_irqs_off(prev->active_mm, next->mm, next);5175 switch_mm_irqs_off(prev->active_mm, next->mm, next);
5176 lru_gen_use_mm(next->mm);
5162 5177
5163 if (!prev->mm) { // from kernel5178 if (!prev->mm) { // from kernel
5164 /* will mmdrop() in finish_task_switch(). */5179 /* will mmdrop() in finish_task_switch(). */
kernel/sched/debug.c+1−0
@@ -333,6 +333,7 @@ static __init int sched_init_debug(void) · 332 unmodified lines
333 debugfs_create_u32("scan_period_min_ms", 0644, numa, &sysctl_numa_balancing_scan_period_min);333 debugfs_create_u32("scan_period_min_ms", 0644, numa, &sysctl_numa_balancing_scan_period_min);
334 debugfs_create_u32("scan_period_max_ms", 0644, numa, &sysctl_numa_balancing_scan_period_max);334 debugfs_create_u32("scan_period_max_ms", 0644, numa, &sysctl_numa_balancing_scan_period_max);
335 debugfs_create_u32("scan_size_mb", 0644, numa, &sysctl_numa_balancing_scan_size);335 debugfs_create_u32("scan_size_mb", 0644, numa, &sysctl_numa_balancing_scan_size);
336 debugfs_create_u32("hot_threshold_ms", 0644, numa, &sysctl_numa_balancing_hot_threshold);
336#endif337#endif
337 338
338 debugfs_create_file("debug", 0444, debugfs_sched, NULL, &sched_debug_fops);339 debugfs_create_file("debug", 0444, debugfs_sched, NULL, &sched_debug_fops);
kernel/sched/fair.c+172−3
@@ -40,6 +40,7 @@ · 39 unmodified lines
40 40
41#include <linux/cpuidle.h>41#include <linux/cpuidle.h>
42#include <linux/interrupt.h>42#include <linux/interrupt.h>
43#include <linux/memory-tiers.h>
43#include <linux/mempolicy.h>44#include <linux/mempolicy.h>
44#include <linux/mutex_api.h>45#include <linux/mutex_api.h>
45#include <linux/profile.h>46#include <linux/profile.h>
@@ -1090,6 +1091,12 @@ unsigned int sysctl_numa_balancing_scan_size = 256; · 1044 unmodified lines
1090/* Scan @scan_size MB every @scan_period after an initial @scan_delay in ms */1091/* Scan @scan_size MB every @scan_period after an initial @scan_delay in ms */
1091unsigned int sysctl_numa_balancing_scan_delay = 1000;1092unsigned int sysctl_numa_balancing_scan_delay = 1000;
1092 1093
1094/* The page with hint page fault latency < threshold in ms is considered hot */
1095unsigned int sysctl_numa_balancing_hot_threshold = MSEC_PER_SEC;
1096
1097/* Restrict the NUMA promotion throughput (MB/s) for each target node. */
1098unsigned int sysctl_numa_balancing_promote_rate_limit = 65536;
1099
1093struct numa_group {1100struct numa_group {
1094 refcount_t refcount;1101 refcount_t refcount;
1095 1102
@@ -1432,6 +1439,120 @@ static inline unsigned long group_weight(struct task_struct *p, int nid, · 336 unmodified lines
1432 return 1000 * faults / total_faults;1439 return 1000 * faults / total_faults;
1433}1440}
1434 1441
1442/*
1443 * If memory tiering mode is enabled, cpupid of slow memory page is
1444 * used to record scan time instead of CPU and PID. When tiering mode
1445 * is disabled at run time, the scan time (in cpupid) will be
1446 * interpreted as CPU and PID. So CPU needs to be checked to avoid to
1447 * access out of array bound.
1448 */
1449static inline bool cpupid_valid(int cpupid)
1450{
1451 return cpupid_to_cpu(cpupid) < nr_cpu_ids;
1452}
1453
1454/*
1455 * For memory tiering mode, if there are enough free pages (more than
1456 * enough watermark defined here) in fast memory node, to take full
1457 * advantage of fast memory capacity, all recently accessed slow
1458 * memory pages will be migrated to fast memory node without
1459 * considering hot threshold.
1460 */
1461static bool pgdat_free_space_enough(struct pglist_data *pgdat)
1462{
1463 int z;
1464 unsigned long enough_wmark;
1465
1466 enough_wmark = max(1UL * 1024 * 1024 * 1024 >> PAGE_SHIFT,
1467 pgdat->node_present_pages >> 4);
1468 for (z = pgdat->nr_zones - 1; z >= 0; z--) {
1469 struct zone *zone = pgdat->node_zones + z;
1470
1471 if (!populated_zone(zone))
1472 continue;
1473
1474 if (zone_watermark_ok(zone, 0,
1475 wmark_pages(zone, WMARK_PROMO) + enough_wmark,
1476 ZONE_MOVABLE, 0))
1477 return true;
1478 }
1479 return false;
1480}
1481
1482/*
1483 * For memory tiering mode, when page tables are scanned, the scan
1484 * time will be recorded in struct page in addition to make page
1485 * PROT_NONE for slow memory page. So when the page is accessed, in
1486 * hint page fault handler, the hint page fault latency is calculated
1487 * via,
1488 *
1489 * hint page fault latency = hint page fault time - scan time
1490 *
1491 * The smaller the hint page fault latency, the higher the possibility
1492 * for the page to be hot.
1493 */
1494static int numa_hint_fault_latency(struct page *page)
1495{
1496 int last_time, time;
1497
1498 time = jiffies_to_msecs(jiffies);
1499 last_time = xchg_page_access_time(page, time);
1500
1501 return (time - last_time) & PAGE_ACCESS_TIME_MASK;
1502}
1503
1504/*
1505 * For memory tiering mode, too high promotion/demotion throughput may
1506 * hurt application latency. So we provide a mechanism to rate limit
1507 * the number of pages that are tried to be promoted.
1508 */
1509static bool numa_promotion_rate_limit(struct pglist_data *pgdat,
1510 unsigned long rate_limit, int nr)
1511{
1512 unsigned long nr_cand;
1513 unsigned int now, start;
1514
1515 now = jiffies_to_msecs(jiffies);
1516 mod_node_page_state(pgdat, PGPROMOTE_CANDIDATE, nr);
1517 nr_cand = node_page_state(pgdat, PGPROMOTE_CANDIDATE);
1518 start = pgdat->nbp_rl_start;
1519 if (now - start > MSEC_PER_SEC &&
1520 cmpxchg(&pgdat->nbp_rl_start, start, now) == start)
1521 pgdat->nbp_rl_nr_cand = nr_cand;
1522 if (nr_cand - pgdat->nbp_rl_nr_cand >= rate_limit)
1523 return true;
1524 return false;
1525}
1526
1527#define NUMA_MIGRATION_ADJUST_STEPS 16
1528
1529static void numa_promotion_adjust_threshold(struct pglist_data *pgdat,
1530 unsigned long rate_limit,
1531 unsigned int ref_th)
1532{
1533 unsigned int now, start, th_period, unit_th, th;
1534 unsigned long nr_cand, ref_cand, diff_cand;
1535
1536 now = jiffies_to_msecs(jiffies);
1537 th_period = sysctl_numa_balancing_scan_period_max;
1538 start = pgdat->nbp_th_start;
1539 if (now - start > th_period &&
1540 cmpxchg(&pgdat->nbp_th_start, start, now) == start) {
1541 ref_cand = rate_limit *
1542 sysctl_numa_balancing_scan_period_max / MSEC_PER_SEC;
1543 nr_cand = node_page_state(pgdat, PGPROMOTE_CANDIDATE);
1544 diff_cand = nr_cand - pgdat->nbp_th_nr_cand;
1545 unit_th = ref_th * 2 / NUMA_MIGRATION_ADJUST_STEPS;
1546 th = pgdat->nbp_threshold ? : ref_th;
1547 if (diff_cand > ref_cand * 11 / 10)
1548 th = max(th - unit_th, unit_th);
1549 else if (diff_cand < ref_cand * 9 / 10)
1550 th = min(th + unit_th, ref_th * 2);
1551 pgdat->nbp_th_nr_cand = nr_cand;
1552 pgdat->nbp_threshold = th;
1553 }
1554}
1555
1435bool should_numa_migrate_memory(struct task_struct *p, struct page * page,1556bool should_numa_migrate_memory(struct task_struct *p, struct page * page,
1436 int src_nid, int dst_cpu)1557 int src_nid, int dst_cpu)
1437{1558{
@@ -1439,9 +1560,44 @@ bool should_numa_migrate_memory(struct task_struct *p, struct page * page, · 1 unmodified line
1439 int dst_nid = cpu_to_node(dst_cpu);1560 int dst_nid = cpu_to_node(dst_cpu);
1440 int last_cpupid, this_cpupid;1561 int last_cpupid, this_cpupid;
1441 1562
1563 /*
1564 * The pages in slow memory node should be migrated according
1565 * to hot/cold instead of private/shared.
1566 */
1567 if (sysctl_numa_balancing_mode & NUMA_BALANCING_MEMORY_TIERING &&
1568 !node_is_toptier(src_nid)) {
1569 struct pglist_data *pgdat;
1570 unsigned long rate_limit;
1571 unsigned int latency, th, def_th;
1572
1573 pgdat = NODE_DATA(dst_nid);
1574 if (pgdat_free_space_enough(pgdat)) {
1575 /* workload changed, reset hot threshold */
1576 pgdat->nbp_threshold = 0;
1577 return true;
1578 }
1579
1580 def_th = sysctl_numa_balancing_hot_threshold;
1581 rate_limit = sysctl_numa_balancing_promote_rate_limit << \
1582 (20 - PAGE_SHIFT);
1583 numa_promotion_adjust_threshold(pgdat, rate_limit, def_th);
1584
1585 th = pgdat->nbp_threshold ? : def_th;
1586 latency = numa_hint_fault_latency(page);
1587 if (latency >= th)
1588 return false;
1589
1590 return !numa_promotion_rate_limit(pgdat, rate_limit,
1591 thp_nr_pages(page));
1592 }
1593
1442 this_cpupid = cpu_pid_to_cpupid(dst_cpu, current->pid);1594 this_cpupid = cpu_pid_to_cpupid(dst_cpu, current->pid);
1443 last_cpupid = page_cpupid_xchg_last(page, this_cpupid);1595 last_cpupid = page_cpupid_xchg_last(page, this_cpupid);
1444 1596
1597 if (!(sysctl_numa_balancing_mode & NUMA_BALANCING_MEMORY_TIERING) &&
1598 !node_is_toptier(src_nid) && !cpupid_valid(last_cpupid))
1599 return false;
1600
1445 /*1601 /*
1446 * Allow first faults or private faults to migrate immediately early in1602 * Allow first faults or private faults to migrate immediately early in
1447 * the lifetime of a task. The magic number 4 is based on waiting for1603 * the lifetime of a task. The magic number 4 is based on waiting for
@@ -2681,6 +2837,15 @@ void task_numa_fault(int last_cpupid, int mem_node, int pages, int flags) · 1233 unmodified lines
2681 if (!p->mm)2837 if (!p->mm)
2682 return;2838 return;
2683 2839
2840 /*
2841 * NUMA faults statistics are unnecessary for the slow memory
2842 * node for memory tiering mode.
2843 */
2844 if (!node_is_toptier(mem_node) &&
2845 (sysctl_numa_balancing_mode & NUMA_BALANCING_MEMORY_TIERING ||
2846 !cpupid_valid(last_cpupid)))
2847 return;
2848
2684 /* Allocate buffer to track faults on a per-node basis */2849 /* Allocate buffer to track faults on a per-node basis */
2685 if (unlikely(!p->numa_faults)) {2850 if (unlikely(!p->numa_faults)) {
2686 int size = sizeof(*p->numa_faults) *2851 int size = sizeof(*p->numa_faults) *
@@ -2761,6 +2926,7 @@ static void task_numa_work(struct callback_head *work) · 74 unmodified lines
2761 struct task_struct *p = current;2926 struct task_struct *p = current;
2762 struct mm_struct *mm = p->mm;2927 struct mm_struct *mm = p->mm;
2763 u64 runtime = p->se.sum_exec_runtime;2928 u64 runtime = p->se.sum_exec_runtime;
2929 MA_STATE(mas, &mm->mm_mt, 0, 0);
2764 struct vm_area_struct *vma;2930 struct vm_area_struct *vma;
2765 unsigned long start, end;2931 unsigned long start, end;
2766 unsigned long nr_pte_updates = 0;2932 unsigned long nr_pte_updates = 0;
@@ -2817,13 +2983,16 @@ static void task_numa_work(struct callback_head *work) · 50 unmodified lines
2817 2983
2818 if (!mmap_read_trylock(mm))2984 if (!mmap_read_trylock(mm))
2819 return;2985 return;
2820 vma = find_vma(mm, start);2986 mas_set(&mas, start);
2987 vma = mas_find(&mas, ULONG_MAX);
2821 if (!vma) {2988 if (!vma) {
2822 reset_ptenuma_scan(p);2989 reset_ptenuma_scan(p);
2823 start = 0;2990 start = 0;
2824 vma = mm->mmap;2991 mas_set(&mas, start);
2992 vma = mas_find(&mas, ULONG_MAX);
2825 }2993 }
2826 for (; vma; vma = vma->vm_next) {2994
2995 for (; vma; vma = mas_find(&mas, ULONG_MAX)) {
2827 if (!vma_migratable(vma) || !vma_policy_mof(vma) ||2996 if (!vma_migratable(vma) || !vma_policy_mof(vma) ||
2828 is_vm_hugetlb_page(vma) || (vma->vm_flags & VM_MIXEDMAP)) {2997 is_vm_hugetlb_page(vma) || (vma->vm_flags & VM_MIXEDMAP)) {
2829 continue;2998 continue;
kernel/sched/sched.h+1−0
@@ -2446,6 +2446,7 @@ extern unsigned int sysctl_numa_balancing_scan_delay; · 2445 unmodified lines
2446extern unsigned int sysctl_numa_balancing_scan_period_min;2446extern unsigned int sysctl_numa_balancing_scan_period_min;
2447extern unsigned int sysctl_numa_balancing_scan_period_max;2447extern unsigned int sysctl_numa_balancing_scan_period_max;
2448extern unsigned int sysctl_numa_balancing_scan_size;2448extern unsigned int sysctl_numa_balancing_scan_size;
2449extern unsigned int sysctl_numa_balancing_hot_threshold;
2449#endif2450#endif
2450 2451
2451#ifdef CONFIG_SCHED_HRTICK2452#ifdef CONFIG_SCHED_HRTICK
kernel/sysctl.c+8−0
@@ -1643,6 +1643,14 @@ static struct ctl_table kern_table[] = { · 1642 unmodified lines
1643 .extra1 = SYSCTL_ZERO,1643 .extra1 = SYSCTL_ZERO,
1644 .extra2 = SYSCTL_FOUR,1644 .extra2 = SYSCTL_FOUR,
1645 },1645 },
1646 {
1647 .procname = "numa_balancing_promote_rate_limit_MBps",
1648 .data = &sysctl_numa_balancing_promote_rate_limit,
1649 .maxlen = sizeof(unsigned int),
1650 .mode = 0644,
1651 .proc_handler = proc_dointvec_minmax,
1652 .extra1 = SYSCTL_ZERO,
1653 },
1646#endif /* CONFIG_NUMA_BALANCING */1654#endif /* CONFIG_NUMA_BALANCING */
1647 {1655 {
1648 .procname = "panic",1656 .procname = "panic",
lib/Kconfig.debug+13−5
@@ -817,13 +817,12 @@ config DEBUG_VM · 816 unmodified lines
817 817
818 If unsure, say N.818 If unsure, say N.
819 819
820config DEBUG_VM_VMACACHE820config DEBUG_VM_MAPLE_TREE
821 bool "Debug VMA caching"821 bool "Debug VM maple trees"
822 depends on DEBUG_VM822 depends on DEBUG_VM
823 select DEBUG_MAPLE_TREE
823 help824 help
824 Enable this to turn on VMA caching debug information. Doing so825 Enable VM maple tree debugging information and extra validations.
825 can cause significant overhead, so only enable it in non-production
826 environments.
827 826
828 If unsure, say N.827 If unsure, say N.
829 828
@@ -976,6 +975,7 @@ config DEBUG_STACKOVERFLOW · 146 unmodified lines
976 975
977source "lib/Kconfig.kasan"976source "lib/Kconfig.kasan"
978source "lib/Kconfig.kfence"977source "lib/Kconfig.kfence"
978source "lib/Kconfig.kmsan"
979 979
980endmenu # "Memory Debugging"980endmenu # "Memory Debugging"
981 981
@@ -1640,6 +1640,14 @@ config BUG_ON_DATA_CORRUPTION · 658 unmodified lines
1640 1640
1641 If unsure, say N.1641 If unsure, say N.
1642 1642
1643config DEBUG_MAPLE_TREE
1644 bool "Debug maple trees"
1645 depends on DEBUG_KERNEL
1646 help
1647 Enable maple tree debugging information and extra validations.
1648
1649 If unsure, say N.
1650
1643endmenu1651endmenu
1644 1652
1645config DEBUG_CREDENTIALS1653config DEBUG_CREDENTIALS
lib/Kconfig.kasan+0−8
@@ -167,14 +167,6 @@ config KASAN_STACK · 166 unmodified lines
167 as well, as it adds inline-style instrumentation that is run167 as well, as it adds inline-style instrumentation that is run
168 unconditionally.168 unconditionally.
169 169
170config KASAN_TAGS_IDENTIFY
171 bool "Memory corruption type identification"
172 depends on KASAN_SW_TAGS || KASAN_HW_TAGS
173 help
174 Enables best-effort identification of the bug types (use-after-free
175 or out-of-bounds) at the cost of increased memory consumption.
176 Only applicable for the tag-based KASAN modes.
177
178config KASAN_VMALLOC170config KASAN_VMALLOC
179 bool "Check accesses to vmalloc allocations"171 bool "Check accesses to vmalloc allocations"
180 depends on HAVE_ARCH_KASAN_VMALLOC172 depends on HAVE_ARCH_KASAN_VMALLOC
lib/Kconfig.kmsan+62−0
@@ -0,0 +1,62 @@
1# SPDX-License-Identifier: GPL-2.0-only
2config HAVE_ARCH_KMSAN
3 bool
4
5config HAVE_KMSAN_COMPILER
6 # Clang versions <14.0.0 also support -fsanitize=kernel-memory, but not
7 # all the features necessary to build the kernel with KMSAN.
8 depends on CC_IS_CLANG && CLANG_VERSION >= 140000
9 def_bool $(cc-option,-fsanitize=kernel-memory -mllvm -msan-disable-checks=1)
10
11config KMSAN
12 bool "KMSAN: detector of uninitialized values use"
13 depends on HAVE_ARCH_KMSAN && HAVE_KMSAN_COMPILER
14 depends on SLUB && DEBUG_KERNEL && !KASAN && !KCSAN
15 select STACKDEPOT
16 select STACKDEPOT_ALWAYS_INIT
17 help
18 KernelMemorySanitizer (KMSAN) is a dynamic detector of uses of
19 uninitialized values in the kernel. It is based on compiler
20 instrumentation provided by Clang and thus requires Clang to build.
21
22 An important note is that KMSAN is not intended for production use,
23 because it drastically increases kernel memory footprint and slows
24 the whole system down.
25
26 See <file:Documentation/dev-tools/kmsan.rst> for more details.
27
28if KMSAN
29
30config HAVE_KMSAN_PARAM_RETVAL
31 # -fsanitize-memory-param-retval is supported only by Clang >= 14.
32 depends on HAVE_KMSAN_COMPILER
33 def_bool $(cc-option,-fsanitize=kernel-memory -fsanitize-memory-param-retval)
34
35config KMSAN_CHECK_PARAM_RETVAL
36 bool "Check for uninitialized values passed to and returned from functions"
37 default y
38 depends on HAVE_KMSAN_PARAM_RETVAL
39 help
40 If the compiler supports -fsanitize-memory-param-retval, KMSAN will
41 eagerly check every function parameter passed by value and every
42 function return value.
43
44 Disabling KMSAN_CHECK_PARAM_RETVAL will result in tracking shadow for
45 function parameters and return values across function borders. This
46 is a more relaxed mode, but it generates more instrumentation code and
47 may potentially report errors in corner cases when non-instrumented
48 functions call instrumented ones.
49
50config KMSAN_KUNIT_TEST
51 tristate "KMSAN integration test suite" if !KUNIT_ALL_TESTS
52 default KUNIT_ALL_TESTS
53 depends on TRACEPOINTS && KUNIT
54 help
55 Test suite for KMSAN, testing various error detection scenarios,
56 and checking that reports are correctly output to console.
57
58 Say Y here if you want the test to be built into the kernel and run
59 during boot; say M if you want the test to build as a module; say N
60 if you are unsure.
61
62endif
lib/Makefile+4−6
@@ -29,7 +29,7 @@ endif · 28 unmodified lines
29 29
30lib-y := ctype.o string.o vsprintf.o cmdline.o \30lib-y := ctype.o string.o vsprintf.o cmdline.o \
31 rbtree.o radix-tree.o timerqueue.o xarray.o \31 rbtree.o radix-tree.o timerqueue.o xarray.o \
32 idr.o extable.o irq_regs.o argv_split.o \32 maple_tree.o idr.o extable.o irq_regs.o argv_split.o \
33 flex_proportions.o ratelimit.o show_mem.o \33 flex_proportions.o ratelimit.o show_mem.o \
34 is_single_threaded.o plist.o decompress.o kobject_uevent.o \34 is_single_threaded.o plist.o decompress.o kobject_uevent.o \
35 earlycpio.o seq_buf.o siphash.o dec_and_lock.o \35 earlycpio.o seq_buf.o siphash.o dec_and_lock.o \
@@ -65,11 +65,6 @@ obj-$(CONFIG_TEST_SYSCTL) += test_sysctl.o · 29 unmodified lines
65obj-$(CONFIG_TEST_SIPHASH) += test_siphash.o65obj-$(CONFIG_TEST_SIPHASH) += test_siphash.o
66obj-$(CONFIG_HASH_KUNIT_TEST) += test_hash.o66obj-$(CONFIG_HASH_KUNIT_TEST) += test_hash.o
67obj-$(CONFIG_TEST_IDA) += test_ida.o67obj-$(CONFIG_TEST_IDA) += test_ida.o
68obj-$(CONFIG_KASAN_KUNIT_TEST) += test_kasan.o
69CFLAGS_test_kasan.o += -fno-builtin
70CFLAGS_test_kasan.o += $(call cc-disable-warning, vla)
71obj-$(CONFIG_KASAN_MODULE_TEST) += test_kasan_module.o
72CFLAGS_test_kasan_module.o += -fno-builtin
73obj-$(CONFIG_TEST_UBSAN) += test_ubsan.o68obj-$(CONFIG_TEST_UBSAN) += test_ubsan.o
74CFLAGS_test_ubsan.o += $(call cc-disable-warning, vla)69CFLAGS_test_ubsan.o += $(call cc-disable-warning, vla)
75UBSAN_SANITIZE_test_ubsan.o := y70UBSAN_SANITIZE_test_ubsan.o := y
@@ -275,6 +270,9 @@ obj-$(CONFIG_POLYNOMIAL) += polynomial.o · 199 unmodified lines
275CFLAGS_stackdepot.o += -fno-builtin270CFLAGS_stackdepot.o += -fno-builtin
276obj-$(CONFIG_STACKDEPOT) += stackdepot.o271obj-$(CONFIG_STACKDEPOT) += stackdepot.o
277KASAN_SANITIZE_stackdepot.o := n272KASAN_SANITIZE_stackdepot.o := n
273# In particular, instrumenting stackdepot.c with KMSAN will result in infinite
274# recursion.
275KMSAN_SANITIZE_stackdepot.o := n
278KCOV_INSTRUMENT_stackdepot.o := n276KCOV_INSTRUMENT_stackdepot.o := n
279 277
280obj-$(CONFIG_REF_TRACKER) += ref_tracker.o278obj-$(CONFIG_REF_TRACKER) += ref_tracker.o
lib/iomap.c+44−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
6 */6 */
7#include <linux/pci.h>7#include <linux/pci.h>
8#include <linux/io.h>8#include <linux/io.h>
9#include <linux/kmsan-checks.h>
9 10
10#include <linux/export.h>11#include <linux/export.h>
11 12
@@ -70,26 +71,35 @@ static void bad_io_access(unsigned long port, const char *access) · 58 unmodified lines
70#define mmio_read64be(addr) swab64(readq(addr))71#define mmio_read64be(addr) swab64(readq(addr))
71#endif72#endif
72 73
74/*
75 * Here and below, we apply __no_kmsan_checks to functions reading data from
76 * hardware, to ensure that KMSAN marks their return values as initialized.
77 */
78__no_kmsan_checks
73unsigned int ioread8(const void __iomem *addr)79unsigned int ioread8(const void __iomem *addr)
74{80{
75 IO_COND(addr, return inb(port), return readb(addr));81 IO_COND(addr, return inb(port), return readb(addr));
76 return 0xff;82 return 0xff;
77}83}
84__no_kmsan_checks
78unsigned int ioread16(const void __iomem *addr)85unsigned int ioread16(const void __iomem *addr)
79{86{
80 IO_COND(addr, return inw(port), return readw(addr));87 IO_COND(addr, return inw(port), return readw(addr));
81 return 0xffff;88 return 0xffff;
82}89}
90__no_kmsan_checks
83unsigned int ioread16be(const void __iomem *addr)91unsigned int ioread16be(const void __iomem *addr)
84{92{
85 IO_COND(addr, return pio_read16be(port), return mmio_read16be(addr));93 IO_COND(addr, return pio_read16be(port), return mmio_read16be(addr));
86 return 0xffff;94 return 0xffff;
87}95}
96__no_kmsan_checks
88unsigned int ioread32(const void __iomem *addr)97unsigned int ioread32(const void __iomem *addr)
89{98{
90 IO_COND(addr, return inl(port), return readl(addr));99 IO_COND(addr, return inl(port), return readl(addr));
91 return 0xffffffff;100 return 0xffffffff;
92}101}
102__no_kmsan_checks
93unsigned int ioread32be(const void __iomem *addr)103unsigned int ioread32be(const void __iomem *addr)
94{104{
95 IO_COND(addr, return pio_read32be(port), return mmio_read32be(addr));105 IO_COND(addr, return pio_read32be(port), return mmio_read32be(addr));
@@ -142,18 +152,21 @@ static u64 pio_read64be_hi_lo(unsigned long port) · 46 unmodified lines
142 return lo | (hi << 32);152 return lo | (hi << 32);
143}153}
144 154
155__no_kmsan_checks
145u64 ioread64_lo_hi(const void __iomem *addr)156u64 ioread64_lo_hi(const void __iomem *addr)
146{157{
147 IO_COND(addr, return pio_read64_lo_hi(port), return readq(addr));158 IO_COND(addr, return pio_read64_lo_hi(port), return readq(addr));
148 return 0xffffffffffffffffULL;159 return 0xffffffffffffffffULL;
149}160}
150 161
162__no_kmsan_checks
151u64 ioread64_hi_lo(const void __iomem *addr)163u64 ioread64_hi_lo(const void __iomem *addr)
152{164{
153 IO_COND(addr, return pio_read64_hi_lo(port), return readq(addr));165 IO_COND(addr, return pio_read64_hi_lo(port), return readq(addr));
154 return 0xffffffffffffffffULL;166 return 0xffffffffffffffffULL;
155}167}
156 168
169__no_kmsan_checks
157u64 ioread64be_lo_hi(const void __iomem *addr)170u64 ioread64be_lo_hi(const void __iomem *addr)
158{171{
159 IO_COND(addr, return pio_read64be_lo_hi(port),172 IO_COND(addr, return pio_read64be_lo_hi(port),
@@ -161,6 +174,7 @@ u64 ioread64be_lo_hi(const void __iomem *addr) · 1 unmodified line
161 return 0xffffffffffffffffULL;174 return 0xffffffffffffffffULL;
162}175}
163 176
177__no_kmsan_checks
164u64 ioread64be_hi_lo(const void __iomem *addr)178u64 ioread64be_hi_lo(const void __iomem *addr)
165{179{
166 IO_COND(addr, return pio_read64be_hi_lo(port),180 IO_COND(addr, return pio_read64be_hi_lo(port),
@@ -188,22 +202,32 @@ EXPORT_SYMBOL(ioread64be_hi_lo); · 21 unmodified lines
188 202
189void iowrite8(u8 val, void __iomem *addr)203void iowrite8(u8 val, void __iomem *addr)
190{204{
205 /* Make sure uninitialized memory isn't copied to devices. */
206 kmsan_check_memory(&val, sizeof(val));
191 IO_COND(addr, outb(val,port), writeb(val, addr));207 IO_COND(addr, outb(val,port), writeb(val, addr));
192}208}
193void iowrite16(u16 val, void __iomem *addr)209void iowrite16(u16 val, void __iomem *addr)
194{210{
211 /* Make sure uninitialized memory isn't copied to devices. */
212 kmsan_check_memory(&val, sizeof(val));
195 IO_COND(addr, outw(val,port), writew(val, addr));213 IO_COND(addr, outw(val,port), writew(val, addr));
196}214}
197void iowrite16be(u16 val, void __iomem *addr)215void iowrite16be(u16 val, void __iomem *addr)
198{216{
217 /* Make sure uninitialized memory isn't copied to devices. */
218 kmsan_check_memory(&val, sizeof(val));
199 IO_COND(addr, pio_write16be(val,port), mmio_write16be(val, addr));219 IO_COND(addr, pio_write16be(val,port), mmio_write16be(val, addr));
200}220}
201void iowrite32(u32 val, void __iomem *addr)221void iowrite32(u32 val, void __iomem *addr)
202{222{
223 /* Make sure uninitialized memory isn't copied to devices. */
224 kmsan_check_memory(&val, sizeof(val));
203 IO_COND(addr, outl(val,port), writel(val, addr));225 IO_COND(addr, outl(val,port), writel(val, addr));
204}226}
205void iowrite32be(u32 val, void __iomem *addr)227void iowrite32be(u32 val, void __iomem *addr)
206{228{
229 /* Make sure uninitialized memory isn't copied to devices. */
230 kmsan_check_memory(&val, sizeof(val));
207 IO_COND(addr, pio_write32be(val,port), mmio_write32be(val, addr));231 IO_COND(addr, pio_write32be(val,port), mmio_write32be(val, addr));
208}232}
209EXPORT_SYMBOL(iowrite8);233EXPORT_SYMBOL(iowrite8);
@@ -239,24 +263,32 @@ static void pio_write64be_hi_lo(u64 val, unsigned long port) · 29 unmodified lines
239 263
240void iowrite64_lo_hi(u64 val, void __iomem *addr)264void iowrite64_lo_hi(u64 val, void __iomem *addr)
241{265{
266 /* Make sure uninitialized memory isn't copied to devices. */
267 kmsan_check_memory(&val, sizeof(val));
242 IO_COND(addr, pio_write64_lo_hi(val, port),268 IO_COND(addr, pio_write64_lo_hi(val, port),
243 writeq(val, addr));269 writeq(val, addr));
244}270}
245 271
246void iowrite64_hi_lo(u64 val, void __iomem *addr)272void iowrite64_hi_lo(u64 val, void __iomem *addr)
247{273{
274 /* Make sure uninitialized memory isn't copied to devices. */
275 kmsan_check_memory(&val, sizeof(val));
248 IO_COND(addr, pio_write64_hi_lo(val, port),276 IO_COND(addr, pio_write64_hi_lo(val, port),
249 writeq(val, addr));277 writeq(val, addr));
250}278}
251 279
252void iowrite64be_lo_hi(u64 val, void __iomem *addr)280void iowrite64be_lo_hi(u64 val, void __iomem *addr)
253{281{
282 /* Make sure uninitialized memory isn't copied to devices. */
283 kmsan_check_memory(&val, sizeof(val));
254 IO_COND(addr, pio_write64be_lo_hi(val, port),284 IO_COND(addr, pio_write64be_lo_hi(val, port),
255 mmio_write64be(val, addr));285 mmio_write64be(val, addr));
256}286}
257 287
258void iowrite64be_hi_lo(u64 val, void __iomem *addr)288void iowrite64be_hi_lo(u64 val, void __iomem *addr)
259{289{
290 /* Make sure uninitialized memory isn't copied to devices. */
291 kmsan_check_memory(&val, sizeof(val));
260 IO_COND(addr, pio_write64be_hi_lo(val, port),292 IO_COND(addr, pio_write64be_hi_lo(val, port),
261 mmio_write64be(val, addr));293 mmio_write64be(val, addr));
262}294}
@@ -328,14 +360,20 @@ static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count) · 65 unmodified lines
328void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count)360void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count)
329{361{
330 IO_COND(addr, insb(port,dst,count), mmio_insb(addr, dst, count));362 IO_COND(addr, insb(port,dst,count), mmio_insb(addr, dst, count));
363 /* KMSAN must treat values read from devices as initialized. */
364 kmsan_unpoison_memory(dst, count);
331}365}
332void ioread16_rep(const void __iomem *addr, void *dst, unsigned long count)366void ioread16_rep(const void __iomem *addr, void *dst, unsigned long count)
333{367{
334 IO_COND(addr, insw(port,dst,count), mmio_insw(addr, dst, count));368 IO_COND(addr, insw(port,dst,count), mmio_insw(addr, dst, count));
369 /* KMSAN must treat values read from devices as initialized. */
370 kmsan_unpoison_memory(dst, count * 2);
335}371}
336void ioread32_rep(const void __iomem *addr, void *dst, unsigned long count)372void ioread32_rep(const void __iomem *addr, void *dst, unsigned long count)
337{373{
338 IO_COND(addr, insl(port,dst,count), mmio_insl(addr, dst, count));374 IO_COND(addr, insl(port,dst,count), mmio_insl(addr, dst, count));
375 /* KMSAN must treat values read from devices as initialized. */
376 kmsan_unpoison_memory(dst, count * 4);
339}377}
340EXPORT_SYMBOL(ioread8_rep);378EXPORT_SYMBOL(ioread8_rep);
341EXPORT_SYMBOL(ioread16_rep);379EXPORT_SYMBOL(ioread16_rep);
@@ -343,14 +381,20 @@ EXPORT_SYMBOL(ioread32_rep); · 1 unmodified line
343 381
344void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)382void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
345{383{
384 /* Make sure uninitialized memory isn't copied to devices. */
385 kmsan_check_memory(src, count);
346 IO_COND(addr, outsb(port, src, count), mmio_outsb(addr, src, count));386 IO_COND(addr, outsb(port, src, count), mmio_outsb(addr, src, count));
347}387}
348void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)388void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
349{389{
390 /* Make sure uninitialized memory isn't copied to devices. */
391 kmsan_check_memory(src, count * 2);
350 IO_COND(addr, outsw(port, src, count), mmio_outsw(addr, src, count));392 IO_COND(addr, outsw(port, src, count), mmio_outsw(addr, src, count));
351}393}
352void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)394void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
353{395{
396 /* Make sure uninitialized memory isn't copied to devices. */
397 kmsan_check_memory(src, count * 4);
354 IO_COND(addr, outsl(port, src,count), mmio_outsl(addr, src, count));398 IO_COND(addr, outsl(port, src,count), mmio_outsl(addr, src, count));
355}399}
356EXPORT_SYMBOL(iowrite8_rep);400EXPORT_SYMBOL(iowrite8_rep);
lib/iov_iter.c+6−3
@@ -174,13 +174,16 @@ static int copyout(void __user *to, const void *from, size_t n) · 173 unmodified lines
174 174
175static int copyin(void *to, const void __user *from, size_t n)175static int copyin(void *to, const void __user *from, size_t n)
176{176{
177 size_t res = n;
178
177 if (should_fail_usercopy())179 if (should_fail_usercopy())
178 return n;180 return n;
179 if (access_ok(from, n)) {181 if (access_ok(from, n)) {
180 instrument_copy_from_user(to, from, n);182 instrument_copy_from_user_before(to, from, n);
181 n = raw_copy_from_user(to, from, n);183 res = raw_copy_from_user(to, from, n);
184 instrument_copy_from_user_after(to, from, n, res);
182 }185 }
183 return n;186 return res;
184}187}
185 188
186static inline struct pipe_buffer *pipe_buf(const struct pipe_inode_info *pipe,189static inline struct pipe_buffer *pipe_buf(const struct pipe_inode_info *pipe,
lib/maple_tree.c+7130−0
@@ -0,0 +1,7130 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Maple Tree implementation
4 * Copyright (c) 2018-2022 Oracle Corporation
5 * Authors: Liam R. Howlett <Liam.Howlett@oracle.com>
6 * Matthew Wilcox <willy@infradead.org>
7 */
8
9/*
10 * DOC: Interesting implementation details of the Maple Tree
11 *
12 * Each node type has a number of slots for entries and a number of slots for
13 * pivots. In the case of dense nodes, the pivots are implied by the position
14 * and are simply the slot index + the minimum of the node.
15 *
16 * In regular B-Tree terms, pivots are called keys. The term pivot is used to
17 * indicate that the tree is specifying ranges, Pivots may appear in the
18 * subtree with an entry attached to the value where as keys are unique to a
19 * specific position of a B-tree. Pivot values are inclusive of the slot with
20 * the same index.
21 *
22 *
23 * The following illustrates the layout of a range64 nodes slots and pivots.
24 *
25 *
26 * Slots -> | 0 | 1 | 2 | ... | 12 | 13 | 14 | 15 |
27 * ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬ ┬
28 * │ │ │ │ │ │ │ │ └─ Implied maximum
29 * │ │ │ │ │ │ │ └─ Pivot 14
30 * │ │ │ │ │ │ └─ Pivot 13
31 * │ │ │ │ │ └─ Pivot 12
32 * │ │ │ │ └─ Pivot 11
33 * │ │ │ └─ Pivot 2
34 * │ │ └─ Pivot 1
35 * │ └─ Pivot 0
36 * └─ Implied minimum
37 *
38 * Slot contents:
39 * Internal (non-leaf) nodes contain pointers to other nodes.
40 * Leaf nodes contain entries.
41 *
42 * The location of interest is often referred to as an offset. All offsets have
43 * a slot, but the last offset has an implied pivot from the node above (or
44 * UINT_MAX for the root node.
45 *
46 * Ranges complicate certain write activities. When modifying any of
47 * the B-tree variants, it is known that one entry will either be added or
48 * deleted. When modifying the Maple Tree, one store operation may overwrite
49 * the entire data set, or one half of the tree, or the middle half of the tree.
50 *
51 */
52
53
54#include <linux/maple_tree.h>
55#include <linux/xarray.h>
56#include <linux/types.h>
57#include <linux/export.h>
58#include <linux/slab.h>
59#include <linux/limits.h>
60#include <asm/barrier.h>
61
62#define CREATE_TRACE_POINTS
63#include <trace/events/maple_tree.h>
64
65#define MA_ROOT_PARENT 1
66
67/*
68 * Maple state flags
69 * * MA_STATE_BULK - Bulk insert mode
70 * * MA_STATE_REBALANCE - Indicate a rebalance during bulk insert
71 * * MA_STATE_PREALLOC - Preallocated nodes, WARN_ON allocation
72 */
73#define MA_STATE_BULK 1
74#define MA_STATE_REBALANCE 2
75#define MA_STATE_PREALLOC 4
76
77#define ma_parent_ptr(x) ((struct maple_pnode *)(x))
78#define ma_mnode_ptr(x) ((struct maple_node *)(x))
79#define ma_enode_ptr(x) ((struct maple_enode *)(x))
80static struct kmem_cache *maple_node_cache;
81
82#ifdef CONFIG_DEBUG_MAPLE_TREE
83static const unsigned long mt_max[] = {
84 [maple_dense] = MAPLE_NODE_SLOTS,
85 [maple_leaf_64] = ULONG_MAX,
86 [maple_range_64] = ULONG_MAX,
87 [maple_arange_64] = ULONG_MAX,
88};
89#define mt_node_max(x) mt_max[mte_node_type(x)]
90#endif
91
92static const unsigned char mt_slots[] = {
93 [maple_dense] = MAPLE_NODE_SLOTS,
94 [maple_leaf_64] = MAPLE_RANGE64_SLOTS,
95 [maple_range_64] = MAPLE_RANGE64_SLOTS,
96 [maple_arange_64] = MAPLE_ARANGE64_SLOTS,
97};
98#define mt_slot_count(x) mt_slots[mte_node_type(x)]
99
100static const unsigned char mt_pivots[] = {
101 [maple_dense] = 0,
102 [maple_leaf_64] = MAPLE_RANGE64_SLOTS - 1,
103 [maple_range_64] = MAPLE_RANGE64_SLOTS - 1,
104 [maple_arange_64] = MAPLE_ARANGE64_SLOTS - 1,
105};
106#define mt_pivot_count(x) mt_pivots[mte_node_type(x)]
107
108static const unsigned char mt_min_slots[] = {
109 [maple_dense] = MAPLE_NODE_SLOTS / 2,
110 [maple_leaf_64] = (MAPLE_RANGE64_SLOTS / 2) - 2,
111 [maple_range_64] = (MAPLE_RANGE64_SLOTS / 2) - 2,
112 [maple_arange_64] = (MAPLE_ARANGE64_SLOTS / 2) - 1,
113};
114#define mt_min_slot_count(x) mt_min_slots[mte_node_type(x)]
115
116#define MAPLE_BIG_NODE_SLOTS (MAPLE_RANGE64_SLOTS * 2 + 2)
117#define MAPLE_BIG_NODE_GAPS (MAPLE_ARANGE64_SLOTS * 2 + 1)
118
119struct maple_big_node {
120 struct maple_pnode *parent;
121 unsigned long pivot[MAPLE_BIG_NODE_SLOTS - 1];
122 union {
123 struct maple_enode *slot[MAPLE_BIG_NODE_SLOTS];
124 struct {
125 unsigned long padding[MAPLE_BIG_NODE_GAPS];
126 unsigned long gap[MAPLE_BIG_NODE_GAPS];
127 };
128 };
129 unsigned char b_end;
130 enum maple_type type;
131};
132
133/*
134 * The maple_subtree_state is used to build a tree to replace a segment of an
135 * existing tree in a more atomic way. Any walkers of the older tree will hit a
136 * dead node and restart on updates.
137 */
138struct maple_subtree_state {
139 struct ma_state *orig_l; /* Original left side of subtree */
140 struct ma_state *orig_r; /* Original right side of subtree */
141 struct ma_state *l; /* New left side of subtree */
142 struct ma_state *m; /* New middle of subtree (rare) */
143 struct ma_state *r; /* New right side of subtree */
144 struct ma_topiary *free; /* nodes to be freed */
145 struct ma_topiary *destroy; /* Nodes to be destroyed (walked and freed) */
146 struct maple_big_node *bn;
147};
148
149/* Functions */
150static inline struct maple_node *mt_alloc_one(gfp_t gfp)
151{
152 return kmem_cache_alloc(maple_node_cache, gfp | __GFP_ZERO);
153}
154
155static inline int mt_alloc_bulk(gfp_t gfp, size_t size, void **nodes)
156{
157 return kmem_cache_alloc_bulk(maple_node_cache, gfp | __GFP_ZERO, size,
158 nodes);
159}
160
161static inline void mt_free_bulk(size_t size, void __rcu **nodes)
162{
163 kmem_cache_free_bulk(maple_node_cache, size, (void **)nodes);
164}
165
166static void mt_free_rcu(struct rcu_head *head)
167{
168 struct maple_node *node = container_of(head, struct maple_node, rcu);
169
170 kmem_cache_free(maple_node_cache, node);
171}
172
173/*
174 * ma_free_rcu() - Use rcu callback to free a maple node
175 * @node: The node to free
176 *
177 * The maple tree uses the parent pointer to indicate this node is no longer in
178 * use and will be freed.
179 */
180static void ma_free_rcu(struct maple_node *node)
181{
182 node->parent = ma_parent_ptr(node);
183 call_rcu(&node->rcu, mt_free_rcu);
184}
185
186static unsigned int mt_height(const struct maple_tree *mt)
187{
188 return (mt->ma_flags & MT_FLAGS_HEIGHT_MASK) >> MT_FLAGS_HEIGHT_OFFSET;
189}
190
191static void mas_set_height(struct ma_state *mas)
192{
193 unsigned int new_flags = mas->tree->ma_flags;
194
195 new_flags &= ~MT_FLAGS_HEIGHT_MASK;
196 BUG_ON(mas->depth > MAPLE_HEIGHT_MAX);
197 new_flags |= mas->depth << MT_FLAGS_HEIGHT_OFFSET;
198 mas->tree->ma_flags = new_flags;
199}
200
201static unsigned int mas_mt_height(struct ma_state *mas)
202{
203 return mt_height(mas->tree);
204}
205
206static inline enum maple_type mte_node_type(const struct maple_enode *entry)
207{
208 return ((unsigned long)entry >> MAPLE_NODE_TYPE_SHIFT) &
209 MAPLE_NODE_TYPE_MASK;
210}
211
212static inline bool ma_is_dense(const enum maple_type type)
213{
214 return type < maple_leaf_64;
215}
216
217static inline bool ma_is_leaf(const enum maple_type type)
218{
219 return type < maple_range_64;
220}
221
222static inline bool mte_is_leaf(const struct maple_enode *entry)
223{
224 return ma_is_leaf(mte_node_type(entry));
225}
226
227/*
228 * We also reserve values with the bottom two bits set to '10' which are
229 * below 4096
230 */
231static inline bool mt_is_reserved(const void *entry)
232{
233 return ((unsigned long)entry < MAPLE_RESERVED_RANGE) &&
234 xa_is_internal(entry);
235}
236
237static inline void mas_set_err(struct ma_state *mas, long err)
238{
239 mas->node = MA_ERROR(err);
240}
241
242static inline bool mas_is_ptr(struct ma_state *mas)
243{
244 return mas->node == MAS_ROOT;
245}
246
247static inline bool mas_is_start(struct ma_state *mas)
248{
249 return mas->node == MAS_START;
250}
251
252bool mas_is_err(struct ma_state *mas)
253{
254 return xa_is_err(mas->node);
255}
256
257static inline bool mas_searchable(struct ma_state *mas)
258{
259 if (mas_is_none(mas))
260 return false;
261
262 if (mas_is_ptr(mas))
263 return false;
264
265 return true;
266}
267
268static inline struct maple_node *mte_to_node(const struct maple_enode *entry)
269{
270 return (struct maple_node *)((unsigned long)entry & ~MAPLE_NODE_MASK);
271}
272
273/*
274 * mte_to_mat() - Convert a maple encoded node to a maple topiary node.
275 * @entry: The maple encoded node
276 *
277 * Return: a maple topiary pointer
278 */
279static inline struct maple_topiary *mte_to_mat(const struct maple_enode *entry)
280{
281 return (struct maple_topiary *)
282 ((unsigned long)entry & ~MAPLE_NODE_MASK);
283}
284
285/*
286 * mas_mn() - Get the maple state node.
287 * @mas: The maple state
288 *
289 * Return: the maple node (not encoded - bare pointer).
290 */
291static inline struct maple_node *mas_mn(const struct ma_state *mas)
292{
293 return mte_to_node(mas->node);
294}
295
296/*
297 * mte_set_node_dead() - Set a maple encoded node as dead.
298 * @mn: The maple encoded node.
299 */
300static inline void mte_set_node_dead(struct maple_enode *mn)
301{
302 mte_to_node(mn)->parent = ma_parent_ptr(mte_to_node(mn));
303 smp_wmb(); /* Needed for RCU */
304}
305
306/* Bit 1 indicates the root is a node */
307#define MAPLE_ROOT_NODE 0x02
308/* maple_type stored bit 3-6 */
309#define MAPLE_ENODE_TYPE_SHIFT 0x03
310/* Bit 2 means a NULL somewhere below */
311#define MAPLE_ENODE_NULL 0x04
312
313static inline struct maple_enode *mt_mk_node(const struct maple_node *node,
314 enum maple_type type)
315{
316 return (void *)((unsigned long)node |
317 (type << MAPLE_ENODE_TYPE_SHIFT) | MAPLE_ENODE_NULL);
318}
319
320static inline void *mte_mk_root(const struct maple_enode *node)
321{
322 return (void *)((unsigned long)node | MAPLE_ROOT_NODE);
323}
324
325static inline void *mte_safe_root(const struct maple_enode *node)
326{
327 return (void *)((unsigned long)node & ~MAPLE_ROOT_NODE);
328}
329
330static inline void mte_set_full(const struct maple_enode *node)
331{
332 node = (void *)((unsigned long)node & ~MAPLE_ENODE_NULL);
333}
334
335static inline void mte_clear_full(const struct maple_enode *node)
336{
337 node = (void *)((unsigned long)node | MAPLE_ENODE_NULL);
338}
339
340static inline bool ma_is_root(struct maple_node *node)
341{
342 return ((unsigned long)node->parent & MA_ROOT_PARENT);
343}
344
345static inline bool mte_is_root(const struct maple_enode *node)
346{
347 return ma_is_root(mte_to_node(node));
348}
349
350static inline bool mas_is_root_limits(const struct ma_state *mas)
351{
352 return !mas->min && mas->max == ULONG_MAX;
353}
354
355static inline bool mt_is_alloc(struct maple_tree *mt)
356{
357 return (mt->ma_flags & MT_FLAGS_ALLOC_RANGE);
358}
359
360/*
361 * The Parent Pointer
362 * Excluding root, the parent pointer is 256B aligned like all other tree nodes.
363 * When storing a 32 or 64 bit values, the offset can fit into 5 bits. The 16
364 * bit values need an extra bit to store the offset. This extra bit comes from
365 * a reuse of the last bit in the node type. This is possible by using bit 1 to
366 * indicate if bit 2 is part of the type or the slot.
367 *
368 * Note types:
369 * 0x??1 = Root
370 * 0x?00 = 16 bit nodes
371 * 0x010 = 32 bit nodes
372 * 0x110 = 64 bit nodes
373 *
374 * Slot size and alignment
375 * 0b??1 : Root
376 * 0b?00 : 16 bit values, type in 0-1, slot in 2-7
377 * 0b010 : 32 bit values, type in 0-2, slot in 3-7
378 * 0b110 : 64 bit values, type in 0-2, slot in 3-7
379 */
380
381#define MAPLE_PARENT_ROOT 0x01
382
383#define MAPLE_PARENT_SLOT_SHIFT 0x03
384#define MAPLE_PARENT_SLOT_MASK 0xF8
385
386#define MAPLE_PARENT_16B_SLOT_SHIFT 0x02
387#define MAPLE_PARENT_16B_SLOT_MASK 0xFC
388
389#define MAPLE_PARENT_RANGE64 0x06
390#define MAPLE_PARENT_RANGE32 0x04
391#define MAPLE_PARENT_NOT_RANGE16 0x02
392
393/*
394 * mte_parent_shift() - Get the parent shift for the slot storage.
395 * @parent: The parent pointer cast as an unsigned long
396 * Return: The shift into that pointer to the star to of the slot
397 */
398static inline unsigned long mte_parent_shift(unsigned long parent)
399{
400 /* Note bit 1 == 0 means 16B */
401 if (likely(parent & MAPLE_PARENT_NOT_RANGE16))
402 return MAPLE_PARENT_SLOT_SHIFT;
403
404 return MAPLE_PARENT_16B_SLOT_SHIFT;
405}
406
407/*
408 * mte_parent_slot_mask() - Get the slot mask for the parent.
409 * @parent: The parent pointer cast as an unsigned long.
410 * Return: The slot mask for that parent.
411 */
412static inline unsigned long mte_parent_slot_mask(unsigned long parent)
413{
414 /* Note bit 1 == 0 means 16B */
415 if (likely(parent & MAPLE_PARENT_NOT_RANGE16))
416 return MAPLE_PARENT_SLOT_MASK;
417
418 return MAPLE_PARENT_16B_SLOT_MASK;
419}
420
421/*
422 * mas_parent_enum() - Return the maple_type of the parent from the stored
423 * parent type.
424 * @mas: The maple state
425 * @node: The maple_enode to extract the parent's enum
426 * Return: The node->parent maple_type
427 */
428static inline
429enum maple_type mte_parent_enum(struct maple_enode *p_enode,
430 struct maple_tree *mt)
431{
432 unsigned long p_type;
433
434 p_type = (unsigned long)p_enode;
435 if (p_type & MAPLE_PARENT_ROOT)
436 return 0; /* Validated in the caller. */
437
438 p_type &= MAPLE_NODE_MASK;
439 p_type = p_type & ~(MAPLE_PARENT_ROOT | mte_parent_slot_mask(p_type));
440
441 switch (p_type) {
442 case MAPLE_PARENT_RANGE64: /* or MAPLE_PARENT_ARANGE64 */
443 if (mt_is_alloc(mt))
444 return maple_arange_64;
445 return maple_range_64;
446 }
447
448 return 0;
449}
450
451static inline
452enum maple_type mas_parent_enum(struct ma_state *mas, struct maple_enode *enode)
453{
454 return mte_parent_enum(ma_enode_ptr(mte_to_node(enode)->parent), mas->tree);
455}
456
457/*
458 * mte_set_parent() - Set the parent node and encode the slot
459 * @enode: The encoded maple node.
460 * @parent: The encoded maple node that is the parent of @enode.
461 * @slot: The slot that @enode resides in @parent.
462 *
463 * Slot number is encoded in the enode->parent bit 3-6 or 2-6, depending on the
464 * parent type.
465 */
466static inline
467void mte_set_parent(struct maple_enode *enode, const struct maple_enode *parent,
468 unsigned char slot)
469{
470 unsigned long val = (unsigned long) parent;
471 unsigned long shift;
472 unsigned long type;
473 enum maple_type p_type = mte_node_type(parent);
474
475 BUG_ON(p_type == maple_dense);
476 BUG_ON(p_type == maple_leaf_64);
477
478 switch (p_type) {
479 case maple_range_64:
480 case maple_arange_64:
481 shift = MAPLE_PARENT_SLOT_SHIFT;
482 type = MAPLE_PARENT_RANGE64;
483 break;
484 default:
485 case maple_dense:
486 case maple_leaf_64:
487 shift = type = 0;
488 break;
489 }
490
491 val &= ~MAPLE_NODE_MASK; /* Clear all node metadata in parent */
492 val |= (slot << shift) | type;
493 mte_to_node(enode)->parent = ma_parent_ptr(val);
494}
495
496/*
497 * mte_parent_slot() - get the parent slot of @enode.
498 * @enode: The encoded maple node.
499 *
500 * Return: The slot in the parent node where @enode resides.
501 */
502static inline unsigned int mte_parent_slot(const struct maple_enode *enode)
503{
504 unsigned long val = (unsigned long) mte_to_node(enode)->parent;
505
506 /* Root. */
507 if (val & 1)
508 return 0;
509
510 /*
511 * Okay to use MAPLE_PARENT_16B_SLOT_MASK as the last bit will be lost
512 * by shift if the parent shift is MAPLE_PARENT_SLOT_SHIFT
513 */
514 return (val & MAPLE_PARENT_16B_SLOT_MASK) >> mte_parent_shift(val);
515}
516
517/*
518 * mte_parent() - Get the parent of @node.
519 * @node: The encoded maple node.
520 *
521 * Return: The parent maple node.
522 */
523static inline struct maple_node *mte_parent(const struct maple_enode *enode)
524{
525 return (void *)((unsigned long)
526 (mte_to_node(enode)->parent) & ~MAPLE_NODE_MASK);
527}
528
529/*
530 * ma_dead_node() - check if the @enode is dead.
531 * @enode: The encoded maple node
532 *
533 * Return: true if dead, false otherwise.
534 */
535static inline bool ma_dead_node(const struct maple_node *node)
536{
537 struct maple_node *parent = (void *)((unsigned long)
538 node->parent & ~MAPLE_NODE_MASK);
539
540 return (parent == node);
541}
542/*
543 * mte_dead_node() - check if the @enode is dead.
544 * @enode: The encoded maple node
545 *
546 * Return: true if dead, false otherwise.
547 */
548static inline bool mte_dead_node(const struct maple_enode *enode)
549{
550 struct maple_node *parent, *node;
551
552 node = mte_to_node(enode);
553 parent = mte_parent(enode);
554 return (parent == node);
555}
556
557/*
558 * mas_allocated() - Get the number of nodes allocated in a maple state.
559 * @mas: The maple state
560 *
561 * The ma_state alloc member is overloaded to hold a pointer to the first
562 * allocated node or to the number of requested nodes to allocate. If bit 0 is
563 * set, then the alloc contains the number of requested nodes. If there is an
564 * allocated node, then the total allocated nodes is in that node.
565 *
566 * Return: The total number of nodes allocated
567 */
568static inline unsigned long mas_allocated(const struct ma_state *mas)
569{
570 if (!mas->alloc || ((unsigned long)mas->alloc & 0x1))
571 return 0;
572
573 return mas->alloc->total;
574}
575
576/*
577 * mas_set_alloc_req() - Set the requested number of allocations.
578 * @mas: the maple state
579 * @count: the number of allocations.
580 *
581 * The requested number of allocations is either in the first allocated node,
582 * located in @mas->alloc->request_count, or directly in @mas->alloc if there is
583 * no allocated node. Set the request either in the node or do the necessary
584 * encoding to store in @mas->alloc directly.
585 */
586static inline void mas_set_alloc_req(struct ma_state *mas, unsigned long count)
587{
588 if (!mas->alloc || ((unsigned long)mas->alloc & 0x1)) {
589 if (!count)
590 mas->alloc = NULL;
591 else
592 mas->alloc = (struct maple_alloc *)(((count) << 1U) | 1U);
593 return;
594 }
595
596 mas->alloc->request_count = count;
597}
598
599/*
600 * mas_alloc_req() - get the requested number of allocations.
601 * @mas: The maple state
602 *
603 * The alloc count is either stored directly in @mas, or in
604 * @mas->alloc->request_count if there is at least one node allocated. Decode
605 * the request count if it's stored directly in @mas->alloc.
606 *
607 * Return: The allocation request count.
608 */
609static inline unsigned int mas_alloc_req(const struct ma_state *mas)
610{
611 if ((unsigned long)mas->alloc & 0x1)
612 return (unsigned long)(mas->alloc) >> 1;
613 else if (mas->alloc)
614 return mas->alloc->request_count;
615 return 0;
616}
617
618/*
619 * ma_pivots() - Get a pointer to the maple node pivots.
620 * @node - the maple node
621 * @type - the node type
622 *
623 * Return: A pointer to the maple node pivots
624 */
625static inline unsigned long *ma_pivots(struct maple_node *node,
626 enum maple_type type)
627{
628 switch (type) {
629 case maple_arange_64:
630 return node->ma64.pivot;
631 case maple_range_64:
632 case maple_leaf_64:
633 return node->mr64.pivot;
634 case maple_dense:
635 return NULL;
636 }
637 return NULL;
638}
639
640/*
641 * ma_gaps() - Get a pointer to the maple node gaps.
642 * @node - the maple node
643 * @type - the node type
644 *
645 * Return: A pointer to the maple node gaps
646 */
647static inline unsigned long *ma_gaps(struct maple_node *node,
648 enum maple_type type)
649{
650 switch (type) {
651 case maple_arange_64:
652 return node->ma64.gap;
653 case maple_range_64:
654 case maple_leaf_64:
655 case maple_dense:
656 return NULL;
657 }
658 return NULL;
659}
660
661/*
662 * mte_pivot() - Get the pivot at @piv of the maple encoded node.
663 * @mn: The maple encoded node.
664 * @piv: The pivot.
665 *
666 * Return: the pivot at @piv of @mn.
667 */
668static inline unsigned long mte_pivot(const struct maple_enode *mn,
669 unsigned char piv)
670{
671 struct maple_node *node = mte_to_node(mn);
672
673 if (piv >= mt_pivots[piv]) {
674 WARN_ON(1);
675 return 0;
676 }
677 switch (mte_node_type(mn)) {
678 case maple_arange_64:
679 return node->ma64.pivot[piv];
680 case maple_range_64:
681 case maple_leaf_64:
682 return node->mr64.pivot[piv];
683 case maple_dense:
684 return 0;
685 }
686 return 0;
687}
688
689/*
690 * mas_safe_pivot() - get the pivot at @piv or mas->max.
691 * @mas: The maple state
692 * @pivots: The pointer to the maple node pivots
693 * @piv: The pivot to fetch
694 * @type: The maple node type
695 *
696 * Return: The pivot at @piv within the limit of the @pivots array, @mas->max
697 * otherwise.
698 */
699static inline unsigned long
700mas_safe_pivot(const struct ma_state *mas, unsigned long *pivots,
701 unsigned char piv, enum maple_type type)
702{
703 if (piv >= mt_pivots[type])
704 return mas->max;
705
706 return pivots[piv];
707}
708
709/*
710 * mas_safe_min() - Return the minimum for a given offset.
711 * @mas: The maple state
712 * @pivots: The pointer to the maple node pivots
713 * @offset: The offset into the pivot array
714 *
715 * Return: The minimum range value that is contained in @offset.
716 */
717static inline unsigned long
718mas_safe_min(struct ma_state *mas, unsigned long *pivots, unsigned char offset)
719{
720 if (likely(offset))
721 return pivots[offset - 1] + 1;
722
723 return mas->min;
724}
725
726/*
727 * mas_logical_pivot() - Get the logical pivot of a given offset.
728 * @mas: The maple state
729 * @pivots: The pointer to the maple node pivots
730 * @offset: The offset into the pivot array
731 * @type: The maple node type
732 *
733 * When there is no value at a pivot (beyond the end of the data), then the
734 * pivot is actually @mas->max.
735 *
736 * Return: the logical pivot of a given @offset.
737 */
738static inline unsigned long
739mas_logical_pivot(struct ma_state *mas, unsigned long *pivots,
740 unsigned char offset, enum maple_type type)
741{
742 unsigned long lpiv = mas_safe_pivot(mas, pivots, offset, type);
743
744 if (likely(lpiv))
745 return lpiv;
746
747 if (likely(offset))
748 return mas->max;
749
750 return lpiv;
751}
752
753/*
754 * mte_set_pivot() - Set a pivot to a value in an encoded maple node.
755 * @mn: The encoded maple node
756 * @piv: The pivot offset
757 * @val: The value of the pivot
758 */
759static inline void mte_set_pivot(struct maple_enode *mn, unsigned char piv,
760 unsigned long val)
761{
762 struct maple_node *node = mte_to_node(mn);
763 enum maple_type type = mte_node_type(mn);
764
765 BUG_ON(piv >= mt_pivots[type]);
766 switch (type) {
767 default:
768 case maple_range_64:
769 case maple_leaf_64:
770 node->mr64.pivot[piv] = val;
771 break;
772 case maple_arange_64:
773 node->ma64.pivot[piv] = val;
774 break;
775 case maple_dense:
776 break;
777 }
778
779}
780
781/*
782 * ma_slots() - Get a pointer to the maple node slots.
783 * @mn: The maple node
784 * @mt: The maple node type
785 *
786 * Return: A pointer to the maple node slots
787 */
788static inline void __rcu **ma_slots(struct maple_node *mn, enum maple_type mt)
789{
790 switch (mt) {
791 default:
792 case maple_arange_64:
793 return mn->ma64.slot;
794 case maple_range_64:
795 case maple_leaf_64:
796 return mn->mr64.slot;
797 case maple_dense:
798 return mn->slot;
799 }
800}
801
802static inline bool mt_locked(const struct maple_tree *mt)
803{
804 return mt_external_lock(mt) ? mt_lock_is_held(mt) :
805 lockdep_is_held(&mt->ma_lock);
806}
807
808static inline void *mt_slot(const struct maple_tree *mt,
809 void __rcu **slots, unsigned char offset)
810{
811 return rcu_dereference_check(slots[offset], mt_locked(mt));
812}
813
814/*
815 * mas_slot_locked() - Get the slot value when holding the maple tree lock.
816 * @mas: The maple state
817 * @slots: The pointer to the slots
818 * @offset: The offset into the slots array to fetch
819 *
820 * Return: The entry stored in @slots at the @offset.
821 */
822static inline void *mas_slot_locked(struct ma_state *mas, void __rcu **slots,
823 unsigned char offset)
824{
825 return rcu_dereference_protected(slots[offset], mt_locked(mas->tree));
826}
827
828/*
829 * mas_slot() - Get the slot value when not holding the maple tree lock.
830 * @mas: The maple state
831 * @slots: The pointer to the slots
832 * @offset: The offset into the slots array to fetch
833 *
834 * Return: The entry stored in @slots at the @offset
835 */
836static inline void *mas_slot(struct ma_state *mas, void __rcu **slots,
837 unsigned char offset)
838{
839 return mt_slot(mas->tree, slots, offset);
840}
841
842/*
843 * mas_root() - Get the maple tree root.
844 * @mas: The maple state.
845 *
846 * Return: The pointer to the root of the tree
847 */
848static inline void *mas_root(struct ma_state *mas)
849{
850 return rcu_dereference_check(mas->tree->ma_root, mt_locked(mas->tree));
851}
852
853static inline void *mt_root_locked(struct maple_tree *mt)
854{
855 return rcu_dereference_protected(mt->ma_root, mt_locked(mt));
856}
857
858/*
859 * mas_root_locked() - Get the maple tree root when holding the maple tree lock.
860 * @mas: The maple state.
861 *
862 * Return: The pointer to the root of the tree
863 */
864static inline void *mas_root_locked(struct ma_state *mas)
865{
866 return mt_root_locked(mas->tree);
867}
868
869static inline struct maple_metadata *ma_meta(struct maple_node *mn,
870 enum maple_type mt)
871{
872 switch (mt) {
873 case maple_arange_64:
874 return &mn->ma64.meta;
875 default:
876 return &mn->mr64.meta;
877 }
878}
879
880/*
881 * ma_set_meta() - Set the metadata information of a node.
882 * @mn: The maple node
883 * @mt: The maple node type
884 * @offset: The offset of the highest sub-gap in this node.
885 * @end: The end of the data in this node.
886 */
887static inline void ma_set_meta(struct maple_node *mn, enum maple_type mt,
888 unsigned char offset, unsigned char end)
889{
890 struct maple_metadata *meta = ma_meta(mn, mt);
891
892 meta->gap = offset;
893 meta->end = end;
894}
895
896/*
897 * ma_meta_end() - Get the data end of a node from the metadata
898 * @mn: The maple node
899 * @mt: The maple node type
900 */
901static inline unsigned char ma_meta_end(struct maple_node *mn,
902 enum maple_type mt)
903{
904 struct maple_metadata *meta = ma_meta(mn, mt);
905
906 return meta->end;
907}
908
909/*
910 * ma_meta_gap() - Get the largest gap location of a node from the metadata
911 * @mn: The maple node
912 * @mt: The maple node type
913 */
914static inline unsigned char ma_meta_gap(struct maple_node *mn,
915 enum maple_type mt)
916{
917 BUG_ON(mt != maple_arange_64);
918
919 return mn->ma64.meta.gap;
920}
921
922/*
923 * ma_set_meta_gap() - Set the largest gap location in a nodes metadata
924 * @mn: The maple node
925 * @mn: The maple node type
926 * @offset: The location of the largest gap.
927 */
928static inline void ma_set_meta_gap(struct maple_node *mn, enum maple_type mt,
929 unsigned char offset)
930{
931
932 struct maple_metadata *meta = ma_meta(mn, mt);
933
934 meta->gap = offset;
935}
936
937/*
938 * mat_add() - Add a @dead_enode to the ma_topiary of a list of dead nodes.
939 * @mat - the ma_topiary, a linked list of dead nodes.
940 * @dead_enode - the node to be marked as dead and added to the tail of the list
941 *
942 * Add the @dead_enode to the linked list in @mat.
943 */
944static inline void mat_add(struct ma_topiary *mat,
945 struct maple_enode *dead_enode)
946{
947 mte_set_node_dead(dead_enode);
948 mte_to_mat(dead_enode)->next = NULL;
949 if (!mat->tail) {
950 mat->tail = mat->head = dead_enode;
951 return;
952 }
953
954 mte_to_mat(mat->tail)->next = dead_enode;
955 mat->tail = dead_enode;
956}
957
958static void mte_destroy_walk(struct maple_enode *, struct maple_tree *);
959static inline void mas_free(struct ma_state *mas, struct maple_enode *used);
960
961/*
962 * mas_mat_free() - Free all nodes in a dead list.
963 * @mas - the maple state
964 * @mat - the ma_topiary linked list of dead nodes to free.
965 *
966 * Free walk a dead list.
967 */
968static void mas_mat_free(struct ma_state *mas, struct ma_topiary *mat)
969{
970 struct maple_enode *next;
971
972 while (mat->head) {
973 next = mte_to_mat(mat->head)->next;
974 mas_free(mas, mat->head);
975 mat->head = next;
976 }
977}
978
979/*
980 * mas_mat_destroy() - Free all nodes and subtrees in a dead list.
981 * @mas - the maple state
982 * @mat - the ma_topiary linked list of dead nodes to free.
983 *
984 * Destroy walk a dead list.
985 */
986static void mas_mat_destroy(struct ma_state *mas, struct ma_topiary *mat)
987{
988 struct maple_enode *next;
989
990 while (mat->head) {
991 next = mte_to_mat(mat->head)->next;
992 mte_destroy_walk(mat->head, mat->mtree);
993 mat->head = next;
994 }
995}
996/*
997 * mas_descend() - Descend into the slot stored in the ma_state.
998 * @mas - the maple state.
999 *
1000 * Note: Not RCU safe, only use in write side or debug code.
1001 */
1002static inline void mas_descend(struct ma_state *mas)
1003{
1004 enum maple_type type;
1005 unsigned long *pivots;
1006 struct maple_node *node;
1007 void __rcu **slots;
1008
1009 node = mas_mn(mas);
1010 type = mte_node_type(mas->node);
1011 pivots = ma_pivots(node, type);
1012 slots = ma_slots(node, type);
1013
1014 if (mas->offset)
1015 mas->min = pivots[mas->offset - 1] + 1;
1016 mas->max = mas_safe_pivot(mas, pivots, mas->offset, type);
1017 mas->node = mas_slot(mas, slots, mas->offset);
1018}
1019
1020/*
1021 * mte_set_gap() - Set a maple node gap.
1022 * @mn: The encoded maple node
1023 * @gap: The offset of the gap to set
1024 * @val: The gap value
1025 */
1026static inline void mte_set_gap(const struct maple_enode *mn,
1027 unsigned char gap, unsigned long val)
1028{
1029 switch (mte_node_type(mn)) {
1030 default:
1031 break;
1032 case maple_arange_64:
1033 mte_to_node(mn)->ma64.gap[gap] = val;
1034 break;
1035 }
1036}
1037
1038/*
1039 * mas_ascend() - Walk up a level of the tree.
1040 * @mas: The maple state
1041 *
1042 * Sets the @mas->max and @mas->min to the correct values when walking up. This
1043 * may cause several levels of walking up to find the correct min and max.
1044 * May find a dead node which will cause a premature return.
1045 * Return: 1 on dead node, 0 otherwise
1046 */
1047static int mas_ascend(struct ma_state *mas)
1048{
1049 struct maple_enode *p_enode; /* parent enode. */
1050 struct maple_enode *a_enode; /* ancestor enode. */
1051 struct maple_node *a_node; /* ancestor node. */
1052 struct maple_node *p_node; /* parent node. */
1053 unsigned char a_slot;
1054 enum maple_type a_type;
1055 unsigned long min, max;
1056 unsigned long *pivots;
1057 unsigned char offset;
1058 bool set_max = false, set_min = false;
1059
1060 a_node = mas_mn(mas);
1061 if (ma_is_root(a_node)) {
1062 mas->offset = 0;
1063 return 0;
1064 }
1065
1066 p_node = mte_parent(mas->node);
1067 if (unlikely(a_node == p_node))
1068 return 1;
1069 a_type = mas_parent_enum(mas, mas->node);
1070 offset = mte_parent_slot(mas->node);
1071 a_enode = mt_mk_node(p_node, a_type);
1072
1073 /* Check to make sure all parent information is still accurate */
1074 if (p_node != mte_parent(mas->node))
1075 return 1;
1076
1077 mas->node = a_enode;
1078 mas->offset = offset;
1079
1080 if (mte_is_root(a_enode)) {
1081 mas->max = ULONG_MAX;
1082 mas->min = 0;
1083 return 0;
1084 }
1085
1086 min = 0;
1087 max = ULONG_MAX;
1088 do {
1089 p_enode = a_enode;
1090 a_type = mas_parent_enum(mas, p_enode);
1091 a_node = mte_parent(p_enode);
1092 a_slot = mte_parent_slot(p_enode);
1093 pivots = ma_pivots(a_node, a_type);
1094 a_enode = mt_mk_node(a_node, a_type);
1095
1096 if (!set_min && a_slot) {
1097 set_min = true;
1098 min = pivots[a_slot - 1] + 1;
1099 }
1100
1101 if (!set_max && a_slot < mt_pivots[a_type]) {
1102 set_max = true;
1103 max = pivots[a_slot];
1104 }
1105
1106 if (unlikely(ma_dead_node(a_node)))
1107 return 1;
1108
1109 if (unlikely(ma_is_root(a_node)))
1110 break;
1111
1112 } while (!set_min || !set_max);
1113
1114 mas->max = max;
1115 mas->min = min;
1116 return 0;
1117}
1118
1119/*
1120 * mas_pop_node() - Get a previously allocated maple node from the maple state.
1121 * @mas: The maple state
1122 *
1123 * Return: A pointer to a maple node.
1124 */
1125static inline struct maple_node *mas_pop_node(struct ma_state *mas)
1126{
1127 struct maple_alloc *ret, *node = mas->alloc;
1128 unsigned long total = mas_allocated(mas);
1129
1130 /* nothing or a request pending. */
1131 if (unlikely(!total))
1132 return NULL;
1133
1134 if (total == 1) {
1135 /* single allocation in this ma_state */
1136 mas->alloc = NULL;
1137 ret = node;
1138 goto single_node;
1139 }
1140
1141 if (!node->node_count) {
1142 /* Single allocation in this node. */
1143 mas->alloc = node->slot[0];
1144 node->slot[0] = NULL;
1145 mas->alloc->total = node->total - 1;
1146 ret = node;
1147 goto new_head;
1148 }
1149
1150 node->total--;
1151 ret = node->slot[node->node_count];
1152 node->slot[node->node_count--] = NULL;
1153
1154single_node:
1155new_head:
1156 ret->total = 0;
1157 ret->node_count = 0;
1158 if (ret->request_count) {
1159 mas_set_alloc_req(mas, ret->request_count + 1);
1160 ret->request_count = 0;
1161 }
1162 return (struct maple_node *)ret;
1163}
1164
1165/*
1166 * mas_push_node() - Push a node back on the maple state allocation.
1167 * @mas: The maple state
1168 * @used: The used maple node
1169 *
1170 * Stores the maple node back into @mas->alloc for reuse. Updates allocated and
1171 * requested node count as necessary.
1172 */
1173static inline void mas_push_node(struct ma_state *mas, struct maple_node *used)
1174{
1175 struct maple_alloc *reuse = (struct maple_alloc *)used;
1176 struct maple_alloc *head = mas->alloc;
1177 unsigned long count;
1178 unsigned int requested = mas_alloc_req(mas);
1179
1180 memset(reuse, 0, sizeof(*reuse));
1181 count = mas_allocated(mas);
1182
1183 if (count && (head->node_count < MAPLE_ALLOC_SLOTS - 1)) {
1184 if (head->slot[0])
1185 head->node_count++;
1186 head->slot[head->node_count] = reuse;
1187 head->total++;
1188 goto done;
1189 }
1190
1191 reuse->total = 1;
1192 if ((head) && !((unsigned long)head & 0x1)) {
1193 head->request_count = 0;
1194 reuse->slot[0] = head;
1195 reuse->total += head->total;
1196 }
1197
1198 mas->alloc = reuse;
1199done:
1200 if (requested > 1)
1201 mas_set_alloc_req(mas, requested - 1);
1202}
1203
1204/*
1205 * mas_alloc_nodes() - Allocate nodes into a maple state
1206 * @mas: The maple state
1207 * @gfp: The GFP Flags
1208 */
1209static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp)
1210{
1211 struct maple_alloc *node;
1212 struct maple_alloc **nodep = &mas->alloc;
1213 unsigned long allocated = mas_allocated(mas);
1214 unsigned long success = allocated;
1215 unsigned int requested = mas_alloc_req(mas);
1216 unsigned int count;
1217 void **slots = NULL;
1218 unsigned int max_req = 0;
1219
1220 if (!requested)
1221 return;
1222
1223 mas_set_alloc_req(mas, 0);
1224 if (mas->mas_flags & MA_STATE_PREALLOC) {
1225 if (allocated)
1226 return;
1227 WARN_ON(!allocated);
1228 }
1229
1230 if (!allocated || mas->alloc->node_count == MAPLE_ALLOC_SLOTS - 1) {
1231 node = (struct maple_alloc *)mt_alloc_one(gfp);
1232 if (!node)
1233 goto nomem_one;
1234
1235 if (allocated)
1236 node->slot[0] = mas->alloc;
1237
1238 success++;
1239 mas->alloc = node;
1240 requested--;
1241 }
1242
1243 node = mas->alloc;
1244 while (requested) {
1245 max_req = MAPLE_ALLOC_SLOTS;
1246 if (node->slot[0]) {
1247 unsigned int offset = node->node_count + 1;
1248
1249 slots = (void **)&node->slot[offset];
1250 max_req -= offset;
1251 } else {
1252 slots = (void **)&node->slot;
1253 }
1254
1255 max_req = min(requested, max_req);
1256 count = mt_alloc_bulk(gfp, max_req, slots);
1257 if (!count)
1258 goto nomem_bulk;
1259
1260 node->node_count += count;
1261 /* zero indexed. */
1262 if (slots == (void **)&node->slot)
1263 node->node_count--;
1264
1265 success += count;
1266 nodep = &node->slot[0];
1267 node = *nodep;
1268 requested -= count;
1269 }
1270 mas->alloc->total = success;
1271 return;
1272
1273nomem_bulk:
1274 /* Clean up potential freed allocations on bulk failure */
1275 memset(slots, 0, max_req * sizeof(unsigned long));
1276nomem_one:
1277 mas_set_alloc_req(mas, requested);
1278 if (mas->alloc && !(((unsigned long)mas->alloc & 0x1)))
1279 mas->alloc->total = success;
1280 mas_set_err(mas, -ENOMEM);
1281 return;
1282
1283}
1284
1285/*
1286 * mas_free() - Free an encoded maple node
1287 * @mas: The maple state
1288 * @used: The encoded maple node to free.
1289 *
1290 * Uses rcu free if necessary, pushes @used back on the maple state allocations
1291 * otherwise.
1292 */
1293static inline void mas_free(struct ma_state *mas, struct maple_enode *used)
1294{
1295 struct maple_node *tmp = mte_to_node(used);
1296
1297 if (mt_in_rcu(mas->tree))
1298 ma_free_rcu(tmp);
1299 else
1300 mas_push_node(mas, tmp);
1301}
1302
1303/*
1304 * mas_node_count() - Check if enough nodes are allocated and request more if
1305 * there is not enough nodes.
1306 * @mas: The maple state
1307 * @count: The number of nodes needed
1308 * @gfp: the gfp flags
1309 */
1310static void mas_node_count_gfp(struct ma_state *mas, int count, gfp_t gfp)
1311{
1312 unsigned long allocated = mas_allocated(mas);
1313
1314 if (allocated < count) {
1315 mas_set_alloc_req(mas, count - allocated);
1316 mas_alloc_nodes(mas, gfp);
1317 }
1318}
1319
1320/*
1321 * mas_node_count() - Check if enough nodes are allocated and request more if
1322 * there is not enough nodes.
1323 * @mas: The maple state
1324 * @count: The number of nodes needed
1325 *
1326 * Note: Uses GFP_NOWAIT | __GFP_NOWARN for gfp flags.
1327 */
1328static void mas_node_count(struct ma_state *mas, int count)
1329{
1330 return mas_node_count_gfp(mas, count, GFP_NOWAIT | __GFP_NOWARN);
1331}
1332
1333/*
1334 * mas_start() - Sets up maple state for operations.
1335 * @mas: The maple state.
1336 *
1337 * If mas->node == MAS_START, then set the min, max, depth, and offset to
1338 * defaults.
1339 *
1340 * Return:
1341 * - If mas->node is an error or not MAS_START, return NULL.
1342 * - If it's an empty tree: NULL & mas->node == MAS_NONE
1343 * - If it's a single entry: The entry & mas->node == MAS_ROOT
1344 * - If it's a tree: NULL & mas->node == safe root node.
1345 */
1346static inline struct maple_enode *mas_start(struct ma_state *mas)
1347{
1348 if (likely(mas_is_start(mas))) {
1349 struct maple_enode *root;
1350
1351 mas->node = MAS_NONE;
1352 mas->min = 0;
1353 mas->max = ULONG_MAX;
1354 mas->depth = 0;
1355 mas->offset = 0;
1356
1357 root = mas_root(mas);
1358 /* Tree with nodes */
1359 if (likely(xa_is_node(root))) {
1360 mas->node = mte_safe_root(root);
1361 return NULL;
1362 }
1363
1364 /* empty tree */
1365 if (unlikely(!root)) {
1366 mas->offset = MAPLE_NODE_SLOTS;
1367 return NULL;
1368 }
1369
1370 /* Single entry tree */
1371 mas->node = MAS_ROOT;
1372 mas->offset = MAPLE_NODE_SLOTS;
1373
1374 /* Single entry tree. */
1375 if (mas->index > 0)
1376 return NULL;
1377
1378 return root;
1379 }
1380
1381 return NULL;
1382}
1383
1384/*
1385 * ma_data_end() - Find the end of the data in a node.
1386 * @node: The maple node
1387 * @type: The maple node type
1388 * @pivots: The array of pivots in the node
1389 * @max: The maximum value in the node
1390 *
1391 * Uses metadata to find the end of the data when possible.
1392 * Return: The zero indexed last slot with data (may be null).
1393 */
1394static inline unsigned char ma_data_end(struct maple_node *node,
1395 enum maple_type type,
1396 unsigned long *pivots,
1397 unsigned long max)
1398{
1399 unsigned char offset;
1400
1401 if (type == maple_arange_64)
1402 return ma_meta_end(node, type);
1403
1404 offset = mt_pivots[type] - 1;
1405 if (likely(!pivots[offset]))
1406 return ma_meta_end(node, type);
1407
1408 if (likely(pivots[offset] == max))
1409 return offset;
1410
1411 return mt_pivots[type];
1412}
1413
1414/*
1415 * mas_data_end() - Find the end of the data (slot).
1416 * @mas: the maple state
1417 *
1418 * This method is optimized to check the metadata of a node if the node type
1419 * supports data end metadata.
1420 *
1421 * Return: The zero indexed last slot with data (may be null).
1422 */
1423static inline unsigned char mas_data_end(struct ma_state *mas)
1424{
1425 enum maple_type type;
1426 struct maple_node *node;
1427 unsigned char offset;
1428 unsigned long *pivots;
1429
1430 type = mte_node_type(mas->node);
1431 node = mas_mn(mas);
1432 if (type == maple_arange_64)
1433 return ma_meta_end(node, type);
1434
1435 pivots = ma_pivots(node, type);
1436 offset = mt_pivots[type] - 1;
1437 if (likely(!pivots[offset]))
1438 return ma_meta_end(node, type);
1439
1440 if (likely(pivots[offset] == mas->max))
1441 return offset;
1442
1443 return mt_pivots[type];
1444}
1445
1446/*
1447 * mas_leaf_max_gap() - Returns the largest gap in a leaf node
1448 * @mas - the maple state
1449 *
1450 * Return: The maximum gap in the leaf.
1451 */
1452static unsigned long mas_leaf_max_gap(struct ma_state *mas)
1453{
1454 enum maple_type mt;
1455 unsigned long pstart, gap, max_gap;
1456 struct maple_node *mn;
1457 unsigned long *pivots;
1458 void __rcu **slots;
1459 unsigned char i;
1460 unsigned char max_piv;
1461
1462 mt = mte_node_type(mas->node);
1463 mn = mas_mn(mas);
1464 slots = ma_slots(mn, mt);
1465 max_gap = 0;
1466 if (unlikely(ma_is_dense(mt))) {
1467 gap = 0;
1468 for (i = 0; i < mt_slots[mt]; i++) {
1469 if (slots[i]) {
1470 if (gap > max_gap)
1471 max_gap = gap;
1472 gap = 0;
1473 } else {
1474 gap++;
1475 }
1476 }
1477 if (gap > max_gap)
1478 max_gap = gap;
1479 return max_gap;
1480 }
1481
1482 /*
1483 * Check the first implied pivot optimizes the loop below and slot 1 may
1484 * be skipped if there is a gap in slot 0.
1485 */
1486 pivots = ma_pivots(mn, mt);
1487 if (likely(!slots[0])) {
1488 max_gap = pivots[0] - mas->min + 1;
1489 i = 2;
1490 } else {
1491 i = 1;
1492 }
1493
1494 /* reduce max_piv as the special case is checked before the loop */
1495 max_piv = ma_data_end(mn, mt, pivots, mas->max) - 1;
1496 /*
1497 * Check end implied pivot which can only be a gap on the right most
1498 * node.
1499 */
1500 if (unlikely(mas->max == ULONG_MAX) && !slots[max_piv + 1]) {
1501 gap = ULONG_MAX - pivots[max_piv];
1502 if (gap > max_gap)
1503 max_gap = gap;
1504 }
1505
1506 for (; i <= max_piv; i++) {
1507 /* data == no gap. */
1508 if (likely(slots[i]))
1509 continue;
1510
1511 pstart = pivots[i - 1];
1512 gap = pivots[i] - pstart;
1513 if (gap > max_gap)
1514 max_gap = gap;
1515
1516 /* There cannot be two gaps in a row. */
1517 i++;
1518 }
1519 return max_gap;
1520}
1521
1522/*
1523 * ma_max_gap() - Get the maximum gap in a maple node (non-leaf)
1524 * @node: The maple node
1525 * @gaps: The pointer to the gaps
1526 * @mt: The maple node type
1527 * @*off: Pointer to store the offset location of the gap.
1528 *
1529 * Uses the metadata data end to scan backwards across set gaps.
1530 *
1531 * Return: The maximum gap value
1532 */
1533static inline unsigned long
1534ma_max_gap(struct maple_node *node, unsigned long *gaps, enum maple_type mt,
1535 unsigned char *off)
1536{
1537 unsigned char offset, i;
1538 unsigned long max_gap = 0;
1539
1540 i = offset = ma_meta_end(node, mt);
1541 do {
1542 if (gaps[i] > max_gap) {
1543 max_gap = gaps[i];
1544 offset = i;
1545 }
1546 } while (i--);
1547
1548 *off = offset;
1549 return max_gap;
1550}
1551
1552/*
1553 * mas_max_gap() - find the largest gap in a non-leaf node and set the slot.
1554 * @mas: The maple state.
1555 *
1556 * If the metadata gap is set to MAPLE_ARANGE64_META_MAX, there is no gap.
1557 *
1558 * Return: The gap value.
1559 */
1560static inline unsigned long mas_max_gap(struct ma_state *mas)
1561{
1562 unsigned long *gaps;
1563 unsigned char offset;
1564 enum maple_type mt;
1565 struct maple_node *node;
1566
1567 mt = mte_node_type(mas->node);
1568 if (ma_is_leaf(mt))
1569 return mas_leaf_max_gap(mas);
1570
1571 node = mas_mn(mas);
1572 offset = ma_meta_gap(node, mt);
1573 if (offset == MAPLE_ARANGE64_META_MAX)
1574 return 0;
1575
1576 gaps = ma_gaps(node, mt);
1577 return gaps[offset];
1578}
1579
1580/*
1581 * mas_parent_gap() - Set the parent gap and any gaps above, as needed
1582 * @mas: The maple state
1583 * @offset: The gap offset in the parent to set
1584 * @new: The new gap value.
1585 *
1586 * Set the parent gap then continue to set the gap upwards, using the metadata
1587 * of the parent to see if it is necessary to check the node above.
1588 */
1589static inline void mas_parent_gap(struct ma_state *mas, unsigned char offset,
1590 unsigned long new)
1591{
1592 unsigned long meta_gap = 0;
1593 struct maple_node *pnode;
1594 struct maple_enode *penode;
1595 unsigned long *pgaps;
1596 unsigned char meta_offset;
1597 enum maple_type pmt;
1598
1599 pnode = mte_parent(mas->node);
1600 pmt = mas_parent_enum(mas, mas->node);
1601 penode = mt_mk_node(pnode, pmt);
1602 pgaps = ma_gaps(pnode, pmt);
1603
1604ascend:
1605 meta_offset = ma_meta_gap(pnode, pmt);
1606 if (meta_offset == MAPLE_ARANGE64_META_MAX)
1607 meta_gap = 0;
1608 else
1609 meta_gap = pgaps[meta_offset];
1610
1611 pgaps[offset] = new;
1612
1613 if (meta_gap == new)
1614 return;
1615
1616 if (offset != meta_offset) {
1617 if (meta_gap > new)
1618 return;
1619
1620 ma_set_meta_gap(pnode, pmt, offset);
1621 } else if (new < meta_gap) {
1622 meta_offset = 15;
1623 new = ma_max_gap(pnode, pgaps, pmt, &meta_offset);
1624 ma_set_meta_gap(pnode, pmt, meta_offset);
1625 }
1626
1627 if (ma_is_root(pnode))
1628 return;
1629
1630 /* Go to the parent node. */
1631 pnode = mte_parent(penode);
1632 pmt = mas_parent_enum(mas, penode);
1633 pgaps = ma_gaps(pnode, pmt);
1634 offset = mte_parent_slot(penode);
1635 penode = mt_mk_node(pnode, pmt);
1636 goto ascend;
1637}
1638
1639/*
1640 * mas_update_gap() - Update a nodes gaps and propagate up if necessary.
1641 * @mas - the maple state.
1642 */
1643static inline void mas_update_gap(struct ma_state *mas)
1644{
1645 unsigned char pslot;
1646 unsigned long p_gap;
1647 unsigned long max_gap;
1648
1649 if (!mt_is_alloc(mas->tree))
1650 return;
1651
1652 if (mte_is_root(mas->node))
1653 return;
1654
1655 max_gap = mas_max_gap(mas);
1656
1657 pslot = mte_parent_slot(mas->node);
1658 p_gap = ma_gaps(mte_parent(mas->node),
1659 mas_parent_enum(mas, mas->node))[pslot];
1660
1661 if (p_gap != max_gap)
1662 mas_parent_gap(mas, pslot, max_gap);
1663}
1664
1665/*
1666 * mas_adopt_children() - Set the parent pointer of all nodes in @parent to
1667 * @parent with the slot encoded.
1668 * @mas - the maple state (for the tree)
1669 * @parent - the maple encoded node containing the children.
1670 */
1671static inline void mas_adopt_children(struct ma_state *mas,
1672 struct maple_enode *parent)
1673{
1674 enum maple_type type = mte_node_type(parent);
1675 struct maple_node *node = mas_mn(mas);
1676 void __rcu **slots = ma_slots(node, type);
1677 unsigned long *pivots = ma_pivots(node, type);
1678 struct maple_enode *child;
1679 unsigned char offset;
1680
1681 offset = ma_data_end(node, type, pivots, mas->max);
1682 do {
1683 child = mas_slot_locked(mas, slots, offset);
1684 mte_set_parent(child, parent, offset);
1685 } while (offset--);
1686}
1687
1688/*
1689 * mas_replace() - Replace a maple node in the tree with mas->node. Uses the
1690 * parent encoding to locate the maple node in the tree.
1691 * @mas - the ma_state to use for operations.
1692 * @advanced - boolean to adopt the child nodes and free the old node (false) or
1693 * leave the node (true) and handle the adoption and free elsewhere.
1694 */
1695static inline void mas_replace(struct ma_state *mas, bool advanced)
1696 __must_hold(mas->tree->lock)
1697{
1698 struct maple_node *mn = mas_mn(mas);
1699 struct maple_enode *old_enode;
1700 unsigned char offset = 0;
1701 void __rcu **slots = NULL;
1702
1703 if (ma_is_root(mn)) {
1704 old_enode = mas_root_locked(mas);
1705 } else {
1706 offset = mte_parent_slot(mas->node);
1707 slots = ma_slots(mte_parent(mas->node),
1708 mas_parent_enum(mas, mas->node));
1709 old_enode = mas_slot_locked(mas, slots, offset);
1710 }
1711
1712 if (!advanced && !mte_is_leaf(mas->node))
1713 mas_adopt_children(mas, mas->node);
1714
1715 if (mte_is_root(mas->node)) {
1716 mn->parent = ma_parent_ptr(
1717 ((unsigned long)mas->tree | MA_ROOT_PARENT));
1718 rcu_assign_pointer(mas->tree->ma_root, mte_mk_root(mas->node));
1719 mas_set_height(mas);
1720 } else {
1721 rcu_assign_pointer(slots[offset], mas->node);
1722 }
1723
1724 if (!advanced)
1725 mas_free(mas, old_enode);
1726}
1727
1728/*
1729 * mas_new_child() - Find the new child of a node.
1730 * @mas: the maple state
1731 * @child: the maple state to store the child.
1732 */
1733static inline bool mas_new_child(struct ma_state *mas, struct ma_state *child)
1734 __must_hold(mas->tree->lock)
1735{
1736 enum maple_type mt;
1737 unsigned char offset;
1738 unsigned char end;
1739 unsigned long *pivots;
1740 struct maple_enode *entry;
1741 struct maple_node *node;
1742 void __rcu **slots;
1743
1744 mt = mte_node_type(mas->node);
1745 node = mas_mn(mas);
1746 slots = ma_slots(node, mt);
1747 pivots = ma_pivots(node, mt);
1748 end = ma_data_end(node, mt, pivots, mas->max);
1749 for (offset = mas->offset; offset <= end; offset++) {
1750 entry = mas_slot_locked(mas, slots, offset);
1751 if (mte_parent(entry) == node) {
1752 *child = *mas;
1753 mas->offset = offset + 1;
1754 child->offset = offset;
1755 mas_descend(child);
1756 child->offset = 0;
1757 return true;
1758 }
1759 }
1760 return false;
1761}
1762
1763/*
1764 * mab_shift_right() - Shift the data in mab right. Note, does not clean out the
1765 * old data or set b_node->b_end.
1766 * @b_node: the maple_big_node
1767 * @shift: the shift count
1768 */
1769static inline void mab_shift_right(struct maple_big_node *b_node,
1770 unsigned char shift)
1771{
1772 unsigned long size = b_node->b_end * sizeof(unsigned long);
1773
1774 memmove(b_node->pivot + shift, b_node->pivot, size);
1775 memmove(b_node->slot + shift, b_node->slot, size);
1776 if (b_node->type == maple_arange_64)
1777 memmove(b_node->gap + shift, b_node->gap, size);
1778}
1779
1780/*
1781 * mab_middle_node() - Check if a middle node is needed (unlikely)
1782 * @b_node: the maple_big_node that contains the data.
1783 * @size: the amount of data in the b_node
1784 * @split: the potential split location
1785 * @slot_count: the size that can be stored in a single node being considered.
1786 *
1787 * Return: true if a middle node is required.
1788 */
1789static inline bool mab_middle_node(struct maple_big_node *b_node, int split,
1790 unsigned char slot_count)
1791{
1792 unsigned char size = b_node->b_end;
1793
1794 if (size >= 2 * slot_count)
1795 return true;
1796
1797 if (!b_node->slot[split] && (size >= 2 * slot_count - 1))
1798 return true;
1799
1800 return false;
1801}
1802
1803/*
1804 * mab_no_null_split() - ensure the split doesn't fall on a NULL
1805 * @b_node: the maple_big_node with the data
1806 * @split: the suggested split location
1807 * @slot_count: the number of slots in the node being considered.
1808 *
1809 * Return: the split location.
1810 */
1811static inline int mab_no_null_split(struct maple_big_node *b_node,
1812 unsigned char split, unsigned char slot_count)
1813{
1814 if (!b_node->slot[split]) {
1815 /*
1816 * If the split is less than the max slot && the right side will
1817 * still be sufficient, then increment the split on NULL.
1818 */
1819 if ((split < slot_count - 1) &&
1820 (b_node->b_end - split) > (mt_min_slots[b_node->type]))
1821 split++;
1822 else
1823 split--;
1824 }
1825 return split;
1826}
1827
1828/*
1829 * mab_calc_split() - Calculate the split location and if there needs to be two
1830 * splits.
1831 * @bn: The maple_big_node with the data
1832 * @mid_split: The second split, if required. 0 otherwise.
1833 *
1834 * Return: The first split location. The middle split is set in @mid_split.
1835 */
1836static inline int mab_calc_split(struct ma_state *mas,
1837 struct maple_big_node *bn, unsigned char *mid_split, unsigned long min)
1838{
1839 unsigned char b_end = bn->b_end;
1840 int split = b_end / 2; /* Assume equal split. */
1841 unsigned char slot_min, slot_count = mt_slots[bn->type];
1842
1843 /*
1844 * To support gap tracking, all NULL entries are kept together and a node cannot
1845 * end on a NULL entry, with the exception of the left-most leaf. The
1846 * limitation means that the split of a node must be checked for this condition
1847 * and be able to put more data in one direction or the other.
1848 */
1849 if (unlikely((mas->mas_flags & MA_STATE_BULK))) {
1850 *mid_split = 0;
1851 split = b_end - mt_min_slots[bn->type];
1852
1853 if (!ma_is_leaf(bn->type))
1854 return split;
1855
1856 mas->mas_flags |= MA_STATE_REBALANCE;
1857 if (!bn->slot[split])
1858 split--;
1859 return split;
1860 }
1861
1862 /*
1863 * Although extremely rare, it is possible to enter what is known as the 3-way
1864 * split scenario. The 3-way split comes about by means of a store of a range
1865 * that overwrites the end and beginning of two full nodes. The result is a set
1866 * of entries that cannot be stored in 2 nodes. Sometimes, these two nodes can
1867 * also be located in different parent nodes which are also full. This can
1868 * carry upwards all the way to the root in the worst case.
1869 */
1870 if (unlikely(mab_middle_node(bn, split, slot_count))) {
1871 split = b_end / 3;
1872 *mid_split = split * 2;
1873 } else {
1874 slot_min = mt_min_slots[bn->type];
1875
1876 *mid_split = 0;
1877 /*
1878 * Avoid having a range less than the slot count unless it
1879 * causes one node to be deficient.
1880 * NOTE: mt_min_slots is 1 based, b_end and split are zero.
1881 */
1882 while (((bn->pivot[split] - min) < slot_count - 1) &&
1883 (split < slot_count - 1) && (b_end - split > slot_min))
1884 split++;
1885 }
1886
1887 /* Avoid ending a node on a NULL entry */
1888 split = mab_no_null_split(bn, split, slot_count);
1889 if (!(*mid_split))
1890 return split;
1891
1892 *mid_split = mab_no_null_split(bn, *mid_split, slot_count);
1893
1894 return split;
1895}
1896
1897/*
1898 * mas_mab_cp() - Copy data from a maple state inclusively to a maple_big_node
1899 * and set @b_node->b_end to the next free slot.
1900 * @mas: The maple state
1901 * @mas_start: The starting slot to copy
1902 * @mas_end: The end slot to copy (inclusively)
1903 * @b_node: The maple_big_node to place the data
1904 * @mab_start: The starting location in maple_big_node to store the data.
1905 */
1906static inline void mas_mab_cp(struct ma_state *mas, unsigned char mas_start,
1907 unsigned char mas_end, struct maple_big_node *b_node,
1908 unsigned char mab_start)
1909{
1910 enum maple_type mt;
1911 struct maple_node *node;
1912 void __rcu **slots;
1913 unsigned long *pivots, *gaps;
1914 int i = mas_start, j = mab_start;
1915 unsigned char piv_end;
1916
1917 node = mas_mn(mas);
1918 mt = mte_node_type(mas->node);
1919 pivots = ma_pivots(node, mt);
1920 if (!i) {
1921 b_node->pivot[j] = pivots[i++];
1922 if (unlikely(i > mas_end))
1923 goto complete;
1924 j++;
1925 }
1926
1927 piv_end = min(mas_end, mt_pivots[mt]);
1928 for (; i < piv_end; i++, j++) {
1929 b_node->pivot[j] = pivots[i];
1930 if (unlikely(!b_node->pivot[j]))
1931 break;
1932
1933 if (unlikely(mas->max == b_node->pivot[j]))
1934 goto complete;
1935 }
1936
1937 if (likely(i <= mas_end))
1938 b_node->pivot[j] = mas_safe_pivot(mas, pivots, i, mt);
1939
1940complete:
1941 b_node->b_end = ++j;
1942 j -= mab_start;
1943 slots = ma_slots(node, mt);
1944 memcpy(b_node->slot + mab_start, slots + mas_start, sizeof(void *) * j);
1945 if (!ma_is_leaf(mt) && mt_is_alloc(mas->tree)) {
1946 gaps = ma_gaps(node, mt);
1947 memcpy(b_node->gap + mab_start, gaps + mas_start,
1948 sizeof(unsigned long) * j);
1949 }
1950}
1951
1952/*
1953 * mas_leaf_set_meta() - Set the metadata of a leaf if possible.
1954 * @mas: The maple state
1955 * @node: The maple node
1956 * @pivots: pointer to the maple node pivots
1957 * @mt: The maple type
1958 * @end: The assumed end
1959 *
1960 * Note, end may be incremented within this function but not modified at the
1961 * source. This is fine since the metadata is the last thing to be stored in a
1962 * node during a write.
1963 */
1964static inline void mas_leaf_set_meta(struct ma_state *mas,
1965 struct maple_node *node, unsigned long *pivots,
1966 enum maple_type mt, unsigned char end)
1967{
1968 /* There is no room for metadata already */
1969 if (mt_pivots[mt] <= end)
1970 return;
1971
1972 if (pivots[end] && pivots[end] < mas->max)
1973 end++;
1974
1975 if (end < mt_slots[mt] - 1)
1976 ma_set_meta(node, mt, 0, end);
1977}
1978
1979/*
1980 * mab_mas_cp() - Copy data from maple_big_node to a maple encoded node.
1981 * @b_node: the maple_big_node that has the data
1982 * @mab_start: the start location in @b_node.
1983 * @mab_end: The end location in @b_node (inclusively)
1984 * @mas: The maple state with the maple encoded node.
1985 */
1986static inline void mab_mas_cp(struct maple_big_node *b_node,
1987 unsigned char mab_start, unsigned char mab_end,
1988 struct ma_state *mas, bool new_max)
1989{
1990 int i, j = 0;
1991 enum maple_type mt = mte_node_type(mas->node);
1992 struct maple_node *node = mte_to_node(mas->node);
1993 void __rcu **slots = ma_slots(node, mt);
1994 unsigned long *pivots = ma_pivots(node, mt);
1995 unsigned long *gaps = NULL;
1996 unsigned char end;
1997
1998 if (mab_end - mab_start > mt_pivots[mt])
1999 mab_end--;
2000
2001 if (!pivots[mt_pivots[mt] - 1])
2002 slots[mt_pivots[mt]] = NULL;
2003
2004 i = mab_start;
2005 do {
2006 pivots[j++] = b_node->pivot[i++];
2007 } while (i <= mab_end && likely(b_node->pivot[i]));
2008
2009 memcpy(slots, b_node->slot + mab_start,
2010 sizeof(void *) * (i - mab_start));
2011
2012 if (new_max)
2013 mas->max = b_node->pivot[i - 1];
2014
2015 end = j - 1;
2016 if (likely(!ma_is_leaf(mt) && mt_is_alloc(mas->tree))) {
2017 unsigned long max_gap = 0;
2018 unsigned char offset = 15;
2019
2020 gaps = ma_gaps(node, mt);
2021 do {
2022 gaps[--j] = b_node->gap[--i];
2023 if (gaps[j] > max_gap) {
2024 offset = j;
2025 max_gap = gaps[j];
2026 }
2027 } while (j);
2028
2029 ma_set_meta(node, mt, offset, end);
2030 } else {
2031 mas_leaf_set_meta(mas, node, pivots, mt, end);
2032 }
2033}
2034
2035/*
2036 * mas_descend_adopt() - Descend through a sub-tree and adopt children.
2037 * @mas: the maple state with the maple encoded node of the sub-tree.
2038 *
2039 * Descend through a sub-tree and adopt children who do not have the correct
2040 * parents set. Follow the parents which have the correct parents as they are
2041 * the new entries which need to be followed to find other incorrectly set
2042 * parents.
2043 */
2044static inline void mas_descend_adopt(struct ma_state *mas)
2045{
2046 struct ma_state list[3], next[3];
2047 int i, n;
2048
2049 /*
2050 * At each level there may be up to 3 correct parent pointers which indicates
2051 * the new nodes which need to be walked to find any new nodes at a lower level.
2052 */
2053
2054 for (i = 0; i < 3; i++) {
2055 list[i] = *mas;
2056 list[i].offset = 0;
2057 next[i].offset = 0;
2058 }
2059 next[0] = *mas;
2060
2061 while (!mte_is_leaf(list[0].node)) {
2062 n = 0;
2063 for (i = 0; i < 3; i++) {
2064 if (mas_is_none(&list[i]))
2065 continue;
2066
2067 if (i && list[i-1].node == list[i].node)
2068 continue;
2069
2070 while ((n < 3) && (mas_new_child(&list[i], &next[n])))
2071 n++;
2072
2073 mas_adopt_children(&list[i], list[i].node);
2074 }
2075
2076 while (n < 3)
2077 next[n++].node = MAS_NONE;
2078
2079 /* descend by setting the list to the children */
2080 for (i = 0; i < 3; i++)
2081 list[i] = next[i];
2082 }
2083}
2084
2085/*
2086 * mas_bulk_rebalance() - Rebalance the end of a tree after a bulk insert.
2087 * @mas: The maple state
2088 * @end: The maple node end
2089 * @mt: The maple node type
2090 */
2091static inline void mas_bulk_rebalance(struct ma_state *mas, unsigned char end,
2092 enum maple_type mt)
2093{
2094 if (!(mas->mas_flags & MA_STATE_BULK))
2095 return;
2096
2097 if (mte_is_root(mas->node))
2098 return;
2099
2100 if (end > mt_min_slots[mt]) {
2101 mas->mas_flags &= ~MA_STATE_REBALANCE;
2102 return;
2103 }
2104}
2105
2106/*
2107 * mas_store_b_node() - Store an @entry into the b_node while also copying the
2108 * data from a maple encoded node.
2109 * @wr_mas: the maple write state
2110 * @b_node: the maple_big_node to fill with data
2111 * @offset_end: the offset to end copying
2112 *
2113 * Return: The actual end of the data stored in @b_node
2114 */
2115static inline void mas_store_b_node(struct ma_wr_state *wr_mas,
2116 struct maple_big_node *b_node, unsigned char offset_end)
2117{
2118 unsigned char slot;
2119 unsigned char b_end;
2120 /* Possible underflow of piv will wrap back to 0 before use. */
2121 unsigned long piv;
2122 struct ma_state *mas = wr_mas->mas;
2123
2124 b_node->type = wr_mas->type;
2125 b_end = 0;
2126 slot = mas->offset;
2127 if (slot) {
2128 /* Copy start data up to insert. */
2129 mas_mab_cp(mas, 0, slot - 1, b_node, 0);
2130 b_end = b_node->b_end;
2131 piv = b_node->pivot[b_end - 1];
2132 } else
2133 piv = mas->min - 1;
2134
2135 if (piv + 1 < mas->index) {
2136 /* Handle range starting after old range */
2137 b_node->slot[b_end] = wr_mas->content;
2138 if (!wr_mas->content)
2139 b_node->gap[b_end] = mas->index - 1 - piv;
2140 b_node->pivot[b_end++] = mas->index - 1;
2141 }
2142
2143 /* Store the new entry. */
2144 mas->offset = b_end;
2145 b_node->slot[b_end] = wr_mas->entry;
2146 b_node->pivot[b_end] = mas->last;
2147
2148 /* Appended. */
2149 if (mas->last >= mas->max)
2150 goto b_end;
2151
2152 /* Handle new range ending before old range ends */
2153 piv = mas_logical_pivot(mas, wr_mas->pivots, offset_end, wr_mas->type);
2154 if (piv > mas->last) {
2155 if (piv == ULONG_MAX)
2156 mas_bulk_rebalance(mas, b_node->b_end, wr_mas->type);
2157
2158 if (offset_end != slot)
2159 wr_mas->content = mas_slot_locked(mas, wr_mas->slots,
2160 offset_end);
2161
2162 b_node->slot[++b_end] = wr_mas->content;
2163 if (!wr_mas->content)
2164 b_node->gap[b_end] = piv - mas->last + 1;
2165 b_node->pivot[b_end] = piv;
2166 }
2167
2168 slot = offset_end + 1;
2169 if (slot > wr_mas->node_end)
2170 goto b_end;
2171
2172 /* Copy end data to the end of the node. */
2173 mas_mab_cp(mas, slot, wr_mas->node_end + 1, b_node, ++b_end);
2174 b_node->b_end--;
2175 return;
2176
2177b_end:
2178 b_node->b_end = b_end;
2179}
2180
2181/*
2182 * mas_prev_sibling() - Find the previous node with the same parent.
2183 * @mas: the maple state
2184 *
2185 * Return: True if there is a previous sibling, false otherwise.
2186 */
2187static inline bool mas_prev_sibling(struct ma_state *mas)
2188{
2189 unsigned int p_slot = mte_parent_slot(mas->node);
2190
2191 if (mte_is_root(mas->node))
2192 return false;
2193
2194 if (!p_slot)
2195 return false;
2196
2197 mas_ascend(mas);
2198 mas->offset = p_slot - 1;
2199 mas_descend(mas);
2200 return true;
2201}
2202
2203/*
2204 * mas_next_sibling() - Find the next node with the same parent.
2205 * @mas: the maple state
2206 *
2207 * Return: true if there is a next sibling, false otherwise.
2208 */
2209static inline bool mas_next_sibling(struct ma_state *mas)
2210{
2211 MA_STATE(parent, mas->tree, mas->index, mas->last);
2212
2213 if (mte_is_root(mas->node))
2214 return false;
2215
2216 parent = *mas;
2217 mas_ascend(&parent);
2218 parent.offset = mte_parent_slot(mas->node) + 1;
2219 if (parent.offset > mas_data_end(&parent))
2220 return false;
2221
2222 *mas = parent;
2223 mas_descend(mas);
2224 return true;
2225}
2226
2227/*
2228 * mte_node_or_node() - Return the encoded node or MAS_NONE.
2229 * @enode: The encoded maple node.
2230 *
2231 * Shorthand to avoid setting %NULLs in the tree or maple_subtree_state.
2232 *
2233 * Return: @enode or MAS_NONE
2234 */
2235static inline struct maple_enode *mte_node_or_none(struct maple_enode *enode)
2236{
2237 if (enode)
2238 return enode;
2239
2240 return ma_enode_ptr(MAS_NONE);
2241}
2242
2243/*
2244 * mas_wr_node_walk() - Find the correct offset for the index in the @mas.
2245 * @wr_mas: The maple write state
2246 *
2247 * Uses mas_slot_locked() and does not need to worry about dead nodes.
2248 */
2249static inline void mas_wr_node_walk(struct ma_wr_state *wr_mas)
2250{
2251 struct ma_state *mas = wr_mas->mas;
2252 unsigned char count;
2253 unsigned char offset;
2254 unsigned long index, min, max;
2255
2256 if (unlikely(ma_is_dense(wr_mas->type))) {
2257 wr_mas->r_max = wr_mas->r_min = mas->index;
2258 mas->offset = mas->index = mas->min;
2259 return;
2260 }
2261
2262 wr_mas->node = mas_mn(wr_mas->mas);
2263 wr_mas->pivots = ma_pivots(wr_mas->node, wr_mas->type);
2264 count = wr_mas->node_end = ma_data_end(wr_mas->node, wr_mas->type,
2265 wr_mas->pivots, mas->max);
2266 offset = mas->offset;
2267 min = mas_safe_min(mas, wr_mas->pivots, offset);
2268 if (unlikely(offset == count))
2269 goto max;
2270
2271 max = wr_mas->pivots[offset];
2272 index = mas->index;
2273 if (unlikely(index <= max))
2274 goto done;
2275
2276 if (unlikely(!max && offset))
2277 goto max;
2278
2279 min = max + 1;
2280 while (++offset < count) {
2281 max = wr_mas->pivots[offset];
2282 if (index <= max)
2283 goto done;
2284 else if (unlikely(!max))
2285 break;
2286
2287 min = max + 1;
2288 }
2289
2290max:
2291 max = mas->max;
2292done:
2293 wr_mas->r_max = max;
2294 wr_mas->r_min = min;
2295 wr_mas->offset_end = mas->offset = offset;
2296}
2297
2298/*
2299 * mas_topiary_range() - Add a range of slots to the topiary.
2300 * @mas: The maple state
2301 * @destroy: The topiary to add the slots (usually destroy)
2302 * @start: The starting slot inclusively
2303 * @end: The end slot inclusively
2304 */
2305static inline void mas_topiary_range(struct ma_state *mas,
2306 struct ma_topiary *destroy, unsigned char start, unsigned char end)
2307{
2308 void __rcu **slots;
2309 unsigned char offset;
2310
2311 MT_BUG_ON(mas->tree, mte_is_leaf(mas->node));
2312 slots = ma_slots(mas_mn(mas), mte_node_type(mas->node));
2313 for (offset = start; offset <= end; offset++) {
2314 struct maple_enode *enode = mas_slot_locked(mas, slots, offset);
2315
2316 if (mte_dead_node(enode))
2317 continue;
2318
2319 mat_add(destroy, enode);
2320 }
2321}
2322
2323/*
2324 * mast_topiary() - Add the portions of the tree to the removal list; either to
2325 * be freed or discarded (destroy walk).
2326 * @mast: The maple_subtree_state.
2327 */
2328static inline void mast_topiary(struct maple_subtree_state *mast)
2329{
2330 MA_WR_STATE(wr_mas, mast->orig_l, NULL);
2331 unsigned char r_start, r_end;
2332 unsigned char l_start, l_end;
2333 void __rcu **l_slots, **r_slots;
2334
2335 wr_mas.type = mte_node_type(mast->orig_l->node);
2336 mast->orig_l->index = mast->orig_l->last;
2337 mas_wr_node_walk(&wr_mas);
2338 l_start = mast->orig_l->offset + 1;
2339 l_end = mas_data_end(mast->orig_l);
2340 r_start = 0;
2341 r_end = mast->orig_r->offset;
2342
2343 if (r_end)
2344 r_end--;
2345
2346 l_slots = ma_slots(mas_mn(mast->orig_l),
2347 mte_node_type(mast->orig_l->node));
2348
2349 r_slots = ma_slots(mas_mn(mast->orig_r),
2350 mte_node_type(mast->orig_r->node));
2351
2352 if ((l_start < l_end) &&
2353 mte_dead_node(mas_slot_locked(mast->orig_l, l_slots, l_start))) {
2354 l_start++;
2355 }
2356
2357 if (mte_dead_node(mas_slot_locked(mast->orig_r, r_slots, r_end))) {
2358 if (r_end)
2359 r_end--;
2360 }
2361
2362 if ((l_start > r_end) && (mast->orig_l->node == mast->orig_r->node))
2363 return;
2364
2365 /* At the node where left and right sides meet, add the parts between */
2366 if (mast->orig_l->node == mast->orig_r->node) {
2367 return mas_topiary_range(mast->orig_l, mast->destroy,
2368 l_start, r_end);
2369 }
2370
2371 /* mast->orig_r is different and consumed. */
2372 if (mte_is_leaf(mast->orig_r->node))
2373 return;
2374
2375 if (mte_dead_node(mas_slot_locked(mast->orig_l, l_slots, l_end)))
2376 l_end--;
2377
2378
2379 if (l_start <= l_end)
2380 mas_topiary_range(mast->orig_l, mast->destroy, l_start, l_end);
2381
2382 if (mte_dead_node(mas_slot_locked(mast->orig_r, r_slots, r_start)))
2383 r_start++;
2384
2385 if (r_start <= r_end)
2386 mas_topiary_range(mast->orig_r, mast->destroy, 0, r_end);
2387}
2388
2389/*
2390 * mast_rebalance_next() - Rebalance against the next node
2391 * @mast: The maple subtree state
2392 * @old_r: The encoded maple node to the right (next node).
2393 */
2394static inline void mast_rebalance_next(struct maple_subtree_state *mast)
2395{
2396 unsigned char b_end = mast->bn->b_end;
2397
2398 mas_mab_cp(mast->orig_r, 0, mt_slot_count(mast->orig_r->node),
2399 mast->bn, b_end);
2400 mast->orig_r->last = mast->orig_r->max;
2401}
2402
2403/*
2404 * mast_rebalance_prev() - Rebalance against the previous node
2405 * @mast: The maple subtree state
2406 * @old_l: The encoded maple node to the left (previous node)
2407 */
2408static inline void mast_rebalance_prev(struct maple_subtree_state *mast)
2409{
2410 unsigned char end = mas_data_end(mast->orig_l) + 1;
2411 unsigned char b_end = mast->bn->b_end;
2412
2413 mab_shift_right(mast->bn, end);
2414 mas_mab_cp(mast->orig_l, 0, end - 1, mast->bn, 0);
2415 mast->l->min = mast->orig_l->min;
2416 mast->orig_l->index = mast->orig_l->min;
2417 mast->bn->b_end = end + b_end;
2418 mast->l->offset += end;
2419}
2420
2421/*
2422 * mast_spanning_rebalance() - Rebalance nodes with nearest neighbour favouring
2423 * the node to the right. Checking the nodes to the right then the left at each
2424 * level upwards until root is reached. Free and destroy as needed.
2425 * Data is copied into the @mast->bn.
2426 * @mast: The maple_subtree_state.
2427 */
2428static inline
2429bool mast_spanning_rebalance(struct maple_subtree_state *mast)
2430{
2431 struct ma_state r_tmp = *mast->orig_r;
2432 struct ma_state l_tmp = *mast->orig_l;
2433 struct maple_enode *ancestor = NULL;
2434 unsigned char start, end;
2435 unsigned char depth = 0;
2436
2437 r_tmp = *mast->orig_r;
2438 l_tmp = *mast->orig_l;
2439 do {
2440 mas_ascend(mast->orig_r);
2441 mas_ascend(mast->orig_l);
2442 depth++;
2443 if (!ancestor &&
2444 (mast->orig_r->node == mast->orig_l->node)) {
2445 ancestor = mast->orig_r->node;
2446 end = mast->orig_r->offset - 1;
2447 start = mast->orig_l->offset + 1;
2448 }
2449
2450 if (mast->orig_r->offset < mas_data_end(mast->orig_r)) {
2451 if (!ancestor) {
2452 ancestor = mast->orig_r->node;
2453 start = 0;
2454 }
2455
2456 mast->orig_r->offset++;
2457 do {
2458 mas_descend(mast->orig_r);
2459 mast->orig_r->offset = 0;
2460 depth--;
2461 } while (depth);
2462
2463 mast_rebalance_next(mast);
2464 do {
2465 unsigned char l_off = 0;
2466 struct maple_enode *child = r_tmp.node;
2467
2468 mas_ascend(&r_tmp);
2469 if (ancestor == r_tmp.node)
2470 l_off = start;
2471
2472 if (r_tmp.offset)
2473 r_tmp.offset--;
2474
2475 if (l_off < r_tmp.offset)
2476 mas_topiary_range(&r_tmp, mast->destroy,
2477 l_off, r_tmp.offset);
2478
2479 if (l_tmp.node != child)
2480 mat_add(mast->free, child);
2481
2482 } while (r_tmp.node != ancestor);
2483
2484 *mast->orig_l = l_tmp;
2485 return true;
2486
2487 } else if (mast->orig_l->offset != 0) {
2488 if (!ancestor) {
2489 ancestor = mast->orig_l->node;
2490 end = mas_data_end(mast->orig_l);
2491 }
2492
2493 mast->orig_l->offset--;
2494 do {
2495 mas_descend(mast->orig_l);
2496 mast->orig_l->offset =
2497 mas_data_end(mast->orig_l);
2498 depth--;
2499 } while (depth);
2500
2501 mast_rebalance_prev(mast);
2502 do {
2503 unsigned char r_off;
2504 struct maple_enode *child = l_tmp.node;
2505
2506 mas_ascend(&l_tmp);
2507 if (ancestor == l_tmp.node)
2508 r_off = end;
2509 else
2510 r_off = mas_data_end(&l_tmp);
2511
2512 if (l_tmp.offset < r_off)
2513 l_tmp.offset++;
2514
2515 if (l_tmp.offset < r_off)
2516 mas_topiary_range(&l_tmp, mast->destroy,
2517 l_tmp.offset, r_off);
2518
2519 if (r_tmp.node != child)
2520 mat_add(mast->free, child);
2521
2522 } while (l_tmp.node != ancestor);
2523
2524 *mast->orig_r = r_tmp;
2525 return true;
2526 }
2527 } while (!mte_is_root(mast->orig_r->node));
2528
2529 *mast->orig_r = r_tmp;
2530 *mast->orig_l = l_tmp;
2531 return false;
2532}
2533
2534/*
2535 * mast_ascend_free() - Add current original maple state nodes to the free list
2536 * and ascend.
2537 * @mast: the maple subtree state.
2538 *
2539 * Ascend the original left and right sides and add the previous nodes to the
2540 * free list. Set the slots to point to the correct location in the new nodes.
2541 */
2542static inline void
2543mast_ascend_free(struct maple_subtree_state *mast)
2544{
2545 MA_WR_STATE(wr_mas, mast->orig_r, NULL);
2546 struct maple_enode *left = mast->orig_l->node;
2547 struct maple_enode *right = mast->orig_r->node;
2548
2549 mas_ascend(mast->orig_l);
2550 mas_ascend(mast->orig_r);
2551 mat_add(mast->free, left);
2552
2553 if (left != right)
2554 mat_add(mast->free, right);
2555
2556 mast->orig_r->offset = 0;
2557 mast->orig_r->index = mast->r->max;
2558 /* last should be larger than or equal to index */
2559 if (mast->orig_r->last < mast->orig_r->index)
2560 mast->orig_r->last = mast->orig_r->index;
2561 /*
2562 * The node may not contain the value so set slot to ensure all
2563 * of the nodes contents are freed or destroyed.
2564 */
2565 wr_mas.type = mte_node_type(mast->orig_r->node);
2566 mas_wr_node_walk(&wr_mas);
2567 /* Set up the left side of things */
2568 mast->orig_l->offset = 0;
2569 mast->orig_l->index = mast->l->min;
2570 wr_mas.mas = mast->orig_l;
2571 wr_mas.type = mte_node_type(mast->orig_l->node);
2572 mas_wr_node_walk(&wr_mas);
2573
2574 mast->bn->type = wr_mas.type;
2575}
2576
2577/*
2578 * mas_new_ma_node() - Create and return a new maple node. Helper function.
2579 * @mas: the maple state with the allocations.
2580 * @b_node: the maple_big_node with the type encoding.
2581 *
2582 * Use the node type from the maple_big_node to allocate a new node from the
2583 * ma_state. This function exists mainly for code readability.
2584 *
2585 * Return: A new maple encoded node
2586 */
2587static inline struct maple_enode
2588*mas_new_ma_node(struct ma_state *mas, struct maple_big_node *b_node)
2589{
2590 return mt_mk_node(ma_mnode_ptr(mas_pop_node(mas)), b_node->type);
2591}
2592
2593/*
2594 * mas_mab_to_node() - Set up right and middle nodes
2595 *
2596 * @mas: the maple state that contains the allocations.
2597 * @b_node: the node which contains the data.
2598 * @left: The pointer which will have the left node
2599 * @right: The pointer which may have the right node
2600 * @middle: the pointer which may have the middle node (rare)
2601 * @mid_split: the split location for the middle node
2602 *
2603 * Return: the split of left.
2604 */
2605static inline unsigned char mas_mab_to_node(struct ma_state *mas,
2606 struct maple_big_node *b_node, struct maple_enode **left,
2607 struct maple_enode **right, struct maple_enode **middle,
2608 unsigned char *mid_split, unsigned long min)
2609{
2610 unsigned char split = 0;
2611 unsigned char slot_count = mt_slots[b_node->type];
2612
2613 *left = mas_new_ma_node(mas, b_node);
2614 *right = NULL;
2615 *middle = NULL;
2616 *mid_split = 0;
2617
2618 if (b_node->b_end < slot_count) {
2619 split = b_node->b_end;
2620 } else {
2621 split = mab_calc_split(mas, b_node, mid_split, min);
2622 *right = mas_new_ma_node(mas, b_node);
2623 }
2624
2625 if (*mid_split)
2626 *middle = mas_new_ma_node(mas, b_node);
2627
2628 return split;
2629
2630}
2631
2632/*
2633 * mab_set_b_end() - Add entry to b_node at b_node->b_end and increment the end
2634 * pointer.
2635 * @b_node - the big node to add the entry
2636 * @mas - the maple state to get the pivot (mas->max)
2637 * @entry - the entry to add, if NULL nothing happens.
2638 */
2639static inline void mab_set_b_end(struct maple_big_node *b_node,
2640 struct ma_state *mas,
2641 void *entry)
2642{
2643 if (!entry)
2644 return;
2645
2646 b_node->slot[b_node->b_end] = entry;
2647 if (mt_is_alloc(mas->tree))
2648 b_node->gap[b_node->b_end] = mas_max_gap(mas);
2649 b_node->pivot[b_node->b_end++] = mas->max;
2650}
2651
2652/*
2653 * mas_set_split_parent() - combine_then_separate helper function. Sets the parent
2654 * of @mas->node to either @left or @right, depending on @slot and @split
2655 *
2656 * @mas - the maple state with the node that needs a parent
2657 * @left - possible parent 1
2658 * @right - possible parent 2
2659 * @slot - the slot the mas->node was placed
2660 * @split - the split location between @left and @right
2661 */
2662static inline void mas_set_split_parent(struct ma_state *mas,
2663 struct maple_enode *left,
2664 struct maple_enode *right,
2665 unsigned char *slot, unsigned char split)
2666{
2667 if (mas_is_none(mas))
2668 return;
2669
2670 if ((*slot) <= split)
2671 mte_set_parent(mas->node, left, *slot);
2672 else if (right)
2673 mte_set_parent(mas->node, right, (*slot) - split - 1);
2674
2675 (*slot)++;
2676}
2677
2678/*
2679 * mte_mid_split_check() - Check if the next node passes the mid-split
2680 * @**l: Pointer to left encoded maple node.
2681 * @**m: Pointer to middle encoded maple node.
2682 * @**r: Pointer to right encoded maple node.
2683 * @slot: The offset
2684 * @*split: The split location.
2685 * @mid_split: The middle split.
2686 */
2687static inline void mte_mid_split_check(struct maple_enode **l,
2688 struct maple_enode **r,
2689 struct maple_enode *right,
2690 unsigned char slot,
2691 unsigned char *split,
2692 unsigned char mid_split)
2693{
2694 if (*r == right)
2695 return;
2696
2697 if (slot < mid_split)
2698 return;
2699
2700 *l = *r;
2701 *r = right;
2702 *split = mid_split;
2703}
2704
2705/*
2706 * mast_set_split_parents() - Helper function to set three nodes parents. Slot
2707 * is taken from @mast->l.
2708 * @mast - the maple subtree state
2709 * @left - the left node
2710 * @right - the right node
2711 * @split - the split location.
2712 */
2713static inline void mast_set_split_parents(struct maple_subtree_state *mast,
2714 struct maple_enode *left,
2715 struct maple_enode *middle,
2716 struct maple_enode *right,
2717 unsigned char split,
2718 unsigned char mid_split)
2719{
2720 unsigned char slot;
2721 struct maple_enode *l = left;
2722 struct maple_enode *r = right;
2723
2724 if (mas_is_none(mast->l))
2725 return;
2726
2727 if (middle)
2728 r = middle;
2729
2730 slot = mast->l->offset;
2731
2732 mte_mid_split_check(&l, &r, right, slot, &split, mid_split);
2733 mas_set_split_parent(mast->l, l, r, &slot, split);
2734
2735 mte_mid_split_check(&l, &r, right, slot, &split, mid_split);
2736 mas_set_split_parent(mast->m, l, r, &slot, split);
2737
2738 mte_mid_split_check(&l, &r, right, slot, &split, mid_split);
2739 mas_set_split_parent(mast->r, l, r, &slot, split);
2740}
2741
2742/*
2743 * mas_wmb_replace() - Write memory barrier and replace
2744 * @mas: The maple state
2745 * @free: the maple topiary list of nodes to free
2746 * @destroy: The maple topiary list of nodes to destroy (walk and free)
2747 *
2748 * Updates gap as necessary.
2749 */
2750static inline void mas_wmb_replace(struct ma_state *mas,
2751 struct ma_topiary *free,
2752 struct ma_topiary *destroy)
2753{
2754 /* All nodes must see old data as dead prior to replacing that data */
2755 smp_wmb(); /* Needed for RCU */
2756
2757 /* Insert the new data in the tree */
2758 mas_replace(mas, true);
2759
2760 if (!mte_is_leaf(mas->node))
2761 mas_descend_adopt(mas);
2762
2763 mas_mat_free(mas, free);
2764
2765 if (destroy)
2766 mas_mat_destroy(mas, destroy);
2767
2768 if (mte_is_leaf(mas->node))
2769 return;
2770
2771 mas_update_gap(mas);
2772}
2773
2774/*
2775 * mast_new_root() - Set a new tree root during subtree creation
2776 * @mast: The maple subtree state
2777 * @mas: The maple state
2778 */
2779static inline void mast_new_root(struct maple_subtree_state *mast,
2780 struct ma_state *mas)
2781{
2782 mas_mn(mast->l)->parent =
2783 ma_parent_ptr(((unsigned long)mas->tree | MA_ROOT_PARENT));
2784 if (!mte_dead_node(mast->orig_l->node) &&
2785 !mte_is_root(mast->orig_l->node)) {
2786 do {
2787 mast_ascend_free(mast);
2788 mast_topiary(mast);
2789 } while (!mte_is_root(mast->orig_l->node));
2790 }
2791 if ((mast->orig_l->node != mas->node) &&
2792 (mast->l->depth > mas_mt_height(mas))) {
2793 mat_add(mast->free, mas->node);
2794 }
2795}
2796
2797/*
2798 * mast_cp_to_nodes() - Copy data out to nodes.
2799 * @mast: The maple subtree state
2800 * @left: The left encoded maple node
2801 * @middle: The middle encoded maple node
2802 * @right: The right encoded maple node
2803 * @split: The location to split between left and (middle ? middle : right)
2804 * @mid_split: The location to split between middle and right.
2805 */
2806static inline void mast_cp_to_nodes(struct maple_subtree_state *mast,
2807 struct maple_enode *left, struct maple_enode *middle,
2808 struct maple_enode *right, unsigned char split, unsigned char mid_split)
2809{
2810 bool new_lmax = true;
2811
2812 mast->l->node = mte_node_or_none(left);
2813 mast->m->node = mte_node_or_none(middle);
2814 mast->r->node = mte_node_or_none(right);
2815
2816 mast->l->min = mast->orig_l->min;
2817 if (split == mast->bn->b_end) {
2818 mast->l->max = mast->orig_r->max;
2819 new_lmax = false;
2820 }
2821
2822 mab_mas_cp(mast->bn, 0, split, mast->l, new_lmax);
2823
2824 if (middle) {
2825 mab_mas_cp(mast->bn, 1 + split, mid_split, mast->m, true);
2826 mast->m->min = mast->bn->pivot[split] + 1;
2827 split = mid_split;
2828 }
2829
2830 mast->r->max = mast->orig_r->max;
2831 if (right) {
2832 mab_mas_cp(mast->bn, 1 + split, mast->bn->b_end, mast->r, false);
2833 mast->r->min = mast->bn->pivot[split] + 1;
2834 }
2835}
2836
2837/*
2838 * mast_combine_cp_left - Copy in the original left side of the tree into the
2839 * combined data set in the maple subtree state big node.
2840 * @mast: The maple subtree state
2841 */
2842static inline void mast_combine_cp_left(struct maple_subtree_state *mast)
2843{
2844 unsigned char l_slot = mast->orig_l->offset;
2845
2846 if (!l_slot)
2847 return;
2848
2849 mas_mab_cp(mast->orig_l, 0, l_slot - 1, mast->bn, 0);
2850}
2851
2852/*
2853 * mast_combine_cp_right: Copy in the original right side of the tree into the
2854 * combined data set in the maple subtree state big node.
2855 * @mast: The maple subtree state
2856 */
2857static inline void mast_combine_cp_right(struct maple_subtree_state *mast)
2858{
2859 if (mast->bn->pivot[mast->bn->b_end - 1] >= mast->orig_r->max)
2860 return;
2861
2862 mas_mab_cp(mast->orig_r, mast->orig_r->offset + 1,
2863 mt_slot_count(mast->orig_r->node), mast->bn,
2864 mast->bn->b_end);
2865 mast->orig_r->last = mast->orig_r->max;
2866}
2867
2868/*
2869 * mast_sufficient: Check if the maple subtree state has enough data in the big
2870 * node to create at least one sufficient node
2871 * @mast: the maple subtree state
2872 */
2873static inline bool mast_sufficient(struct maple_subtree_state *mast)
2874{
2875 if (mast->bn->b_end > mt_min_slot_count(mast->orig_l->node))
2876 return true;
2877
2878 return false;
2879}
2880
2881/*
2882 * mast_overflow: Check if there is too much data in the subtree state for a
2883 * single node.
2884 * @mast: The maple subtree state
2885 */
2886static inline bool mast_overflow(struct maple_subtree_state *mast)
2887{
2888 if (mast->bn->b_end >= mt_slot_count(mast->orig_l->node))
2889 return true;
2890
2891 return false;
2892}
2893
2894static inline void *mtree_range_walk(struct ma_state *mas)
2895{
2896 unsigned long *pivots;
2897 unsigned char offset;
2898 struct maple_node *node;
2899 struct maple_enode *next, *last;
2900 enum maple_type type;
2901 void __rcu **slots;
2902 unsigned char end;
2903 unsigned long max, min;
2904 unsigned long prev_max, prev_min;
2905
2906 last = next = mas->node;
2907 prev_min = min = mas->min;
2908 max = mas->max;
2909 do {
2910 offset = 0;
2911 last = next;
2912 node = mte_to_node(next);
2913 type = mte_node_type(next);
2914 pivots = ma_pivots(node, type);
2915 end = ma_data_end(node, type, pivots, max);
2916 if (unlikely(ma_dead_node(node)))
2917 goto dead_node;
2918
2919 if (pivots[offset] >= mas->index) {
2920 prev_max = max;
2921 prev_min = min;
2922 max = pivots[offset];
2923 goto next;
2924 }
2925
2926 do {
2927 offset++;
2928 } while ((offset < end) && (pivots[offset] < mas->index));
2929
2930 prev_min = min;
2931 min = pivots[offset - 1] + 1;
2932 prev_max = max;
2933 if (likely(offset < end && pivots[offset]))
2934 max = pivots[offset];
2935
2936next:
2937 slots = ma_slots(node, type);
2938 next = mt_slot(mas->tree, slots, offset);
2939 if (unlikely(ma_dead_node(node)))
2940 goto dead_node;
2941 } while (!ma_is_leaf(type));
2942
2943 mas->offset = offset;
2944 mas->index = min;
2945 mas->last = max;
2946 mas->min = prev_min;
2947 mas->max = prev_max;
2948 mas->node = last;
2949 return (void *) next;
2950
2951dead_node:
2952 mas_reset(mas);
2953 return NULL;
2954}
2955
2956/*
2957 * mas_spanning_rebalance() - Rebalance across two nodes which may not be peers.
2958 * @mas: The starting maple state
2959 * @mast: The maple_subtree_state, keeps track of 4 maple states.
2960 * @count: The estimated count of iterations needed.
2961 *
2962 * Follow the tree upwards from @l_mas and @r_mas for @count, or until the root
2963 * is hit. First @b_node is split into two entries which are inserted into the
2964 * next iteration of the loop. @b_node is returned populated with the final
2965 * iteration. @mas is used to obtain allocations. orig_l_mas keeps track of the
2966 * nodes that will remain active by using orig_l_mas->index and orig_l_mas->last
2967 * to account of what has been copied into the new sub-tree. The update of
2968 * orig_l_mas->last is used in mas_consume to find the slots that will need to
2969 * be either freed or destroyed. orig_l_mas->depth keeps track of the height of
2970 * the new sub-tree in case the sub-tree becomes the full tree.
2971 *
2972 * Return: the number of elements in b_node during the last loop.
2973 */
2974static int mas_spanning_rebalance(struct ma_state *mas,
2975 struct maple_subtree_state *mast, unsigned char count)
2976{
2977 unsigned char split, mid_split;
2978 unsigned char slot = 0;
2979 struct maple_enode *left = NULL, *middle = NULL, *right = NULL;
2980
2981 MA_STATE(l_mas, mas->tree, mas->index, mas->index);
2982 MA_STATE(r_mas, mas->tree, mas->index, mas->last);
2983 MA_STATE(m_mas, mas->tree, mas->index, mas->index);
2984 MA_TOPIARY(free, mas->tree);
2985 MA_TOPIARY(destroy, mas->tree);
2986
2987 /*
2988 * The tree needs to be rebalanced and leaves need to be kept at the same level.
2989 * Rebalancing is done by use of the ``struct maple_topiary``.
2990 */
2991 mast->l = &l_mas;
2992 mast->m = &m_mas;
2993 mast->r = &r_mas;
2994 mast->free = &free;
2995 mast->destroy = &destroy;
2996 l_mas.node = r_mas.node = m_mas.node = MAS_NONE;
2997 if (!(mast->orig_l->min && mast->orig_r->max == ULONG_MAX) &&
2998 unlikely(mast->bn->b_end <= mt_min_slots[mast->bn->type]))
2999 mast_spanning_rebalance(mast);
3000
3001 mast->orig_l->depth = 0;
3002
3003 /*
3004 * Each level of the tree is examined and balanced, pushing data to the left or
3005 * right, or rebalancing against left or right nodes is employed to avoid
3006 * rippling up the tree to limit the amount of churn. Once a new sub-section of
3007 * the tree is created, there may be a mix of new and old nodes. The old nodes
3008 * will have the incorrect parent pointers and currently be in two trees: the
3009 * original tree and the partially new tree. To remedy the parent pointers in
3010 * the old tree, the new data is swapped into the active tree and a walk down
3011 * the tree is performed and the parent pointers are updated.
3012 * See mas_descend_adopt() for more information..
3013 */
3014 while (count--) {
3015 mast->bn->b_end--;
3016 mast->bn->type = mte_node_type(mast->orig_l->node);
3017 split = mas_mab_to_node(mas, mast->bn, &left, &right, &middle,
3018 &mid_split, mast->orig_l->min);
3019 mast_set_split_parents(mast, left, middle, right, split,
3020 mid_split);
3021 mast_cp_to_nodes(mast, left, middle, right, split, mid_split);
3022
3023 /*
3024 * Copy data from next level in the tree to mast->bn from next
3025 * iteration
3026 */
3027 memset(mast->bn, 0, sizeof(struct maple_big_node));
3028 mast->bn->type = mte_node_type(left);
3029 mast->orig_l->depth++;
3030
3031 /* Root already stored in l->node. */
3032 if (mas_is_root_limits(mast->l))
3033 goto new_root;
3034
3035 mast_ascend_free(mast);
3036 mast_combine_cp_left(mast);
3037 l_mas.offset = mast->bn->b_end;
3038 mab_set_b_end(mast->bn, &l_mas, left);
3039 mab_set_b_end(mast->bn, &m_mas, middle);
3040 mab_set_b_end(mast->bn, &r_mas, right);
3041
3042 /* Copy anything necessary out of the right node. */
3043 mast_combine_cp_right(mast);
3044 mast_topiary(mast);
3045 mast->orig_l->last = mast->orig_l->max;
3046
3047 if (mast_sufficient(mast))
3048 continue;
3049
3050 if (mast_overflow(mast))
3051 continue;
3052
3053 /* May be a new root stored in mast->bn */
3054 if (mas_is_root_limits(mast->orig_l))
3055 break;
3056
3057 mast_spanning_rebalance(mast);
3058
3059 /* rebalancing from other nodes may require another loop. */
3060 if (!count)
3061 count++;
3062 }
3063
3064 l_mas.node = mt_mk_node(ma_mnode_ptr(mas_pop_node(mas)),
3065 mte_node_type(mast->orig_l->node));
3066 mast->orig_l->depth++;
3067 mab_mas_cp(mast->bn, 0, mt_slots[mast->bn->type] - 1, &l_mas, true);
3068 mte_set_parent(left, l_mas.node, slot);
3069 if (middle)
3070 mte_set_parent(middle, l_mas.node, ++slot);
3071
3072 if (right)
3073 mte_set_parent(right, l_mas.node, ++slot);
3074
3075 if (mas_is_root_limits(mast->l)) {
3076new_root:
3077 mast_new_root(mast, mas);
3078 } else {
3079 mas_mn(&l_mas)->parent = mas_mn(mast->orig_l)->parent;
3080 }
3081
3082 if (!mte_dead_node(mast->orig_l->node))
3083 mat_add(&free, mast->orig_l->node);
3084
3085 mas->depth = mast->orig_l->depth;
3086 *mast->orig_l = l_mas;
3087 mte_set_node_dead(mas->node);
3088
3089 /* Set up mas for insertion. */
3090 mast->orig_l->depth = mas->depth;
3091 mast->orig_l->alloc = mas->alloc;
3092 *mas = *mast->orig_l;
3093 mas_wmb_replace(mas, &free, &destroy);
3094 mtree_range_walk(mas);
3095 return mast->bn->b_end;
3096}
3097
3098/*
3099 * mas_rebalance() - Rebalance a given node.
3100 * @mas: The maple state
3101 * @b_node: The big maple node.
3102 *
3103 * Rebalance two nodes into a single node or two new nodes that are sufficient.
3104 * Continue upwards until tree is sufficient.
3105 *
3106 * Return: the number of elements in b_node during the last loop.
3107 */
3108static inline int mas_rebalance(struct ma_state *mas,
3109 struct maple_big_node *b_node)
3110{
3111 char empty_count = mas_mt_height(mas);
3112 struct maple_subtree_state mast;
3113 unsigned char shift, b_end = ++b_node->b_end;
3114
3115 MA_STATE(l_mas, mas->tree, mas->index, mas->last);
3116 MA_STATE(r_mas, mas->tree, mas->index, mas->last);
3117
3118 trace_ma_op(__func__, mas);
3119
3120 /*
3121 * Rebalancing occurs if a node is insufficient. Data is rebalanced
3122 * against the node to the right if it exists, otherwise the node to the
3123 * left of this node is rebalanced against this node. If rebalancing
3124 * causes just one node to be produced instead of two, then the parent
3125 * is also examined and rebalanced if it is insufficient. Every level
3126 * tries to combine the data in the same way. If one node contains the
3127 * entire range of the tree, then that node is used as a new root node.
3128 */
3129 mas_node_count(mas, 1 + empty_count * 3);
3130 if (mas_is_err(mas))
3131 return 0;
3132
3133 mast.orig_l = &l_mas;
3134 mast.orig_r = &r_mas;
3135 mast.bn = b_node;
3136 mast.bn->type = mte_node_type(mas->node);
3137
3138 l_mas = r_mas = *mas;
3139
3140 if (mas_next_sibling(&r_mas)) {
3141 mas_mab_cp(&r_mas, 0, mt_slot_count(r_mas.node), b_node, b_end);
3142 r_mas.last = r_mas.index = r_mas.max;
3143 } else {
3144 mas_prev_sibling(&l_mas);
3145 shift = mas_data_end(&l_mas) + 1;
3146 mab_shift_right(b_node, shift);
3147 mas->offset += shift;
3148 mas_mab_cp(&l_mas, 0, shift - 1, b_node, 0);
3149 b_node->b_end = shift + b_end;
3150 l_mas.index = l_mas.last = l_mas.min;
3151 }
3152
3153 return mas_spanning_rebalance(mas, &mast, empty_count);
3154}
3155
3156/*
3157 * mas_destroy_rebalance() - Rebalance left-most node while destroying the maple
3158 * state.
3159 * @mas: The maple state
3160 * @end: The end of the left-most node.
3161 *
3162 * During a mass-insert event (such as forking), it may be necessary to
3163 * rebalance the left-most node when it is not sufficient.
3164 */
3165static inline void mas_destroy_rebalance(struct ma_state *mas, unsigned char end)
3166{
3167 enum maple_type mt = mte_node_type(mas->node);
3168 struct maple_node reuse, *newnode, *parent, *new_left, *left, *node;
3169 struct maple_enode *eparent;
3170 unsigned char offset, tmp, split = mt_slots[mt] / 2;
3171 void __rcu **l_slots, **slots;
3172 unsigned long *l_pivs, *pivs, gap;
3173 bool in_rcu = mt_in_rcu(mas->tree);
3174
3175 MA_STATE(l_mas, mas->tree, mas->index, mas->last);
3176
3177 l_mas = *mas;
3178 mas_prev_sibling(&l_mas);
3179
3180 /* set up node. */
3181 if (in_rcu) {
3182 /* Allocate for both left and right as well as parent. */
3183 mas_node_count(mas, 3);
3184 if (mas_is_err(mas))
3185 return;
3186
3187 newnode = mas_pop_node(mas);
3188 } else {
3189 newnode = &reuse;
3190 }
3191
3192 node = mas_mn(mas);
3193 newnode->parent = node->parent;
3194 slots = ma_slots(newnode, mt);
3195 pivs = ma_pivots(newnode, mt);
3196 left = mas_mn(&l_mas);
3197 l_slots = ma_slots(left, mt);
3198 l_pivs = ma_pivots(left, mt);
3199 if (!l_slots[split])
3200 split++;
3201 tmp = mas_data_end(&l_mas) - split;
3202
3203 memcpy(slots, l_slots + split + 1, sizeof(void *) * tmp);
3204 memcpy(pivs, l_pivs + split + 1, sizeof(unsigned long) * tmp);
3205 pivs[tmp] = l_mas.max;
3206 memcpy(slots + tmp, ma_slots(node, mt), sizeof(void *) * end);
3207 memcpy(pivs + tmp, ma_pivots(node, mt), sizeof(unsigned long) * end);
3208
3209 l_mas.max = l_pivs[split];
3210 mas->min = l_mas.max + 1;
3211 eparent = mt_mk_node(mte_parent(l_mas.node),
3212 mas_parent_enum(&l_mas, l_mas.node));
3213 tmp += end;
3214 if (!in_rcu) {
3215 unsigned char max_p = mt_pivots[mt];
3216 unsigned char max_s = mt_slots[mt];
3217
3218 if (tmp < max_p)
3219 memset(pivs + tmp, 0,
3220 sizeof(unsigned long *) * (max_p - tmp));
3221
3222 if (tmp < mt_slots[mt])
3223 memset(slots + tmp, 0, sizeof(void *) * (max_s - tmp));
3224
3225 memcpy(node, newnode, sizeof(struct maple_node));
3226 ma_set_meta(node, mt, 0, tmp - 1);
3227 mte_set_pivot(eparent, mte_parent_slot(l_mas.node),
3228 l_pivs[split]);
3229
3230 /* Remove data from l_pivs. */
3231 tmp = split + 1;
3232 memset(l_pivs + tmp, 0, sizeof(unsigned long) * (max_p - tmp));
3233 memset(l_slots + tmp, 0, sizeof(void *) * (max_s - tmp));
3234 ma_set_meta(left, mt, 0, split);
3235
3236 goto done;
3237 }
3238
3239 /* RCU requires replacing both l_mas, mas, and parent. */
3240 mas->node = mt_mk_node(newnode, mt);
3241 ma_set_meta(newnode, mt, 0, tmp);
3242
3243 new_left = mas_pop_node(mas);
3244 new_left->parent = left->parent;
3245 mt = mte_node_type(l_mas.node);
3246 slots = ma_slots(new_left, mt);
3247 pivs = ma_pivots(new_left, mt);
3248 memcpy(slots, l_slots, sizeof(void *) * split);
3249 memcpy(pivs, l_pivs, sizeof(unsigned long) * split);
3250 ma_set_meta(new_left, mt, 0, split);
3251 l_mas.node = mt_mk_node(new_left, mt);
3252
3253 /* replace parent. */
3254 offset = mte_parent_slot(mas->node);
3255 mt = mas_parent_enum(&l_mas, l_mas.node);
3256 parent = mas_pop_node(mas);
3257 slots = ma_slots(parent, mt);
3258 pivs = ma_pivots(parent, mt);
3259 memcpy(parent, mte_to_node(eparent), sizeof(struct maple_node));
3260 rcu_assign_pointer(slots[offset], mas->node);
3261 rcu_assign_pointer(slots[offset - 1], l_mas.node);
3262 pivs[offset - 1] = l_mas.max;
3263 eparent = mt_mk_node(parent, mt);
3264done:
3265 gap = mas_leaf_max_gap(mas);
3266 mte_set_gap(eparent, mte_parent_slot(mas->node), gap);
3267 gap = mas_leaf_max_gap(&l_mas);
3268 mte_set_gap(eparent, mte_parent_slot(l_mas.node), gap);
3269 mas_ascend(mas);
3270
3271 if (in_rcu)
3272 mas_replace(mas, false);
3273
3274 mas_update_gap(mas);
3275}
3276
3277/*
3278 * mas_split_final_node() - Split the final node in a subtree operation.
3279 * @mast: the maple subtree state
3280 * @mas: The maple state
3281 * @height: The height of the tree in case it's a new root.
3282 */
3283static inline bool mas_split_final_node(struct maple_subtree_state *mast,
3284 struct ma_state *mas, int height)
3285{
3286 struct maple_enode *ancestor;
3287
3288 if (mte_is_root(mas->node)) {
3289 if (mt_is_alloc(mas->tree))
3290 mast->bn->type = maple_arange_64;
3291 else
3292 mast->bn->type = maple_range_64;
3293 mas->depth = height;
3294 }
3295 /*
3296 * Only a single node is used here, could be root.
3297 * The Big_node data should just fit in a single node.
3298 */
3299 ancestor = mas_new_ma_node(mas, mast->bn);
3300 mte_set_parent(mast->l->node, ancestor, mast->l->offset);
3301 mte_set_parent(mast->r->node, ancestor, mast->r->offset);
3302 mte_to_node(ancestor)->parent = mas_mn(mas)->parent;
3303
3304 mast->l->node = ancestor;
3305 mab_mas_cp(mast->bn, 0, mt_slots[mast->bn->type] - 1, mast->l, true);
3306 mas->offset = mast->bn->b_end - 1;
3307 return true;
3308}
3309
3310/*
3311 * mast_fill_bnode() - Copy data into the big node in the subtree state
3312 * @mast: The maple subtree state
3313 * @mas: the maple state
3314 * @skip: The number of entries to skip for new nodes insertion.
3315 */
3316static inline void mast_fill_bnode(struct maple_subtree_state *mast,
3317 struct ma_state *mas,
3318 unsigned char skip)
3319{
3320 bool cp = true;
3321 struct maple_enode *old = mas->node;
3322 unsigned char split;
3323
3324 memset(mast->bn->gap, 0, sizeof(unsigned long) * ARRAY_SIZE(mast->bn->gap));
3325 memset(mast->bn->slot, 0, sizeof(unsigned long) * ARRAY_SIZE(mast->bn->slot));
3326 memset(mast->bn->pivot, 0, sizeof(unsigned long) * ARRAY_SIZE(mast->bn->pivot));
3327 mast->bn->b_end = 0;
3328
3329 if (mte_is_root(mas->node)) {
3330 cp = false;
3331 } else {
3332 mas_ascend(mas);
3333 mat_add(mast->free, old);
3334 mas->offset = mte_parent_slot(mas->node);
3335 }
3336
3337 if (cp && mast->l->offset)
3338 mas_mab_cp(mas, 0, mast->l->offset - 1, mast->bn, 0);
3339
3340 split = mast->bn->b_end;
3341 mab_set_b_end(mast->bn, mast->l, mast->l->node);
3342 mast->r->offset = mast->bn->b_end;
3343 mab_set_b_end(mast->bn, mast->r, mast->r->node);
3344 if (mast->bn->pivot[mast->bn->b_end - 1] == mas->max)
3345 cp = false;
3346
3347 if (cp)
3348 mas_mab_cp(mas, split + skip, mt_slot_count(mas->node) - 1,
3349 mast->bn, mast->bn->b_end);
3350
3351 mast->bn->b_end--;
3352 mast->bn->type = mte_node_type(mas->node);
3353}
3354
3355/*
3356 * mast_split_data() - Split the data in the subtree state big node into regular
3357 * nodes.
3358 * @mast: The maple subtree state
3359 * @mas: The maple state
3360 * @split: The location to split the big node
3361 */
3362static inline void mast_split_data(struct maple_subtree_state *mast,
3363 struct ma_state *mas, unsigned char split)
3364{
3365 unsigned char p_slot;
3366
3367 mab_mas_cp(mast->bn, 0, split, mast->l, true);
3368 mte_set_pivot(mast->r->node, 0, mast->r->max);
3369 mab_mas_cp(mast->bn, split + 1, mast->bn->b_end, mast->r, false);
3370 mast->l->offset = mte_parent_slot(mas->node);
3371 mast->l->max = mast->bn->pivot[split];
3372 mast->r->min = mast->l->max + 1;
3373 if (mte_is_leaf(mas->node))
3374 return;
3375
3376 p_slot = mast->orig_l->offset;
3377 mas_set_split_parent(mast->orig_l, mast->l->node, mast->r->node,
3378 &p_slot, split);
3379 mas_set_split_parent(mast->orig_r, mast->l->node, mast->r->node,
3380 &p_slot, split);
3381}
3382
3383/*
3384 * mas_push_data() - Instead of splitting a node, it is beneficial to push the
3385 * data to the right or left node if there is room.
3386 * @mas: The maple state
3387 * @height: The current height of the maple state
3388 * @mast: The maple subtree state
3389 * @left: Push left or not.
3390 *
3391 * Keeping the height of the tree low means faster lookups.
3392 *
3393 * Return: True if pushed, false otherwise.
3394 */
3395static inline bool mas_push_data(struct ma_state *mas, int height,
3396 struct maple_subtree_state *mast, bool left)
3397{
3398 unsigned char slot_total = mast->bn->b_end;
3399 unsigned char end, space, split;
3400
3401 MA_STATE(tmp_mas, mas->tree, mas->index, mas->last);
3402 tmp_mas = *mas;
3403 tmp_mas.depth = mast->l->depth;
3404
3405 if (left && !mas_prev_sibling(&tmp_mas))
3406 return false;
3407 else if (!left && !mas_next_sibling(&tmp_mas))
3408 return false;
3409
3410 end = mas_data_end(&tmp_mas);
3411 slot_total += end;
3412 space = 2 * mt_slot_count(mas->node) - 2;
3413 /* -2 instead of -1 to ensure there isn't a triple split */
3414 if (ma_is_leaf(mast->bn->type))
3415 space--;
3416
3417 if (mas->max == ULONG_MAX)
3418 space--;
3419
3420 if (slot_total >= space)
3421 return false;
3422
3423 /* Get the data; Fill mast->bn */
3424 mast->bn->b_end++;
3425 if (left) {
3426 mab_shift_right(mast->bn, end + 1);
3427 mas_mab_cp(&tmp_mas, 0, end, mast->bn, 0);
3428 mast->bn->b_end = slot_total + 1;
3429 } else {
3430 mas_mab_cp(&tmp_mas, 0, end, mast->bn, mast->bn->b_end);
3431 }
3432
3433 /* Configure mast for splitting of mast->bn */
3434 split = mt_slots[mast->bn->type] - 2;
3435 if (left) {
3436 /* Switch mas to prev node */
3437 mat_add(mast->free, mas->node);
3438 *mas = tmp_mas;
3439 /* Start using mast->l for the left side. */
3440 tmp_mas.node = mast->l->node;
3441 *mast->l = tmp_mas;
3442 } else {
3443 mat_add(mast->free, tmp_mas.node);
3444 tmp_mas.node = mast->r->node;
3445 *mast->r = tmp_mas;
3446 split = slot_total - split;
3447 }
3448 split = mab_no_null_split(mast->bn, split, mt_slots[mast->bn->type]);
3449 /* Update parent slot for split calculation. */
3450 if (left)
3451 mast->orig_l->offset += end + 1;
3452
3453 mast_split_data(mast, mas, split);
3454 mast_fill_bnode(mast, mas, 2);
3455 mas_split_final_node(mast, mas, height + 1);
3456 return true;
3457}
3458
3459/*
3460 * mas_split() - Split data that is too big for one node into two.
3461 * @mas: The maple state
3462 * @b_node: The maple big node
3463 * Return: 1 on success, 0 on failure.
3464 */
3465static int mas_split(struct ma_state *mas, struct maple_big_node *b_node)
3466{
3467
3468 struct maple_subtree_state mast;
3469 int height = 0;
3470 unsigned char mid_split, split = 0;
3471
3472 /*
3473 * Splitting is handled differently from any other B-tree; the Maple
3474 * Tree splits upwards. Splitting up means that the split operation
3475 * occurs when the walk of the tree hits the leaves and not on the way
3476 * down. The reason for splitting up is that it is impossible to know
3477 * how much space will be needed until the leaf is (or leaves are)
3478 * reached. Since overwriting data is allowed and a range could
3479 * overwrite more than one range or result in changing one entry into 3
3480 * entries, it is impossible to know if a split is required until the
3481 * data is examined.
3482 *
3483 * Splitting is a balancing act between keeping allocations to a minimum
3484 * and avoiding a 'jitter' event where a tree is expanded to make room
3485 * for an entry followed by a contraction when the entry is removed. To
3486 * accomplish the balance, there are empty slots remaining in both left
3487 * and right nodes after a split.
3488 */
3489 MA_STATE(l_mas, mas->tree, mas->index, mas->last);
3490 MA_STATE(r_mas, mas->tree, mas->index, mas->last);
3491 MA_STATE(prev_l_mas, mas->tree, mas->index, mas->last);
3492 MA_STATE(prev_r_mas, mas->tree, mas->index, mas->last);
3493 MA_TOPIARY(mat, mas->tree);
3494
3495 trace_ma_op(__func__, mas);
3496 mas->depth = mas_mt_height(mas);
3497 /* Allocation failures will happen early. */
3498 mas_node_count(mas, 1 + mas->depth * 2);
3499 if (mas_is_err(mas))
3500 return 0;
3501
3502 mast.l = &l_mas;
3503 mast.r = &r_mas;
3504 mast.orig_l = &prev_l_mas;
3505 mast.orig_r = &prev_r_mas;
3506 mast.free = &mat;
3507 mast.bn = b_node;
3508
3509 while (height++ <= mas->depth) {
3510 if (mt_slots[b_node->type] > b_node->b_end) {
3511 mas_split_final_node(&mast, mas, height);
3512 break;
3513 }
3514
3515 l_mas = r_mas = *mas;
3516 l_mas.node = mas_new_ma_node(mas, b_node);
3517 r_mas.node = mas_new_ma_node(mas, b_node);
3518 /*
3519 * Another way that 'jitter' is avoided is to terminate a split up early if the
3520 * left or right node has space to spare. This is referred to as "pushing left"
3521 * or "pushing right" and is similar to the B* tree, except the nodes left or
3522 * right can rarely be reused due to RCU, but the ripple upwards is halted which
3523 * is a significant savings.
3524 */
3525 /* Try to push left. */
3526 if (mas_push_data(mas, height, &mast, true))
3527 break;
3528
3529 /* Try to push right. */
3530 if (mas_push_data(mas, height, &mast, false))
3531 break;
3532
3533 split = mab_calc_split(mas, b_node, &mid_split, prev_l_mas.min);
3534 mast_split_data(&mast, mas, split);
3535 /*
3536 * Usually correct, mab_mas_cp in the above call overwrites
3537 * r->max.
3538 */
3539 mast.r->max = mas->max;
3540 mast_fill_bnode(&mast, mas, 1);
3541 prev_l_mas = *mast.l;
3542 prev_r_mas = *mast.r;
3543 }
3544
3545 /* Set the original node as dead */
3546 mat_add(mast.free, mas->node);
3547 mas->node = l_mas.node;
3548 mas_wmb_replace(mas, mast.free, NULL);
3549 mtree_range_walk(mas);
3550 return 1;
3551}
3552
3553/*
3554 * mas_reuse_node() - Reuse the node to store the data.
3555 * @wr_mas: The maple write state
3556 * @bn: The maple big node
3557 * @end: The end of the data.
3558 *
3559 * Will always return false in RCU mode.
3560 *
3561 * Return: True if node was reused, false otherwise.
3562 */
3563static inline bool mas_reuse_node(struct ma_wr_state *wr_mas,
3564 struct maple_big_node *bn, unsigned char end)
3565{
3566 /* Need to be rcu safe. */
3567 if (mt_in_rcu(wr_mas->mas->tree))
3568 return false;
3569
3570 if (end > bn->b_end) {
3571 int clear = mt_slots[wr_mas->type] - bn->b_end;
3572
3573 memset(wr_mas->slots + bn->b_end, 0, sizeof(void *) * clear--);
3574 memset(wr_mas->pivots + bn->b_end, 0, sizeof(void *) * clear);
3575 }
3576 mab_mas_cp(bn, 0, bn->b_end, wr_mas->mas, false);
3577 return true;
3578}
3579
3580/*
3581 * mas_commit_b_node() - Commit the big node into the tree.
3582 * @wr_mas: The maple write state
3583 * @b_node: The maple big node
3584 * @end: The end of the data.
3585 */
3586static inline int mas_commit_b_node(struct ma_wr_state *wr_mas,
3587 struct maple_big_node *b_node, unsigned char end)
3588{
3589 struct maple_node *node;
3590 unsigned char b_end = b_node->b_end;
3591 enum maple_type b_type = b_node->type;
3592
3593 if ((b_end < mt_min_slots[b_type]) &&
3594 (!mte_is_root(wr_mas->mas->node)) &&
3595 (mas_mt_height(wr_mas->mas) > 1))
3596 return mas_rebalance(wr_mas->mas, b_node);
3597
3598 if (b_end >= mt_slots[b_type])
3599 return mas_split(wr_mas->mas, b_node);
3600
3601 if (mas_reuse_node(wr_mas, b_node, end))
3602 goto reuse_node;
3603
3604 mas_node_count(wr_mas->mas, 1);
3605 if (mas_is_err(wr_mas->mas))
3606 return 0;
3607
3608 node = mas_pop_node(wr_mas->mas);
3609 node->parent = mas_mn(wr_mas->mas)->parent;
3610 wr_mas->mas->node = mt_mk_node(node, b_type);
3611 mab_mas_cp(b_node, 0, b_end, wr_mas->mas, true);
3612
3613 mas_replace(wr_mas->mas, false);
3614reuse_node:
3615 mas_update_gap(wr_mas->mas);
3616 return 1;
3617}
3618
3619/*
3620 * mas_root_expand() - Expand a root to a node
3621 * @mas: The maple state
3622 * @entry: The entry to store into the tree
3623 */
3624static inline int mas_root_expand(struct ma_state *mas, void *entry)
3625{
3626 void *contents = mas_root_locked(mas);
3627 enum maple_type type = maple_leaf_64;
3628 struct maple_node *node;
3629 void __rcu **slots;
3630 unsigned long *pivots;
3631 int slot = 0;
3632
3633 mas_node_count(mas, 1);
3634 if (unlikely(mas_is_err(mas)))
3635 return 0;
3636
3637 node = mas_pop_node(mas);
3638 pivots = ma_pivots(node, type);
3639 slots = ma_slots(node, type);
3640 node->parent = ma_parent_ptr(
3641 ((unsigned long)mas->tree | MA_ROOT_PARENT));
3642 mas->node = mt_mk_node(node, type);
3643
3644 if (mas->index) {
3645 if (contents) {
3646 rcu_assign_pointer(slots[slot], contents);
3647 if (likely(mas->index > 1))
3648 slot++;
3649 }
3650 pivots[slot++] = mas->index - 1;
3651 }
3652
3653 rcu_assign_pointer(slots[slot], entry);
3654 mas->offset = slot;
3655 pivots[slot] = mas->last;
3656 if (mas->last != ULONG_MAX)
3657 slot++;
3658 mas->depth = 1;
3659 mas_set_height(mas);
3660
3661 /* swap the new root into the tree */
3662 rcu_assign_pointer(mas->tree->ma_root, mte_mk_root(mas->node));
3663 ma_set_meta(node, maple_leaf_64, 0, slot);
3664 return slot;
3665}
3666
3667static inline void mas_store_root(struct ma_state *mas, void *entry)
3668{
3669 if (likely((mas->last != 0) || (mas->index != 0)))
3670 mas_root_expand(mas, entry);
3671 else if (((unsigned long) (entry) & 3) == 2)
3672 mas_root_expand(mas, entry);
3673 else {
3674 rcu_assign_pointer(mas->tree->ma_root, entry);
3675 mas->node = MAS_START;
3676 }
3677}
3678
3679/*
3680 * mas_is_span_wr() - Check if the write needs to be treated as a write that
3681 * spans the node.
3682 * @mas: The maple state
3683 * @piv: The pivot value being written
3684 * @type: The maple node type
3685 * @entry: The data to write
3686 *
3687 * Spanning writes are writes that start in one node and end in another OR if
3688 * the write of a %NULL will cause the node to end with a %NULL.
3689 *
3690 * Return: True if this is a spanning write, false otherwise.
3691 */
3692static bool mas_is_span_wr(struct ma_wr_state *wr_mas)
3693{
3694 unsigned long max;
3695 unsigned long last = wr_mas->mas->last;
3696 unsigned long piv = wr_mas->r_max;
3697 enum maple_type type = wr_mas->type;
3698 void *entry = wr_mas->entry;
3699
3700 /* Contained in this pivot */
3701 if (piv > last)
3702 return false;
3703
3704 max = wr_mas->mas->max;
3705 if (unlikely(ma_is_leaf(type))) {
3706 /* Fits in the node, but may span slots. */
3707 if (last < max)
3708 return false;
3709
3710 /* Writes to the end of the node but not null. */
3711 if ((last == max) && entry)
3712 return false;
3713
3714 /*
3715 * Writing ULONG_MAX is not a spanning write regardless of the
3716 * value being written as long as the range fits in the node.
3717 */
3718 if ((last == ULONG_MAX) && (last == max))
3719 return false;
3720 } else if (piv == last) {
3721 if (entry)
3722 return false;
3723
3724 /* Detect spanning store wr walk */
3725 if (last == ULONG_MAX)
3726 return false;
3727 }
3728
3729 trace_ma_write(__func__, wr_mas->mas, piv, entry);
3730
3731 return true;
3732}
3733
3734static inline void mas_wr_walk_descend(struct ma_wr_state *wr_mas)
3735{
3736 wr_mas->mas->depth++;
3737 wr_mas->type = mte_node_type(wr_mas->mas->node);
3738 mas_wr_node_walk(wr_mas);
3739 wr_mas->slots = ma_slots(wr_mas->node, wr_mas->type);
3740}
3741
3742static inline void mas_wr_walk_traverse(struct ma_wr_state *wr_mas)
3743{
3744 wr_mas->mas->max = wr_mas->r_max;
3745 wr_mas->mas->min = wr_mas->r_min;
3746 wr_mas->mas->node = wr_mas->content;
3747 wr_mas->mas->offset = 0;
3748}
3749/*
3750 * mas_wr_walk() - Walk the tree for a write.
3751 * @wr_mas: The maple write state
3752 *
3753 * Uses mas_slot_locked() and does not need to worry about dead nodes.
3754 *
3755 * Return: True if it's contained in a node, false on spanning write.
3756 */
3757static bool mas_wr_walk(struct ma_wr_state *wr_mas)
3758{
3759 struct ma_state *mas = wr_mas->mas;
3760
3761 while (true) {
3762 mas_wr_walk_descend(wr_mas);
3763 if (unlikely(mas_is_span_wr(wr_mas)))
3764 return false;
3765
3766 wr_mas->content = mas_slot_locked(mas, wr_mas->slots,
3767 mas->offset);
3768 if (ma_is_leaf(wr_mas->type))
3769 return true;
3770
3771 mas_wr_walk_traverse(wr_mas);
3772 }
3773
3774 return true;
3775}
3776
3777static bool mas_wr_walk_index(struct ma_wr_state *wr_mas)
3778{
3779 struct ma_state *mas = wr_mas->mas;
3780
3781 while (true) {
3782 mas_wr_walk_descend(wr_mas);
3783 wr_mas->content = mas_slot_locked(mas, wr_mas->slots,
3784 mas->offset);
3785 if (ma_is_leaf(wr_mas->type))
3786 return true;
3787 mas_wr_walk_traverse(wr_mas);
3788
3789 }
3790 return true;
3791}
3792/*
3793 * mas_extend_spanning_null() - Extend a store of a %NULL to include surrounding %NULLs.
3794 * @l_wr_mas: The left maple write state
3795 * @r_wr_mas: The right maple write state
3796 */
3797static inline void mas_extend_spanning_null(struct ma_wr_state *l_wr_mas,
3798 struct ma_wr_state *r_wr_mas)
3799{
3800 struct ma_state *r_mas = r_wr_mas->mas;
3801 struct ma_state *l_mas = l_wr_mas->mas;
3802 unsigned char l_slot;
3803
3804 l_slot = l_mas->offset;
3805 if (!l_wr_mas->content)
3806 l_mas->index = l_wr_mas->r_min;
3807
3808 if ((l_mas->index == l_wr_mas->r_min) &&
3809 (l_slot &&
3810 !mas_slot_locked(l_mas, l_wr_mas->slots, l_slot - 1))) {
3811 if (l_slot > 1)
3812 l_mas->index = l_wr_mas->pivots[l_slot - 2] + 1;
3813 else
3814 l_mas->index = l_mas->min;
3815
3816 l_mas->offset = l_slot - 1;
3817 }
3818
3819 if (!r_wr_mas->content) {
3820 if (r_mas->last < r_wr_mas->r_max)
3821 r_mas->last = r_wr_mas->r_max;
3822 r_mas->offset++;
3823 } else if ((r_mas->last == r_wr_mas->r_max) &&
3824 (r_mas->last < r_mas->max) &&
3825 !mas_slot_locked(r_mas, r_wr_mas->slots, r_mas->offset + 1)) {
3826 r_mas->last = mas_safe_pivot(r_mas, r_wr_mas->pivots,
3827 r_wr_mas->type, r_mas->offset + 1);
3828 r_mas->offset++;
3829 }
3830}
3831
3832static inline void *mas_state_walk(struct ma_state *mas)
3833{
3834 void *entry;
3835
3836 entry = mas_start(mas);
3837 if (mas_is_none(mas))
3838 return NULL;
3839
3840 if (mas_is_ptr(mas))
3841 return entry;
3842
3843 return mtree_range_walk(mas);
3844}
3845
3846/*
3847 * mtree_lookup_walk() - Internal quick lookup that does not keep maple state up
3848 * to date.
3849 *
3850 * @mas: The maple state.
3851 *
3852 * Note: Leaves mas in undesirable state.
3853 * Return: The entry for @mas->index or %NULL on dead node.
3854 */
3855static inline void *mtree_lookup_walk(struct ma_state *mas)
3856{
3857 unsigned long *pivots;
3858 unsigned char offset;
3859 struct maple_node *node;
3860 struct maple_enode *next;
3861 enum maple_type type;
3862 void __rcu **slots;
3863 unsigned char end;
3864 unsigned long max;
3865
3866 next = mas->node;
3867 max = ULONG_MAX;
3868 do {
3869 offset = 0;
3870 node = mte_to_node(next);
3871 type = mte_node_type(next);
3872 pivots = ma_pivots(node, type);
3873 end = ma_data_end(node, type, pivots, max);
3874 if (unlikely(ma_dead_node(node)))
3875 goto dead_node;
3876
3877 if (pivots[offset] >= mas->index)
3878 goto next;
3879
3880 do {
3881 offset++;
3882 } while ((offset < end) && (pivots[offset] < mas->index));
3883
3884 if (likely(offset > end))
3885 max = pivots[offset];
3886
3887next:
3888 slots = ma_slots(node, type);
3889 next = mt_slot(mas->tree, slots, offset);
3890 if (unlikely(ma_dead_node(node)))
3891 goto dead_node;
3892 } while (!ma_is_leaf(type));
3893
3894 return (void *) next;
3895
3896dead_node:
3897 mas_reset(mas);
3898 return NULL;
3899}
3900
3901/*
3902 * mas_new_root() - Create a new root node that only contains the entry passed
3903 * in.
3904 * @mas: The maple state
3905 * @entry: The entry to store.
3906 *
3907 * Only valid when the index == 0 and the last == ULONG_MAX
3908 *
3909 * Return 0 on error, 1 on success.
3910 */
3911static inline int mas_new_root(struct ma_state *mas, void *entry)
3912{
3913 struct maple_enode *root = mas_root_locked(mas);
3914 enum maple_type type = maple_leaf_64;
3915 struct maple_node *node;
3916 void __rcu **slots;
3917 unsigned long *pivots;
3918
3919 if (!entry && !mas->index && mas->last == ULONG_MAX) {
3920 mas->depth = 0;
3921 mas_set_height(mas);
3922 rcu_assign_pointer(mas->tree->ma_root, entry);
3923 mas->node = MAS_START;
3924 goto done;
3925 }
3926
3927 mas_node_count(mas, 1);
3928 if (mas_is_err(mas))
3929 return 0;
3930
3931 node = mas_pop_node(mas);
3932 pivots = ma_pivots(node, type);
3933 slots = ma_slots(node, type);
3934 node->parent = ma_parent_ptr(
3935 ((unsigned long)mas->tree | MA_ROOT_PARENT));
3936 mas->node = mt_mk_node(node, type);
3937 rcu_assign_pointer(slots[0], entry);
3938 pivots[0] = mas->last;
3939 mas->depth = 1;
3940 mas_set_height(mas);
3941 rcu_assign_pointer(mas->tree->ma_root, mte_mk_root(mas->node));
3942
3943done:
3944 if (xa_is_node(root))
3945 mte_destroy_walk(root, mas->tree);
3946
3947 return 1;
3948}
3949/*
3950 * mas_wr_spanning_store() - Create a subtree with the store operation completed
3951 * and new nodes where necessary, then place the sub-tree in the actual tree.
3952 * Note that mas is expected to point to the node which caused the store to
3953 * span.
3954 * @wr_mas: The maple write state
3955 *
3956 * Return: 0 on error, positive on success.
3957 */
3958static inline int mas_wr_spanning_store(struct ma_wr_state *wr_mas)
3959{
3960 struct maple_subtree_state mast;
3961 struct maple_big_node b_node;
3962 struct ma_state *mas;
3963 unsigned char height;
3964
3965 /* Left and Right side of spanning store */
3966 MA_STATE(l_mas, NULL, 0, 0);
3967 MA_STATE(r_mas, NULL, 0, 0);
3968
3969 MA_WR_STATE(r_wr_mas, &r_mas, wr_mas->entry);
3970 MA_WR_STATE(l_wr_mas, &l_mas, wr_mas->entry);
3971
3972 /*
3973 * A store operation that spans multiple nodes is called a spanning
3974 * store and is handled early in the store call stack by the function
3975 * mas_is_span_wr(). When a spanning store is identified, the maple
3976 * state is duplicated. The first maple state walks the left tree path
3977 * to ``index``, the duplicate walks the right tree path to ``last``.
3978 * The data in the two nodes are combined into a single node, two nodes,
3979 * or possibly three nodes (see the 3-way split above). A ``NULL``
3980 * written to the last entry of a node is considered a spanning store as
3981 * a rebalance is required for the operation to complete and an overflow
3982 * of data may happen.
3983 */
3984 mas = wr_mas->mas;
3985 trace_ma_op(__func__, mas);
3986
3987 if (unlikely(!mas->index && mas->last == ULONG_MAX))
3988 return mas_new_root(mas, wr_mas->entry);
3989 /*
3990 * Node rebalancing may occur due to this store, so there may be three new
3991 * entries per level plus a new root.
3992 */
3993 height = mas_mt_height(mas);
3994 mas_node_count(mas, 1 + height * 3);
3995 if (mas_is_err(mas))
3996 return 0;
3997
3998 /*
3999 * Set up right side. Need to get to the next offset after the spanning
4000 * store to ensure it's not NULL and to combine both the next node and
4001 * the node with the start together.
4002 */
4003 r_mas = *mas;
4004 /* Avoid overflow, walk to next slot in the tree. */
4005 if (r_mas.last + 1)
4006 r_mas.last++;
4007
4008 r_mas.index = r_mas.last;
4009 mas_wr_walk_index(&r_wr_mas);
4010 r_mas.last = r_mas.index = mas->last;
4011
4012 /* Set up left side. */
4013 l_mas = *mas;
4014 mas_wr_walk_index(&l_wr_mas);
4015
4016 if (!wr_mas->entry) {
4017 mas_extend_spanning_null(&l_wr_mas, &r_wr_mas);
4018 mas->offset = l_mas.offset;
4019 mas->index = l_mas.index;
4020 mas->last = l_mas.last = r_mas.last;
4021 }
4022
4023 /* expanding NULLs may make this cover the entire range */
4024 if (!l_mas.index && r_mas.last == ULONG_MAX) {
4025 mas_set_range(mas, 0, ULONG_MAX);
4026 return mas_new_root(mas, wr_mas->entry);
4027 }
4028
4029 memset(&b_node, 0, sizeof(struct maple_big_node));
4030 /* Copy l_mas and store the value in b_node. */
4031 mas_store_b_node(&l_wr_mas, &b_node, l_wr_mas.node_end);
4032 /* Copy r_mas into b_node. */
4033 if (r_mas.offset <= r_wr_mas.node_end)
4034 mas_mab_cp(&r_mas, r_mas.offset, r_wr_mas.node_end,
4035 &b_node, b_node.b_end + 1);
4036 else
4037 b_node.b_end++;
4038
4039 /* Stop spanning searches by searching for just index. */
4040 l_mas.index = l_mas.last = mas->index;
4041
4042 mast.bn = &b_node;
4043 mast.orig_l = &l_mas;
4044 mast.orig_r = &r_mas;
4045 /* Combine l_mas and r_mas and split them up evenly again. */
4046 return mas_spanning_rebalance(mas, &mast, height + 1);
4047}
4048
4049/*
4050 * mas_wr_node_store() - Attempt to store the value in a node
4051 * @wr_mas: The maple write state
4052 *
4053 * Attempts to reuse the node, but may allocate.
4054 *
4055 * Return: True if stored, false otherwise
4056 */
4057static inline bool mas_wr_node_store(struct ma_wr_state *wr_mas)
4058{
4059 struct ma_state *mas = wr_mas->mas;
4060 void __rcu **dst_slots;
4061 unsigned long *dst_pivots;
4062 unsigned char dst_offset;
4063 unsigned char new_end = wr_mas->node_end;
4064 unsigned char offset;
4065 unsigned char node_slots = mt_slots[wr_mas->type];
4066 struct maple_node reuse, *newnode;
4067 unsigned char copy_size, max_piv = mt_pivots[wr_mas->type];
4068 bool in_rcu = mt_in_rcu(mas->tree);
4069
4070 offset = mas->offset;
4071 if (mas->last == wr_mas->r_max) {
4072 /* runs right to the end of the node */
4073 if (mas->last == mas->max)
4074 new_end = offset;
4075 /* don't copy this offset */
4076 wr_mas->offset_end++;
4077 } else if (mas->last < wr_mas->r_max) {
4078 /* new range ends in this range */
4079 if (unlikely(wr_mas->r_max == ULONG_MAX))
4080 mas_bulk_rebalance(mas, wr_mas->node_end, wr_mas->type);
4081
4082 new_end++;
4083 } else {
4084 if (wr_mas->end_piv == mas->last)
4085 wr_mas->offset_end++;
4086
4087 new_end -= wr_mas->offset_end - offset - 1;
4088 }
4089
4090 /* new range starts within a range */
4091 if (wr_mas->r_min < mas->index)
4092 new_end++;
4093
4094 /* Not enough room */
4095 if (new_end >= node_slots)
4096 return false;
4097
4098 /* Not enough data. */
4099 if (!mte_is_root(mas->node) && (new_end <= mt_min_slots[wr_mas->type]) &&
4100 !(mas->mas_flags & MA_STATE_BULK))
4101 return false;
4102
4103 /* set up node. */
4104 if (in_rcu) {
4105 mas_node_count(mas, 1);
4106 if (mas_is_err(mas))
4107 return false;
4108
4109 newnode = mas_pop_node(mas);
4110 } else {
4111 memset(&reuse, 0, sizeof(struct maple_node));
4112 newnode = &reuse;
4113 }
4114
4115 newnode->parent = mas_mn(mas)->parent;
4116 dst_pivots = ma_pivots(newnode, wr_mas->type);
4117 dst_slots = ma_slots(newnode, wr_mas->type);
4118 /* Copy from start to insert point */
4119 memcpy(dst_pivots, wr_mas->pivots, sizeof(unsigned long) * (offset + 1));
4120 memcpy(dst_slots, wr_mas->slots, sizeof(void *) * (offset + 1));
4121 dst_offset = offset;
4122
4123 /* Handle insert of new range starting after old range */
4124 if (wr_mas->r_min < mas->index) {
4125 mas->offset++;
4126 rcu_assign_pointer(dst_slots[dst_offset], wr_mas->content);
4127 dst_pivots[dst_offset++] = mas->index - 1;
4128 }
4129
4130 /* Store the new entry and range end. */
4131 if (dst_offset < max_piv)
4132 dst_pivots[dst_offset] = mas->last;
4133 mas->offset = dst_offset;
4134 rcu_assign_pointer(dst_slots[dst_offset], wr_mas->entry);
4135
4136 /*
4137 * this range wrote to the end of the node or it overwrote the rest of
4138 * the data
4139 */
4140 if (wr_mas->offset_end > wr_mas->node_end || mas->last >= mas->max) {
4141 new_end = dst_offset;
4142 goto done;
4143 }
4144
4145 dst_offset++;
4146 /* Copy to the end of node if necessary. */
4147 copy_size = wr_mas->node_end - wr_mas->offset_end + 1;
4148 memcpy(dst_slots + dst_offset, wr_mas->slots + wr_mas->offset_end,
4149 sizeof(void *) * copy_size);
4150 if (dst_offset < max_piv) {
4151 if (copy_size > max_piv - dst_offset)
4152 copy_size = max_piv - dst_offset;
4153
4154 memcpy(dst_pivots + dst_offset,
4155 wr_mas->pivots + wr_mas->offset_end,
4156 sizeof(unsigned long) * copy_size);
4157 }
4158
4159 if ((wr_mas->node_end == node_slots - 1) && (new_end < node_slots - 1))
4160 dst_pivots[new_end] = mas->max;
4161
4162done:
4163 mas_leaf_set_meta(mas, newnode, dst_pivots, maple_leaf_64, new_end);
4164 if (in_rcu) {
4165 mas->node = mt_mk_node(newnode, wr_mas->type);
4166 mas_replace(mas, false);
4167 } else {
4168 memcpy(wr_mas->node, newnode, sizeof(struct maple_node));
4169 }
4170 trace_ma_write(__func__, mas, 0, wr_mas->entry);
4171 mas_update_gap(mas);
4172 return true;
4173}
4174
4175/*
4176 * mas_wr_slot_store: Attempt to store a value in a slot.
4177 * @wr_mas: the maple write state
4178 *
4179 * Return: True if stored, false otherwise
4180 */
4181static inline bool mas_wr_slot_store(struct ma_wr_state *wr_mas)
4182{
4183 struct ma_state *mas = wr_mas->mas;
4184 unsigned long lmax; /* Logical max. */
4185 unsigned char offset = mas->offset;
4186
4187 if ((wr_mas->r_max > mas->last) && ((wr_mas->r_min != mas->index) ||
4188 (offset != wr_mas->node_end)))
4189 return false;
4190
4191 if (offset == wr_mas->node_end - 1)
4192 lmax = mas->max;
4193 else
4194 lmax = wr_mas->pivots[offset + 1];
4195
4196 /* going to overwrite too many slots. */
4197 if (lmax < mas->last)
4198 return false;
4199
4200 if (wr_mas->r_min == mas->index) {
4201 /* overwriting two or more ranges with one. */
4202 if (lmax == mas->last)
4203 return false;
4204
4205 /* Overwriting all of offset and a portion of offset + 1. */
4206 rcu_assign_pointer(wr_mas->slots[offset], wr_mas->entry);
4207 wr_mas->pivots[offset] = mas->last;
4208 goto done;
4209 }
4210
4211 /* Doesn't end on the next range end. */
4212 if (lmax != mas->last)
4213 return false;
4214
4215 /* Overwriting a portion of offset and all of offset + 1 */
4216 if ((offset + 1 < mt_pivots[wr_mas->type]) &&
4217 (wr_mas->entry || wr_mas->pivots[offset + 1]))
4218 wr_mas->pivots[offset + 1] = mas->last;
4219
4220 rcu_assign_pointer(wr_mas->slots[offset + 1], wr_mas->entry);
4221 wr_mas->pivots[offset] = mas->index - 1;
4222 mas->offset++; /* Keep mas accurate. */
4223
4224done:
4225 trace_ma_write(__func__, mas, 0, wr_mas->entry);
4226 mas_update_gap(mas);
4227 return true;
4228}
4229
4230static inline void mas_wr_end_piv(struct ma_wr_state *wr_mas)
4231{
4232 while ((wr_mas->mas->last > wr_mas->end_piv) &&
4233 (wr_mas->offset_end < wr_mas->node_end))
4234 wr_mas->end_piv = wr_mas->pivots[++wr_mas->offset_end];
4235
4236 if (wr_mas->mas->last > wr_mas->end_piv)
4237 wr_mas->end_piv = wr_mas->mas->max;
4238}
4239
4240static inline void mas_wr_extend_null(struct ma_wr_state *wr_mas)
4241{
4242 struct ma_state *mas = wr_mas->mas;
4243
4244 if (mas->last < wr_mas->end_piv && !wr_mas->slots[wr_mas->offset_end])
4245 mas->last = wr_mas->end_piv;
4246
4247 /* Check next slot(s) if we are overwriting the end */
4248 if ((mas->last == wr_mas->end_piv) &&
4249 (wr_mas->node_end != wr_mas->offset_end) &&
4250 !wr_mas->slots[wr_mas->offset_end + 1]) {
4251 wr_mas->offset_end++;
4252 if (wr_mas->offset_end == wr_mas->node_end)
4253 mas->last = mas->max;
4254 else
4255 mas->last = wr_mas->pivots[wr_mas->offset_end];
4256 wr_mas->end_piv = mas->last;
4257 }
4258
4259 if (!wr_mas->content) {
4260 /* If this one is null, the next and prev are not */
4261 mas->index = wr_mas->r_min;
4262 } else {
4263 /* Check prev slot if we are overwriting the start */
4264 if (mas->index == wr_mas->r_min && mas->offset &&
4265 !wr_mas->slots[mas->offset - 1]) {
4266 mas->offset--;
4267 wr_mas->r_min = mas->index =
4268 mas_safe_min(mas, wr_mas->pivots, mas->offset);
4269 wr_mas->r_max = wr_mas->pivots[mas->offset];
4270 }
4271 }
4272}
4273
4274static inline bool mas_wr_append(struct ma_wr_state *wr_mas)
4275{
4276 unsigned char end = wr_mas->node_end;
4277 unsigned char new_end = end + 1;
4278 struct ma_state *mas = wr_mas->mas;
4279 unsigned char node_pivots = mt_pivots[wr_mas->type];
4280
4281 if ((mas->index != wr_mas->r_min) && (mas->last == wr_mas->r_max)) {
4282 if (new_end < node_pivots)
4283 wr_mas->pivots[new_end] = wr_mas->pivots[end];
4284
4285 if (new_end < node_pivots)
4286 ma_set_meta(wr_mas->node, maple_leaf_64, 0, new_end);
4287
4288 rcu_assign_pointer(wr_mas->slots[new_end], wr_mas->entry);
4289 mas->offset = new_end;
4290 wr_mas->pivots[end] = mas->index - 1;
4291
4292 return true;
4293 }
4294
4295 if ((mas->index == wr_mas->r_min) && (mas->last < wr_mas->r_max)) {
4296 if (new_end < node_pivots)
4297 wr_mas->pivots[new_end] = wr_mas->pivots[end];
4298
4299 rcu_assign_pointer(wr_mas->slots[new_end], wr_mas->content);
4300 if (new_end < node_pivots)
4301 ma_set_meta(wr_mas->node, maple_leaf_64, 0, new_end);
4302
4303 wr_mas->pivots[end] = mas->last;
4304 rcu_assign_pointer(wr_mas->slots[end], wr_mas->entry);
4305 return true;
4306 }
4307
4308 return false;
4309}
4310
4311/*
4312 * mas_wr_bnode() - Slow path for a modification.
4313 * @wr_mas: The write maple state
4314 *
4315 * This is where split, rebalance end up.
4316 */
4317static void mas_wr_bnode(struct ma_wr_state *wr_mas)
4318{
4319 struct maple_big_node b_node;
4320
4321 trace_ma_write(__func__, wr_mas->mas, 0, wr_mas->entry);
4322 memset(&b_node, 0, sizeof(struct maple_big_node));
4323 mas_store_b_node(wr_mas, &b_node, wr_mas->offset_end);
4324 mas_commit_b_node(wr_mas, &b_node, wr_mas->node_end);
4325}
4326
4327static inline void mas_wr_modify(struct ma_wr_state *wr_mas)
4328{
4329 unsigned char node_slots;
4330 unsigned char node_size;
4331 struct ma_state *mas = wr_mas->mas;
4332
4333 /* Direct replacement */
4334 if (wr_mas->r_min == mas->index && wr_mas->r_max == mas->last) {
4335 rcu_assign_pointer(wr_mas->slots[mas->offset], wr_mas->entry);
4336 if (!!wr_mas->entry ^ !!wr_mas->content)
4337 mas_update_gap(mas);
4338 return;
4339 }
4340
4341 /* Attempt to append */
4342 node_slots = mt_slots[wr_mas->type];
4343 node_size = wr_mas->node_end - wr_mas->offset_end + mas->offset + 2;
4344 if (mas->max == ULONG_MAX)
4345 node_size++;
4346
4347 /* slot and node store will not fit, go to the slow path */
4348 if (unlikely(node_size >= node_slots))
4349 goto slow_path;
4350
4351 if (wr_mas->entry && (wr_mas->node_end < node_slots - 1) &&
4352 (mas->offset == wr_mas->node_end) && mas_wr_append(wr_mas)) {
4353 if (!wr_mas->content || !wr_mas->entry)
4354 mas_update_gap(mas);
4355 return;
4356 }
4357
4358 if ((wr_mas->offset_end - mas->offset <= 1) && mas_wr_slot_store(wr_mas))
4359 return;
4360 else if (mas_wr_node_store(wr_mas))
4361 return;
4362
4363 if (mas_is_err(mas))
4364 return;
4365
4366slow_path:
4367 mas_wr_bnode(wr_mas);
4368}
4369
4370/*
4371 * mas_wr_store_entry() - Internal call to store a value
4372 * @mas: The maple state
4373 * @entry: The entry to store.
4374 *
4375 * Return: The contents that was stored at the index.
4376 */
4377static inline void *mas_wr_store_entry(struct ma_wr_state *wr_mas)
4378{
4379 struct ma_state *mas = wr_mas->mas;
4380
4381 wr_mas->content = mas_start(mas);
4382 if (mas_is_none(mas) || mas_is_ptr(mas)) {
4383 mas_store_root(mas, wr_mas->entry);
4384 return wr_mas->content;
4385 }
4386
4387 if (unlikely(!mas_wr_walk(wr_mas))) {
4388 mas_wr_spanning_store(wr_mas);
4389 return wr_mas->content;
4390 }
4391
4392 /* At this point, we are at the leaf node that needs to be altered. */
4393 wr_mas->end_piv = wr_mas->r_max;
4394 mas_wr_end_piv(wr_mas);
4395
4396 if (!wr_mas->entry)
4397 mas_wr_extend_null(wr_mas);
4398
4399 /* New root for a single pointer */
4400 if (unlikely(!mas->index && mas->last == ULONG_MAX)) {
4401 mas_new_root(mas, wr_mas->entry);
4402 return wr_mas->content;
4403 }
4404
4405 mas_wr_modify(wr_mas);
4406 return wr_mas->content;
4407}
4408
4409/**
4410 * mas_insert() - Internal call to insert a value
4411 * @mas: The maple state
4412 * @entry: The entry to store
4413 *
4414 * Return: %NULL or the contents that already exists at the requested index
4415 * otherwise. The maple state needs to be checked for error conditions.
4416 */
4417static inline void *mas_insert(struct ma_state *mas, void *entry)
4418{
4419 MA_WR_STATE(wr_mas, mas, entry);
4420
4421 /*
4422 * Inserting a new range inserts either 0, 1, or 2 pivots within the
4423 * tree. If the insert fits exactly into an existing gap with a value
4424 * of NULL, then the slot only needs to be written with the new value.
4425 * If the range being inserted is adjacent to another range, then only a
4426 * single pivot needs to be inserted (as well as writing the entry). If
4427 * the new range is within a gap but does not touch any other ranges,
4428 * then two pivots need to be inserted: the start - 1, and the end. As
4429 * usual, the entry must be written. Most operations require a new node
4430 * to be allocated and replace an existing node to ensure RCU safety,
4431 * when in RCU mode. The exception to requiring a newly allocated node
4432 * is when inserting at the end of a node (appending). When done
4433 * carefully, appending can reuse the node in place.
4434 */
4435 wr_mas.content = mas_start(mas);
4436 if (wr_mas.content)
4437 goto exists;
4438
4439 if (mas_is_none(mas) || mas_is_ptr(mas)) {
4440 mas_store_root(mas, entry);
4441 return NULL;
4442 }
4443
4444 /* spanning writes always overwrite something */
4445 if (!mas_wr_walk(&wr_mas))
4446 goto exists;
4447
4448 /* At this point, we are at the leaf node that needs to be altered. */
4449 wr_mas.offset_end = mas->offset;
4450 wr_mas.end_piv = wr_mas.r_max;
4451
4452 if (wr_mas.content || (mas->last > wr_mas.r_max))
4453 goto exists;
4454
4455 if (!entry)
4456 return NULL;
4457
4458 mas_wr_modify(&wr_mas);
4459 return wr_mas.content;
4460
4461exists:
4462 mas_set_err(mas, -EEXIST);
4463 return wr_mas.content;
4464
4465}
4466
4467/*
4468 * mas_prev_node() - Find the prev non-null entry at the same level in the
4469 * tree. The prev value will be mas->node[mas->offset] or MAS_NONE.
4470 * @mas: The maple state
4471 * @min: The lower limit to search
4472 *
4473 * The prev node value will be mas->node[mas->offset] or MAS_NONE.
4474 * Return: 1 if the node is dead, 0 otherwise.
4475 */
4476static inline int mas_prev_node(struct ma_state *mas, unsigned long min)
4477{
4478 enum maple_type mt;
4479 int offset, level;
4480 void __rcu **slots;
4481 struct maple_node *node;
4482 struct maple_enode *enode;
4483 unsigned long *pivots;
4484
4485 if (mas_is_none(mas))
4486 return 0;
4487
4488 level = 0;
4489 do {
4490 node = mas_mn(mas);
4491 if (ma_is_root(node))
4492 goto no_entry;
4493
4494 /* Walk up. */
4495 if (unlikely(mas_ascend(mas)))
4496 return 1;
4497 offset = mas->offset;
4498 level++;
4499 } while (!offset);
4500
4501 offset--;
4502 mt = mte_node_type(mas->node);
4503 node = mas_mn(mas);
4504 slots = ma_slots(node, mt);
4505 pivots = ma_pivots(node, mt);
4506 mas->max = pivots[offset];
4507 if (offset)
4508 mas->min = pivots[offset - 1] + 1;
4509 if (unlikely(ma_dead_node(node)))
4510 return 1;
4511
4512 if (mas->max < min)
4513 goto no_entry_min;
4514
4515 while (level > 1) {
4516 level--;
4517 enode = mas_slot(mas, slots, offset);
4518 if (unlikely(ma_dead_node(node)))
4519 return 1;
4520
4521 mas->node = enode;
4522 mt = mte_node_type(mas->node);
4523 node = mas_mn(mas);
4524 slots = ma_slots(node, mt);
4525 pivots = ma_pivots(node, mt);
4526 offset = ma_data_end(node, mt, pivots, mas->max);
4527 if (offset)
4528 mas->min = pivots[offset - 1] + 1;
4529
4530 if (offset < mt_pivots[mt])
4531 mas->max = pivots[offset];
4532
4533 if (mas->max < min)
4534 goto no_entry;
4535 }
4536
4537 mas->node = mas_slot(mas, slots, offset);
4538 if (unlikely(ma_dead_node(node)))
4539 return 1;
4540
4541 mas->offset = mas_data_end(mas);
4542 if (unlikely(mte_dead_node(mas->node)))
4543 return 1;
4544
4545 return 0;
4546
4547no_entry_min:
4548 mas->offset = offset;
4549 if (offset)
4550 mas->min = pivots[offset - 1] + 1;
4551no_entry:
4552 if (unlikely(ma_dead_node(node)))
4553 return 1;
4554
4555 mas->node = MAS_NONE;
4556 return 0;
4557}
4558
4559/*
4560 * mas_next_node() - Get the next node at the same level in the tree.
4561 * @mas: The maple state
4562 * @max: The maximum pivot value to check.
4563 *
4564 * The next value will be mas->node[mas->offset] or MAS_NONE.
4565 * Return: 1 on dead node, 0 otherwise.
4566 */
4567static inline int mas_next_node(struct ma_state *mas, struct maple_node *node,
4568 unsigned long max)
4569{
4570 unsigned long min, pivot;
4571 unsigned long *pivots;
4572 struct maple_enode *enode;
4573 int level = 0;
4574 unsigned char offset;
4575 enum maple_type mt;
4576 void __rcu **slots;
4577
4578 if (mas->max >= max)
4579 goto no_entry;
4580
4581 level = 0;
4582 do {
4583 if (ma_is_root(node))
4584 goto no_entry;
4585
4586 min = mas->max + 1;
4587 if (min > max)
4588 goto no_entry;
4589
4590 if (unlikely(mas_ascend(mas)))
4591 return 1;
4592
4593 offset = mas->offset;
4594 level++;
4595 node = mas_mn(mas);
4596 mt = mte_node_type(mas->node);
4597 pivots = ma_pivots(node, mt);
4598 } while (unlikely(offset == ma_data_end(node, mt, pivots, mas->max)));
4599
4600 slots = ma_slots(node, mt);
4601 pivot = mas_safe_pivot(mas, pivots, ++offset, mt);
4602 while (unlikely(level > 1)) {
4603 /* Descend, if necessary */
4604 enode = mas_slot(mas, slots, offset);
4605 if (unlikely(ma_dead_node(node)))
4606 return 1;
4607
4608 mas->node = enode;
4609 level--;
4610 node = mas_mn(mas);
4611 mt = mte_node_type(mas->node);
4612 slots = ma_slots(node, mt);
4613 pivots = ma_pivots(node, mt);
4614 offset = 0;
4615 pivot = pivots[0];
4616 }
4617
4618 enode = mas_slot(mas, slots, offset);
4619 if (unlikely(ma_dead_node(node)))
4620 return 1;
4621
4622 mas->node = enode;
4623 mas->min = min;
4624 mas->max = pivot;
4625 return 0;
4626
4627no_entry:
4628 if (unlikely(ma_dead_node(node)))
4629 return 1;
4630
4631 mas->node = MAS_NONE;
4632 return 0;
4633}
4634
4635/*
4636 * mas_next_nentry() - Get the next node entry
4637 * @mas: The maple state
4638 * @max: The maximum value to check
4639 * @*range_start: Pointer to store the start of the range.
4640 *
4641 * Sets @mas->offset to the offset of the next node entry, @mas->last to the
4642 * pivot of the entry.
4643 *
4644 * Return: The next entry, %NULL otherwise
4645 */
4646static inline void *mas_next_nentry(struct ma_state *mas,
4647 struct maple_node *node, unsigned long max, enum maple_type type)
4648{
4649 unsigned char count;
4650 unsigned long pivot;
4651 unsigned long *pivots;
4652 void __rcu **slots;
4653 void *entry;
4654
4655 if (mas->last == mas->max) {
4656 mas->index = mas->max;
4657 return NULL;
4658 }
4659
4660 pivots = ma_pivots(node, type);
4661 slots = ma_slots(node, type);
4662 mas->index = mas_safe_min(mas, pivots, mas->offset);
4663 if (ma_dead_node(node))
4664 return NULL;
4665
4666 if (mas->index > max)
4667 return NULL;
4668
4669 count = ma_data_end(node, type, pivots, mas->max);
4670 if (mas->offset > count)
4671 return NULL;
4672
4673 while (mas->offset < count) {
4674 pivot = pivots[mas->offset];
4675 entry = mas_slot(mas, slots, mas->offset);
4676 if (ma_dead_node(node))
4677 return NULL;
4678
4679 if (entry)
4680 goto found;
4681
4682 if (pivot >= max)
4683 return NULL;
4684
4685 mas->index = pivot + 1;
4686 mas->offset++;
4687 }
4688
4689 if (mas->index > mas->max) {
4690 mas->index = mas->last;
4691 return NULL;
4692 }
4693
4694 pivot = mas_safe_pivot(mas, pivots, mas->offset, type);
4695 entry = mas_slot(mas, slots, mas->offset);
4696 if (ma_dead_node(node))
4697 return NULL;
4698
4699 if (!pivot)
4700 return NULL;
4701
4702 if (!entry)
4703 return NULL;
4704
4705found:
4706 mas->last = pivot;
4707 return entry;
4708}
4709
4710static inline void mas_rewalk(struct ma_state *mas, unsigned long index)
4711{
4712
4713retry:
4714 mas_set(mas, index);
4715 mas_state_walk(mas);
4716 if (mas_is_start(mas))
4717 goto retry;
4718
4719 return;
4720
4721}
4722
4723/*
4724 * mas_next_entry() - Internal function to get the next entry.
4725 * @mas: The maple state
4726 * @limit: The maximum range start.
4727 *
4728 * Set the @mas->node to the next entry and the range_start to
4729 * the beginning value for the entry. Does not check beyond @limit.
4730 * Sets @mas->index and @mas->last to the limit if it is hit.
4731 * Restarts on dead nodes.
4732 *
4733 * Return: the next entry or %NULL.
4734 */
4735static inline void *mas_next_entry(struct ma_state *mas, unsigned long limit)
4736{
4737 void *entry = NULL;
4738 struct maple_enode *prev_node;
4739 struct maple_node *node;
4740 unsigned char offset;
4741 unsigned long last;
4742 enum maple_type mt;
4743
4744 last = mas->last;
4745retry:
4746 offset = mas->offset;
4747 prev_node = mas->node;
4748 node = mas_mn(mas);
4749 mt = mte_node_type(mas->node);
4750 mas->offset++;
4751 if (unlikely(mas->offset >= mt_slots[mt])) {
4752 mas->offset = mt_slots[mt] - 1;
4753 goto next_node;
4754 }
4755
4756 while (!mas_is_none(mas)) {
4757 entry = mas_next_nentry(mas, node, limit, mt);
4758 if (unlikely(ma_dead_node(node))) {
4759 mas_rewalk(mas, last);
4760 goto retry;
4761 }
4762
4763 if (likely(entry))
4764 return entry;
4765
4766 if (unlikely((mas->index > limit)))
4767 break;
4768
4769next_node:
4770 prev_node = mas->node;
4771 offset = mas->offset;
4772 if (unlikely(mas_next_node(mas, node, limit))) {
4773 mas_rewalk(mas, last);
4774 goto retry;
4775 }
4776 mas->offset = 0;
4777 node = mas_mn(mas);
4778 mt = mte_node_type(mas->node);
4779 }
4780
4781 mas->index = mas->last = limit;
4782 mas->offset = offset;
4783 mas->node = prev_node;
4784 return NULL;
4785}
4786
4787/*
4788 * mas_prev_nentry() - Get the previous node entry.
4789 * @mas: The maple state.
4790 * @limit: The lower limit to check for a value.
4791 *
4792 * Return: the entry, %NULL otherwise.
4793 */
4794static inline void *mas_prev_nentry(struct ma_state *mas, unsigned long limit,
4795 unsigned long index)
4796{
4797 unsigned long pivot, min;
4798 unsigned char offset;
4799 struct maple_node *mn;
4800 enum maple_type mt;
4801 unsigned long *pivots;
4802 void __rcu **slots;
4803 void *entry;
4804
4805retry:
4806 if (!mas->offset)
4807 return NULL;
4808
4809 mn = mas_mn(mas);
4810 mt = mte_node_type(mas->node);
4811 offset = mas->offset - 1;
4812 if (offset >= mt_slots[mt])
4813 offset = mt_slots[mt] - 1;
4814
4815 slots = ma_slots(mn, mt);
4816 pivots = ma_pivots(mn, mt);
4817 if (offset == mt_pivots[mt])
4818 pivot = mas->max;
4819 else
4820 pivot = pivots[offset];
4821
4822 if (unlikely(ma_dead_node(mn))) {
4823 mas_rewalk(mas, index);
4824 goto retry;
4825 }
4826
4827 while (offset && ((!mas_slot(mas, slots, offset) && pivot >= limit) ||
4828 !pivot))
4829 pivot = pivots[--offset];
4830
4831 min = mas_safe_min(mas, pivots, offset);
4832 entry = mas_slot(mas, slots, offset);
4833 if (unlikely(ma_dead_node(mn))) {
4834 mas_rewalk(mas, index);
4835 goto retry;
4836 }
4837
4838 if (likely(entry)) {
4839 mas->offset = offset;
4840 mas->last = pivot;
4841 mas->index = min;
4842 }
4843 return entry;
4844}
4845
4846static inline void *mas_prev_entry(struct ma_state *mas, unsigned long min)
4847{
4848 void *entry;
4849
4850retry:
4851 while (likely(!mas_is_none(mas))) {
4852 entry = mas_prev_nentry(mas, min, mas->index);
4853 if (unlikely(mas->last < min))
4854 goto not_found;
4855
4856 if (likely(entry))
4857 return entry;
4858
4859 if (unlikely(mas_prev_node(mas, min))) {
4860 mas_rewalk(mas, mas->index);
4861 goto retry;
4862 }
4863
4864 mas->offset++;
4865 }
4866
4867 mas->offset--;
4868not_found:
4869 mas->index = mas->last = min;
4870 return NULL;
4871}
4872
4873/*
4874 * mas_rev_awalk() - Internal function. Reverse allocation walk. Find the
4875 * highest gap address of a given size in a given node and descend.
4876 * @mas: The maple state
4877 * @size: The needed size.
4878 *
4879 * Return: True if found in a leaf, false otherwise.
4880 *
4881 */
4882static bool mas_rev_awalk(struct ma_state *mas, unsigned long size)
4883{
4884 enum maple_type type = mte_node_type(mas->node);
4885 struct maple_node *node = mas_mn(mas);
4886 unsigned long *pivots, *gaps;
4887 void __rcu **slots;
4888 unsigned long gap = 0;
4889 unsigned long max, min, index;
4890 unsigned char offset;
4891
4892 if (unlikely(mas_is_err(mas)))
4893 return true;
4894
4895 if (ma_is_dense(type)) {
4896 /* dense nodes. */
4897 mas->offset = (unsigned char)(mas->index - mas->min);
4898 return true;
4899 }
4900
4901 pivots = ma_pivots(node, type);
4902 slots = ma_slots(node, type);
4903 gaps = ma_gaps(node, type);
4904 offset = mas->offset;
4905 min = mas_safe_min(mas, pivots, offset);
4906 /* Skip out of bounds. */
4907 while (mas->last < min)
4908 min = mas_safe_min(mas, pivots, --offset);
4909
4910 max = mas_safe_pivot(mas, pivots, offset, type);
4911 index = mas->index;
4912 while (index <= max) {
4913 gap = 0;
4914 if (gaps)
4915 gap = gaps[offset];
4916 else if (!mas_slot(mas, slots, offset))
4917 gap = max - min + 1;
4918
4919 if (gap) {
4920 if ((size <= gap) && (size <= mas->last - min + 1))
4921 break;
4922
4923 if (!gaps) {
4924 /* Skip the next slot, it cannot be a gap. */
4925 if (offset < 2)
4926 goto ascend;
4927
4928 offset -= 2;
4929 max = pivots[offset];
4930 min = mas_safe_min(mas, pivots, offset);
4931 continue;
4932 }
4933 }
4934
4935 if (!offset)
4936 goto ascend;
4937
4938 offset--;
4939 max = min - 1;
4940 min = mas_safe_min(mas, pivots, offset);
4941 }
4942
4943 if (unlikely(index > max)) {
4944 mas_set_err(mas, -EBUSY);
4945 return false;
4946 }
4947
4948 if (unlikely(ma_is_leaf(type))) {
4949 mas->offset = offset;
4950 mas->min = min;
4951 mas->max = min + gap - 1;
4952 return true;
4953 }
4954
4955 /* descend, only happens under lock. */
4956 mas->node = mas_slot(mas, slots, offset);
4957 mas->min = min;
4958 mas->max = max;
4959 mas->offset = mas_data_end(mas);
4960 return false;
4961
4962ascend:
4963 if (mte_is_root(mas->node))
4964 mas_set_err(mas, -EBUSY);
4965
4966 return false;
4967}
4968
4969static inline bool mas_anode_descend(struct ma_state *mas, unsigned long size)
4970{
4971 enum maple_type type = mte_node_type(mas->node);
4972 unsigned long pivot, min, gap = 0;
4973 unsigned char count, offset;
4974 unsigned long *gaps = NULL, *pivots = ma_pivots(mas_mn(mas), type);
4975 void __rcu **slots = ma_slots(mas_mn(mas), type);
4976 bool found = false;
4977
4978 if (ma_is_dense(type)) {
4979 mas->offset = (unsigned char)(mas->index - mas->min);
4980 return true;
4981 }
4982
4983 gaps = ma_gaps(mte_to_node(mas->node), type);
4984 offset = mas->offset;
4985 count = mt_slots[type];
4986 min = mas_safe_min(mas, pivots, offset);
4987 for (; offset < count; offset++) {
4988 pivot = mas_safe_pivot(mas, pivots, offset, type);
4989 if (offset && !pivot)
4990 break;
4991
4992 /* Not within lower bounds */
4993 if (mas->index > pivot)
4994 goto next_slot;
4995
4996 if (gaps)
4997 gap = gaps[offset];
4998 else if (!mas_slot(mas, slots, offset))
4999 gap = min(pivot, mas->last) - max(mas->index, min) + 1;

2131 more lines aren’t shown here.

lib/show_mem.c+2−2
@@ -8,13 +8,13 @@ · 7 unmodified lines
8#include <linux/mm.h>8#include <linux/mm.h>
9#include <linux/cma.h>9#include <linux/cma.h>
10 10
11void show_mem(unsigned int filter, nodemask_t *nodemask)11void __show_mem(unsigned int filter, nodemask_t *nodemask, int max_zone_idx)
12{12{
13 pg_data_t *pgdat;13 pg_data_t *pgdat;
14 unsigned long total = 0, reserved = 0, highmem = 0;14 unsigned long total = 0, reserved = 0, highmem = 0;
15 15
16 printk("Mem-Info:\n");16 printk("Mem-Info:\n");
17 show_free_areas(filter, nodemask);17 __show_free_areas(filter, nodemask, max_zone_idx);
18 18
19 for_each_online_pgdat(pgdat) {19 for_each_online_pgdat(pgdat) {
20 int zoneid;20 int zoneid;
lib/stackdepot.c+24−5
@@ -43,7 +43,8 @@ · 42 unmodified lines
43#define STACK_ALLOC_OFFSET_BITS (STACK_ALLOC_ORDER + PAGE_SHIFT - \43#define STACK_ALLOC_OFFSET_BITS (STACK_ALLOC_ORDER + PAGE_SHIFT - \
44 STACK_ALLOC_ALIGN)44 STACK_ALLOC_ALIGN)
45#define STACK_ALLOC_INDEX_BITS (DEPOT_STACK_BITS - \45#define STACK_ALLOC_INDEX_BITS (DEPOT_STACK_BITS - \
46 STACK_ALLOC_NULL_PROTECTION_BITS - STACK_ALLOC_OFFSET_BITS)46 STACK_ALLOC_NULL_PROTECTION_BITS - \
47 STACK_ALLOC_OFFSET_BITS - STACK_DEPOT_EXTRA_BITS)
47#define STACK_ALLOC_SLABS_CAP 819248#define STACK_ALLOC_SLABS_CAP 8192
48#define STACK_ALLOC_MAX_SLABS \49#define STACK_ALLOC_MAX_SLABS \
49 (((1LL << (STACK_ALLOC_INDEX_BITS)) < STACK_ALLOC_SLABS_CAP) ? \50 (((1LL << (STACK_ALLOC_INDEX_BITS)) < STACK_ALLOC_SLABS_CAP) ? \
@@ -56,6 +57,7 @@ union handle_parts { · 6 unmodified lines
56 u32 slabindex : STACK_ALLOC_INDEX_BITS;57 u32 slabindex : STACK_ALLOC_INDEX_BITS;
57 u32 offset : STACK_ALLOC_OFFSET_BITS;58 u32 offset : STACK_ALLOC_OFFSET_BITS;
58 u32 valid : STACK_ALLOC_NULL_PROTECTION_BITS;59 u32 valid : STACK_ALLOC_NULL_PROTECTION_BITS;
60 u32 extra : STACK_DEPOT_EXTRA_BITS;
59 };61 };
60};62};
61 63
@@ -77,6 +79,14 @@ static int next_slab_inited; · 15 unmodified lines
77static size_t depot_offset;79static size_t depot_offset;
78static DEFINE_RAW_SPINLOCK(depot_lock);80static DEFINE_RAW_SPINLOCK(depot_lock);
79 81
82unsigned int stack_depot_get_extra_bits(depot_stack_handle_t handle)
83{
84 union handle_parts parts = { .handle = handle };
85
86 return parts.extra;
87}
88EXPORT_SYMBOL(stack_depot_get_extra_bits);
89
80static bool init_stack_slab(void **prealloc)90static bool init_stack_slab(void **prealloc)
81{91{
82 if (!*prealloc)92 if (!*prealloc)
@@ -140,6 +150,7 @@ depot_alloc_stack(unsigned long *entries, int size, u32 hash, void **prealloc) · 57 unmodified lines
140 stack->handle.slabindex = depot_index;150 stack->handle.slabindex = depot_index;
141 stack->handle.offset = depot_offset >> STACK_ALLOC_ALIGN;151 stack->handle.offset = depot_offset >> STACK_ALLOC_ALIGN;
142 stack->handle.valid = 1;152 stack->handle.valid = 1;
153 stack->handle.extra = 0;
143 memcpy(stack->entries, entries, flex_array_size(stack, entries, size));154 memcpy(stack->entries, entries, flex_array_size(stack, entries, size));
144 depot_offset += required_size;155 depot_offset += required_size;
145 156
@@ -382,6 +393,7 @@ EXPORT_SYMBOL_GPL(stack_depot_fetch); · 236 unmodified lines
382 *393 *
383 * @entries: Pointer to storage array394 * @entries: Pointer to storage array
384 * @nr_entries: Size of the storage array395 * @nr_entries: Size of the storage array
396 * @extra_bits: Flags to store in unused bits of depot_stack_handle_t
385 * @alloc_flags: Allocation gfp flags397 * @alloc_flags: Allocation gfp flags
386 * @can_alloc: Allocate stack slabs (increased chance of failure if false)398 * @can_alloc: Allocate stack slabs (increased chance of failure if false)
387 *399 *
@@ -393,6 +405,10 @@ EXPORT_SYMBOL_GPL(stack_depot_fetch); · 5 unmodified lines
393 * If the stack trace in @entries is from an interrupt, only the portion up to405 * If the stack trace in @entries is from an interrupt, only the portion up to
394 * interrupt entry is saved.406 * interrupt entry is saved.
395 *407 *
408 * Additional opaque flags can be passed in @extra_bits, stored in the unused
409 * bits of the stack handle, and retrieved using stack_depot_get_extra_bits()
410 * without calling stack_depot_fetch().
411 *
396 * Context: Any context, but setting @can_alloc to %false is required if412 * Context: Any context, but setting @can_alloc to %false is required if
397 * alloc_pages() cannot be used from the current context. Currently413 * alloc_pages() cannot be used from the current context. Currently
398 * this is the case from contexts where neither %GFP_ATOMIC nor414 * this is the case from contexts where neither %GFP_ATOMIC nor
@@ -402,10 +418,11 @@ EXPORT_SYMBOL_GPL(stack_depot_fetch); · 3 unmodified lines
402 */418 */
403depot_stack_handle_t __stack_depot_save(unsigned long *entries,419depot_stack_handle_t __stack_depot_save(unsigned long *entries,
404 unsigned int nr_entries,420 unsigned int nr_entries,
421 unsigned int extra_bits,
405 gfp_t alloc_flags, bool can_alloc)422 gfp_t alloc_flags, bool can_alloc)
406{423{
407 struct stack_record *found = NULL, **bucket;424 struct stack_record *found = NULL, **bucket;
408 depot_stack_handle_t retval = 0;425 union handle_parts retval = { .handle = 0 };
409 struct page *page = NULL;426 struct page *page = NULL;
410 void *prealloc = NULL;427 void *prealloc = NULL;
411 unsigned long flags;428 unsigned long flags;
@@ -489,9 +506,11 @@ exit: · 77 unmodified lines
489 free_pages((unsigned long)prealloc, STACK_ALLOC_ORDER);506 free_pages((unsigned long)prealloc, STACK_ALLOC_ORDER);
490 }507 }
491 if (found)508 if (found)
492 retval = found->handle.handle;509 retval.handle = found->handle.handle;
493fast_exit:510fast_exit:
494 return retval;511 retval.extra = extra_bits;
512
513 return retval.handle;
495}514}
496EXPORT_SYMBOL_GPL(__stack_depot_save);515EXPORT_SYMBOL_GPL(__stack_depot_save);
497 516
@@ -511,6 +530,6 @@ depot_stack_handle_t stack_depot_save(unsigned long *entries, · 13 unmodified lines
511 unsigned int nr_entries,530 unsigned int nr_entries,
512 gfp_t alloc_flags)531 gfp_t alloc_flags)
513{532{
514 return __stack_depot_save(entries, nr_entries, alloc_flags, true);533 return __stack_depot_save(entries, nr_entries, 0, alloc_flags, true);
515}534}
516EXPORT_SYMBOL_GPL(stack_depot_save);535EXPORT_SYMBOL_GPL(stack_depot_save);
lib/string.c+8−0
@@ -197,6 +197,14 @@ ssize_t strscpy(char *dest, const char *src, size_t count) · 196 unmodified lines
197 max = 0;197 max = 0;
198#endif198#endif
199 199
200 /*
201 * read_word_at_a_time() below may read uninitialized bytes after the
202 * trailing zero and use them in comparisons. Disable this optimization
203 * under KMSAN to prevent false positive reports.
204 */
205 if (IS_ENABLED(CONFIG_KMSAN))
206 max = 0;
207
200 while (max >= sizeof(unsigned long)) {208 while (max >= sizeof(unsigned long)) {
201 unsigned long c, data;209 unsigned long c, data;
202 210
lib/test_hmm.c+10−3
@@ -107,8 +107,8 @@ struct dmirror_chunk { · 106 unmodified lines
107 */107 */
108struct dmirror_device {108struct dmirror_device {
109 struct cdev cdevice;109 struct cdev cdevice;
110 struct hmm_devmem *devmem;
111 unsigned int zone_device_type;110 unsigned int zone_device_type;
111 struct device device;
112 112
113 unsigned int devmem_capacity;113 unsigned int devmem_capacity;
114 unsigned int devmem_count;114 unsigned int devmem_count;
@@ -1390,7 +1390,14 @@ static int dmirror_device_init(struct dmirror_device *mdevice, int id) · 1275 unmodified lines
1390 1390
1391 cdev_init(&mdevice->cdevice, &dmirror_fops);1391 cdev_init(&mdevice->cdevice, &dmirror_fops);
1392 mdevice->cdevice.owner = THIS_MODULE;1392 mdevice->cdevice.owner = THIS_MODULE;
1393 ret = cdev_add(&mdevice->cdevice, dev, 1);1393 device_initialize(&mdevice->device);
1394 mdevice->device.devt = dev;
1395
1396 ret = dev_set_name(&mdevice->device, "hmm_dmirror%u", id);
1397 if (ret)
1398 return ret;
1399
1400 ret = cdev_device_add(&mdevice->cdevice, &mdevice->device);
1394 if (ret)1401 if (ret)
1395 return ret;1402 return ret;
1396 1403
@@ -1416,7 +1423,7 @@ static void dmirror_device_remove(struct dmirror_device *mdevice) · 19 unmodified lines
1416 kfree(mdevice->devmem_chunks);1423 kfree(mdevice->devmem_chunks);
1417 }1424 }
1418 1425
1419 cdev_del(&mdevice->cdevice);1426 cdev_device_del(&mdevice->cdevice, &mdevice->device);
1420}1427}
1421 1428
1422static int __init hmm_dmirror_init(void)1429static int __init hmm_dmirror_init(void)
lib/test_maple_tree.c+38307−0
@@ -0,0 +1,38307 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * test_maple_tree.c: Test the maple tree API
4 * Copyright (c) 2018 Liam R. Howlett
5 * Author: Liam R. Howlett <Liam.Howlett@Oracle.com>
6 */
7
8#include <linux/maple_tree.h>
9#include <linux/module.h>
10#include <stdlib.h>
11#include <time.h>
12
13#define MTREE_ALLOC_MAX 0x2000000000000Ul
14#define CONFIG_DEBUG_MAPLE_TREE
15#define CONFIG_MAPLE_SEARCH
16/* #define BENCH_SLOT_STORE */
17/* #define BENCH_NODE_STORE */
18/* #define BENCH_AWALK */
19/* #define BENCH_WALK */
20/* #define BENCH_MT_FOR_EACH */
21/* #define BENCH_FORK */
22static
23int mtree_insert_index(struct maple_tree *mt, unsigned long index, gfp_t gfp)
24{
25 return mtree_insert(mt, index, xa_mk_value(index & LONG_MAX), gfp);
26}
27
28static void mtree_erase_index(struct maple_tree *mt, unsigned long index)
29{
30 MT_BUG_ON(mt, mtree_erase(mt, index) != xa_mk_value(index & LONG_MAX));
31 MT_BUG_ON(mt, mtree_load(mt, index) != NULL);
32}
33
34static int mtree_test_insert(struct maple_tree *mt, unsigned long index,
35 void *ptr)
36{
37 return mtree_insert(mt, index, ptr, GFP_KERNEL);
38}
39
40static int mtree_test_store_range(struct maple_tree *mt, unsigned long start,
41 unsigned long end, void *ptr)
42{
43 return mtree_store_range(mt, start, end, ptr, GFP_KERNEL);
44}
45
46static int mtree_test_store(struct maple_tree *mt, unsigned long start,
47 void *ptr)
48{
49 return mtree_test_store_range(mt, start, start, ptr);
50}
51
52static int mtree_test_insert_range(struct maple_tree *mt, unsigned long start,
53 unsigned long end, void *ptr)
54{
55 return mtree_insert_range(mt, start, end, ptr, GFP_KERNEL);
56}
57
58static void *mtree_test_load(struct maple_tree *mt, unsigned long index)
59{
60 return mtree_load(mt, index);
61}
62
63static void *mtree_test_erase(struct maple_tree *mt, unsigned long index)
64{
65 return mtree_erase(mt, index);
66}
67
68static noinline void check_mtree_alloc_range(struct maple_tree *mt,
69 unsigned long start, unsigned long end, unsigned long size,
70 unsigned long expected, int eret, void *ptr)
71{
72
73 unsigned long result = expected + 1;
74 int ret;
75
76 ret = mtree_alloc_range(mt, &result, ptr, size, start, end,
77 GFP_KERNEL);
78 MT_BUG_ON(mt, ret != eret);
79 if (ret)
80 return;
81
82 MT_BUG_ON(mt, result != expected);
83}
84
85static noinline void check_mtree_alloc_rrange(struct maple_tree *mt,
86 unsigned long start, unsigned long end, unsigned long size,
87 unsigned long expected, int eret, void *ptr)
88{
89
90 unsigned long result = expected + 1;
91 int ret;
92
93 ret = mtree_alloc_rrange(mt, &result, ptr, size, start, end - 1,
94 GFP_KERNEL);
95 MT_BUG_ON(mt, ret != eret);
96 if (ret)
97 return;
98
99 MT_BUG_ON(mt, result != expected);
100}
101
102static noinline void check_load(struct maple_tree *mt, unsigned long index,
103 void *ptr)
104{
105 void *ret = mtree_test_load(mt, index);
106
107 if (ret != ptr)
108 pr_err("Load %lu returned %p expect %p\n", index, ret, ptr);
109 MT_BUG_ON(mt, ret != ptr);
110}
111
112static noinline void check_store_range(struct maple_tree *mt,
113 unsigned long start, unsigned long end, void *ptr, int expected)
114{
115 int ret = -EINVAL;
116 unsigned long i;
117
118 ret = mtree_test_store_range(mt, start, end, ptr);
119 MT_BUG_ON(mt, ret != expected);
120
121 if (ret)
122 return;
123
124 for (i = start; i <= end; i++)
125 check_load(mt, i, ptr);
126}
127
128static noinline void check_insert_range(struct maple_tree *mt,
129 unsigned long start, unsigned long end, void *ptr, int expected)
130{
131 int ret = -EINVAL;
132 unsigned long i;
133
134 ret = mtree_test_insert_range(mt, start, end, ptr);
135 MT_BUG_ON(mt, ret != expected);
136
137 if (ret)
138 return;
139
140 for (i = start; i <= end; i++)
141 check_load(mt, i, ptr);
142}
143
144static noinline void check_insert(struct maple_tree *mt, unsigned long index,
145 void *ptr)
146{
147 int ret = -EINVAL;
148
149 ret = mtree_test_insert(mt, index, ptr);
150 MT_BUG_ON(mt, ret != 0);
151}
152
153static noinline void check_erase(struct maple_tree *mt, unsigned long index,
154 void *ptr)
155{
156 MT_BUG_ON(mt, mtree_test_erase(mt, index) != ptr);
157}
158
159static noinline void check_dup_insert(struct maple_tree *mt,
160 unsigned long index, void *ptr)
161{
162 int ret = -EINVAL;
163
164 ret = mtree_test_insert(mt, index, ptr);
165 MT_BUG_ON(mt, ret != -EEXIST);
166}
167
168
169static noinline
170void check_index_load(struct maple_tree *mt, unsigned long index)
171{
172 return check_load(mt, index, xa_mk_value(index & LONG_MAX));
173}
174
175static noinline void check_nomem(struct maple_tree *mt)
176{
177 MA_STATE(ms, mt, 1, 1);
178
179 MT_BUG_ON(mt, !mtree_empty(mt));
180 /* Ensure no bypassing of allocation failures */
181 mt_set_non_kernel(0);
182
183 /* Storing something at 1 requires memory allocation */
184 MT_BUG_ON(mt, mtree_insert(mt, 1, &ms, GFP_ATOMIC) != -ENOMEM);
185 /* Storing something at 0 does not */
186 MT_BUG_ON(mt, mtree_insert(mt, 0, &ms, GFP_ATOMIC) != 0);
187
188 /*
189 * Simulate two threads racing; the first one fails to allocate
190 * memory to insert an entry at 1, then the second one succeeds
191 * in allocating memory to insert an entry at 2. The first one
192 * then needs to free the node it allocated. LeakSanitizer will
193 * notice this, as will the 'nr_allocated' debugging aid in the
194 * userspace test suite.
195 */
196 mtree_lock(mt);
197 mas_store(&ms, &ms); /* insert 1 -> &ms, fails. */
198 MT_BUG_ON(mt, ms.node != MA_ERROR(-ENOMEM));
199 mas_nomem(&ms, GFP_KERNEL); /* Node allocated in here. */
200 MT_BUG_ON(mt, ms.node != MAS_START);
201 mtree_unlock(mt);
202 MT_BUG_ON(mt, mtree_insert(mt, 2, mt, GFP_KERNEL) != 0);
203 mtree_lock(mt);
204 mas_store(&ms, &ms); /* insert 1 -> &ms */
205 mas_nomem(&ms, GFP_KERNEL); /* Node allocated in here. */
206 mtree_unlock(mt);
207 mtree_destroy(mt);
208}
209
210static inline int not_empty(struct maple_node *node)
211{
212 int i;
213
214 if (node->parent)
215 return 1;
216
217 for (i = 0; i < ARRAY_SIZE(node->slot); i++)
218 if (node->slot[i])
219 return 1;
220
221 return 0;
222}
223
224static noinline void check_new_node(struct maple_tree *mt)
225{
226
227 struct maple_node *mn, *mn2, *mn3;
228 struct maple_alloc *smn;
229 struct maple_node *nodes[100];
230 int i, j, total;
231
232 MA_STATE(mas, mt, 0, 0);
233
234 /* Try allocating 3 nodes */
235 mtree_lock(mt);
236 /* request 3 nodes to be allocated. */
237 mas_node_count(&mas, 3);
238 /* Allocation request of 3. */
239 MT_BUG_ON(mt, mas_alloc_req(&mas) != 3);
240 /* Allocate failed. */
241 MT_BUG_ON(mt, mas.node != MA_ERROR(-ENOMEM));
242 MT_BUG_ON(mt, !mas_nomem(&mas, GFP_KERNEL));
243
244 MT_BUG_ON(mt, mas_allocated(&mas) != 3);
245 mn = mas_pop_node(&mas);
246 MT_BUG_ON(mt, not_empty(mn));
247 MT_BUG_ON(mt, mn == NULL);
248 MT_BUG_ON(mt, mas.alloc == NULL);
249 MT_BUG_ON(mt, mas.alloc->slot[0] == NULL);
250 mas_push_node(&mas, mn);
251 mas_nomem(&mas, GFP_KERNEL); /* free */
252 mtree_unlock(mt);
253
254
255 /* Try allocating 1 node, then 2 more */
256 mtree_lock(mt);
257 /* Set allocation request to 1. */
258 mas_set_alloc_req(&mas, 1);
259 /* Check Allocation request of 1. */
260 MT_BUG_ON(mt, mas_alloc_req(&mas) != 1);
261 mas_set_err(&mas, -ENOMEM);
262 /* Validate allocation request. */
263 MT_BUG_ON(mt, !mas_nomem(&mas, GFP_KERNEL));
264 /* Eat the requested node. */
265 mn = mas_pop_node(&mas);
266 MT_BUG_ON(mt, not_empty(mn));
267 MT_BUG_ON(mt, mn == NULL);
268 MT_BUG_ON(mt, mn->slot[0] != NULL);
269 MT_BUG_ON(mt, mn->slot[1] != NULL);
270 MT_BUG_ON(mt, mas_allocated(&mas) != 0);
271
272 ma_free_rcu(mn);
273 mas.node = MAS_START;
274 mas_nomem(&mas, GFP_KERNEL);
275 /* Allocate 3 nodes, will fail. */
276 mas_node_count(&mas, 3);
277 /* Drop the lock and allocate 3 nodes. */
278 mas_nomem(&mas, GFP_KERNEL);
279 /* Ensure 3 are allocated. */
280 MT_BUG_ON(mt, mas_allocated(&mas) != 3);
281 /* Allocation request of 0. */
282 MT_BUG_ON(mt, mas_alloc_req(&mas) != 0);
283
284 MT_BUG_ON(mt, mas.alloc == NULL);
285 MT_BUG_ON(mt, mas.alloc->slot[0] == NULL);
286 MT_BUG_ON(mt, mas.alloc->slot[1] == NULL);
287 /* Ensure we counted 3. */
288 MT_BUG_ON(mt, mas_allocated(&mas) != 3);
289 /* Free. */
290 mas_nomem(&mas, GFP_KERNEL);
291
292 /* Set allocation request to 1. */
293 mas_set_alloc_req(&mas, 1);
294 MT_BUG_ON(mt, mas_alloc_req(&mas) != 1);
295 mas_set_err(&mas, -ENOMEM);
296 /* Validate allocation request. */
297 MT_BUG_ON(mt, !mas_nomem(&mas, GFP_KERNEL));
298 MT_BUG_ON(mt, mas_allocated(&mas) != 1);
299 /* Check the node is only one node. */
300 mn = mas_pop_node(&mas);
301 MT_BUG_ON(mt, not_empty(mn));
302 MT_BUG_ON(mt, mas_allocated(&mas) != 0);
303 MT_BUG_ON(mt, mn == NULL);
304 MT_BUG_ON(mt, mn->slot[0] != NULL);
305 MT_BUG_ON(mt, mn->slot[1] != NULL);
306 MT_BUG_ON(mt, mas_allocated(&mas) != 0);
307 mas_push_node(&mas, mn);
308 MT_BUG_ON(mt, mas_allocated(&mas) != 1);
309 MT_BUG_ON(mt, mas.alloc->node_count);
310
311 mas_set_alloc_req(&mas, 2); /* request 2 more. */
312 MT_BUG_ON(mt, mas_alloc_req(&mas) != 2);
313 mas_set_err(&mas, -ENOMEM);
314 MT_BUG_ON(mt, !mas_nomem(&mas, GFP_KERNEL));
315 MT_BUG_ON(mt, mas_allocated(&mas) != 3);
316 MT_BUG_ON(mt, mas.alloc == NULL);
317 MT_BUG_ON(mt, mas.alloc->slot[0] == NULL);
318 MT_BUG_ON(mt, mas.alloc->slot[1] == NULL);
319 for (i = 2; i >= 0; i--) {
320 mn = mas_pop_node(&mas);
321 MT_BUG_ON(mt, mas_allocated(&mas) != i);
322 MT_BUG_ON(mt, !mn);
323 MT_BUG_ON(mt, not_empty(mn));
324 ma_free_rcu(mn);
325 }
326
327 total = 64;
328 mas_set_alloc_req(&mas, total); /* request 2 more. */
329 MT_BUG_ON(mt, mas_alloc_req(&mas) != total);
330 mas_set_err(&mas, -ENOMEM);
331 MT_BUG_ON(mt, !mas_nomem(&mas, GFP_KERNEL));
332 for (i = total; i > 0; i--) {
333 unsigned int e = 0; /* expected node_count */
334
335 if (i >= 35)
336 e = i - 35;
337 else if (i >= 5)
338 e = i - 5;
339 else if (i >= 2)
340 e = i - 2;
341 MT_BUG_ON(mt, mas.alloc->node_count != e);
342 mn = mas_pop_node(&mas);
343 MT_BUG_ON(mt, not_empty(mn));
344 MT_BUG_ON(mt, mas_allocated(&mas) != i - 1);
345 MT_BUG_ON(mt, !mn);
346 ma_free_rcu(mn);
347 }
348
349 total = 100;
350 for (i = 1; i < total; i++) {
351 mas_set_alloc_req(&mas, i);
352 mas_set_err(&mas, -ENOMEM);
353 MT_BUG_ON(mt, !mas_nomem(&mas, GFP_KERNEL));
354 for (j = i; j > 0; j--) {
355 mn = mas_pop_node(&mas);
356 MT_BUG_ON(mt, mas_allocated(&mas) != j - 1);
357 MT_BUG_ON(mt, !mn);
358 MT_BUG_ON(mt, not_empty(mn));
359 mas_push_node(&mas, mn);
360 MT_BUG_ON(mt, mas_allocated(&mas) != j);
361 mn = mas_pop_node(&mas);
362 MT_BUG_ON(mt, not_empty(mn));
363 MT_BUG_ON(mt, mas_allocated(&mas) != j - 1);
364 ma_free_rcu(mn);
365 }
366 MT_BUG_ON(mt, mas_allocated(&mas) != 0);
367
368 mas_set_alloc_req(&mas, i);
369 mas_set_err(&mas, -ENOMEM);
370 MT_BUG_ON(mt, !mas_nomem(&mas, GFP_KERNEL));
371 for (j = 0; j <= i/2; j++) {
372 MT_BUG_ON(mt, mas_allocated(&mas) != i - j);
373 nodes[j] = mas_pop_node(&mas);
374 MT_BUG_ON(mt, mas_allocated(&mas) != i - j - 1);
375 }
376
377 while (j) {
378 j--;
379 mas_push_node(&mas, nodes[j]);
380 MT_BUG_ON(mt, mas_allocated(&mas) != i - j);
381 }
382 MT_BUG_ON(mt, mas_allocated(&mas) != i);
383 for (j = 0; j <= i/2; j++) {
384 MT_BUG_ON(mt, mas_allocated(&mas) != i - j);
385 mn = mas_pop_node(&mas);
386 MT_BUG_ON(mt, not_empty(mn));
387 ma_free_rcu(mn);
388 MT_BUG_ON(mt, mas_allocated(&mas) != i - j - 1);
389 }
390 MT_BUG_ON(mt, mas_nomem(&mas, GFP_KERNEL));
391
392 }
393
394 /* Set allocation request. */
395 total = 500;
396 mas_node_count(&mas, total);
397 /* Drop the lock and allocate the nodes. */
398 mas_nomem(&mas, GFP_KERNEL);
399 MT_BUG_ON(mt, !mas.alloc);
400 i = 1;
401 smn = mas.alloc;
402 while (i < total) {
403 for (j = 0; j < MAPLE_ALLOC_SLOTS; j++) {
404 i++;
405 MT_BUG_ON(mt, !smn->slot[j]);
406 if (i == total)
407 break;
408 }
409 smn = smn->slot[0]; /* next. */
410 }
411 MT_BUG_ON(mt, mas_allocated(&mas) != total);
412 mas_nomem(&mas, GFP_KERNEL); /* Free. */
413
414 MT_BUG_ON(mt, mas_allocated(&mas) != 0);
415 for (i = 1; i < 128; i++) {
416 mas_node_count(&mas, i); /* Request */
417 mas_nomem(&mas, GFP_KERNEL); /* Fill request */
418 MT_BUG_ON(mt, mas_allocated(&mas) != i); /* check request filled */
419 for (j = i; j > 0; j--) { /*Free the requests */
420 mn = mas_pop_node(&mas); /* get the next node. */
421 MT_BUG_ON(mt, mn == NULL);
422 MT_BUG_ON(mt, not_empty(mn));
423 ma_free_rcu(mn);
424 }
425 MT_BUG_ON(mt, mas_allocated(&mas) != 0);
426 }
427
428 for (i = 1; i < MAPLE_NODE_MASK + 1; i++) {
429 MA_STATE(mas2, mt, 0, 0);
430 mas_node_count(&mas, i); /* Request */
431 mas_nomem(&mas, GFP_KERNEL); /* Fill request */
432 MT_BUG_ON(mt, mas_allocated(&mas) != i); /* check request filled */
433 for (j = 1; j <= i; j++) { /* Move the allocations to mas2 */
434 mn = mas_pop_node(&mas); /* get the next node. */
435 MT_BUG_ON(mt, mn == NULL);
436 MT_BUG_ON(mt, not_empty(mn));
437 mas_push_node(&mas2, mn);
438 MT_BUG_ON(mt, mas_allocated(&mas2) != j);
439 }
440 MT_BUG_ON(mt, mas_allocated(&mas) != 0);
441 MT_BUG_ON(mt, mas_allocated(&mas2) != i);
442
443 for (j = i; j > 0; j--) { /*Free the requests */
444 MT_BUG_ON(mt, mas_allocated(&mas2) != j);
445 mn = mas_pop_node(&mas2); /* get the next node. */
446 MT_BUG_ON(mt, mn == NULL);
447 MT_BUG_ON(mt, not_empty(mn));
448 ma_free_rcu(mn);
449 }
450 MT_BUG_ON(mt, mas_allocated(&mas2) != 0);
451 }
452
453
454 MT_BUG_ON(mt, mas_allocated(&mas) != 0);
455 mas_node_count(&mas, MAPLE_ALLOC_SLOTS + 1); /* Request */
456 MT_BUG_ON(mt, mas.node != MA_ERROR(-ENOMEM));
457 MT_BUG_ON(mt, !mas_nomem(&mas, GFP_KERNEL));
458 MT_BUG_ON(mt, mas_allocated(&mas) != MAPLE_ALLOC_SLOTS + 1);
459 MT_BUG_ON(mt, mas.alloc->node_count != MAPLE_ALLOC_SLOTS - 1);
460
461 mn = mas_pop_node(&mas); /* get the next node. */
462 MT_BUG_ON(mt, mn == NULL);
463 MT_BUG_ON(mt, not_empty(mn));
464 MT_BUG_ON(mt, mas_allocated(&mas) != MAPLE_ALLOC_SLOTS);
465 MT_BUG_ON(mt, mas.alloc->node_count != MAPLE_ALLOC_SLOTS - 2);
466
467 mas_push_node(&mas, mn);
468 MT_BUG_ON(mt, mas_allocated(&mas) != MAPLE_ALLOC_SLOTS + 1);
469 MT_BUG_ON(mt, mas.alloc->node_count != MAPLE_ALLOC_SLOTS - 1);
470
471 /* Check the limit of pop/push/pop */
472 mas_node_count(&mas, MAPLE_ALLOC_SLOTS + 2); /* Request */
473 MT_BUG_ON(mt, mas_alloc_req(&mas) != 1);
474 MT_BUG_ON(mt, mas.node != MA_ERROR(-ENOMEM));
475 MT_BUG_ON(mt, !mas_nomem(&mas, GFP_KERNEL));
476 MT_BUG_ON(mt, mas_alloc_req(&mas));
477 MT_BUG_ON(mt, mas.alloc->node_count);
478 MT_BUG_ON(mt, mas_allocated(&mas) != MAPLE_ALLOC_SLOTS + 2);
479 mn = mas_pop_node(&mas);
480 MT_BUG_ON(mt, not_empty(mn));
481 MT_BUG_ON(mt, mas_allocated(&mas) != MAPLE_ALLOC_SLOTS + 1);
482 MT_BUG_ON(mt, mas.alloc->node_count != MAPLE_ALLOC_SLOTS - 1);
483 mas_push_node(&mas, mn);
484 MT_BUG_ON(mt, mas.alloc->node_count);
485 MT_BUG_ON(mt, mas_allocated(&mas) != MAPLE_ALLOC_SLOTS + 2);
486 mn = mas_pop_node(&mas);
487 MT_BUG_ON(mt, not_empty(mn));
488 ma_free_rcu(mn);
489 for (i = 1; i <= MAPLE_ALLOC_SLOTS + 1; i++) {
490 mn = mas_pop_node(&mas);
491 MT_BUG_ON(mt, not_empty(mn));
492 ma_free_rcu(mn);
493 }
494 MT_BUG_ON(mt, mas_allocated(&mas) != 0);
495
496
497 for (i = 3; i < MAPLE_NODE_MASK * 3; i++) {
498 mas.node = MA_ERROR(-ENOMEM);
499 mas_node_count(&mas, i); /* Request */
500 mas_nomem(&mas, GFP_KERNEL); /* Fill request */
501 mn = mas_pop_node(&mas); /* get the next node. */
502 mas_push_node(&mas, mn); /* put it back */
503 mas_destroy(&mas);
504
505 mas.node = MA_ERROR(-ENOMEM);
506 mas_node_count(&mas, i); /* Request */
507 mas_nomem(&mas, GFP_KERNEL); /* Fill request */
508 mn = mas_pop_node(&mas); /* get the next node. */
509 mn2 = mas_pop_node(&mas); /* get the next node. */
510 mas_push_node(&mas, mn); /* put them back */
511 mas_push_node(&mas, mn2);
512 mas_destroy(&mas);
513
514 mas.node = MA_ERROR(-ENOMEM);
515 mas_node_count(&mas, i); /* Request */
516 mas_nomem(&mas, GFP_KERNEL); /* Fill request */
517 mn = mas_pop_node(&mas); /* get the next node. */
518 mn2 = mas_pop_node(&mas); /* get the next node. */
519 mn3 = mas_pop_node(&mas); /* get the next node. */
520 mas_push_node(&mas, mn); /* put them back */
521 mas_push_node(&mas, mn2);
522 mas_push_node(&mas, mn3);
523 mas_destroy(&mas);
524
525 mas.node = MA_ERROR(-ENOMEM);
526 mas_node_count(&mas, i); /* Request */
527 mas_nomem(&mas, GFP_KERNEL); /* Fill request */
528 mn = mas_pop_node(&mas); /* get the next node. */
529 ma_free_rcu(mn);
530 mas_destroy(&mas);
531
532 mas.node = MA_ERROR(-ENOMEM);
533 mas_node_count(&mas, i); /* Request */
534 mas_nomem(&mas, GFP_KERNEL); /* Fill request */
535 mn = mas_pop_node(&mas); /* get the next node. */
536 ma_free_rcu(mn);
537 mn = mas_pop_node(&mas); /* get the next node. */
538 ma_free_rcu(mn);
539 mn = mas_pop_node(&mas); /* get the next node. */
540 ma_free_rcu(mn);
541 mas_destroy(&mas);
542 }
543
544 mas.node = MA_ERROR(-ENOMEM);
545 mas_node_count(&mas, 5); /* Request */
546 mas_nomem(&mas, GFP_KERNEL); /* Fill request */
547 MT_BUG_ON(mt, mas_allocated(&mas) != 5);
548 mas.node = MA_ERROR(-ENOMEM);
549 mas_node_count(&mas, 10); /* Request */
550 mas_nomem(&mas, GFP_KERNEL); /* Fill request */
551 mas.node = MAS_START;
552 MT_BUG_ON(mt, mas_allocated(&mas) != 10);
553 mas_destroy(&mas);
554
555 mas.node = MA_ERROR(-ENOMEM);
556 mas_node_count(&mas, MAPLE_ALLOC_SLOTS - 1); /* Request */
557 mas_nomem(&mas, GFP_KERNEL); /* Fill request */
558 MT_BUG_ON(mt, mas_allocated(&mas) != MAPLE_ALLOC_SLOTS - 1);
559 mas.node = MA_ERROR(-ENOMEM);
560 mas_node_count(&mas, 10 + MAPLE_ALLOC_SLOTS - 1); /* Request */
561 mas_nomem(&mas, GFP_KERNEL); /* Fill request */
562 mas.node = MAS_START;
563 MT_BUG_ON(mt, mas_allocated(&mas) != 10 + MAPLE_ALLOC_SLOTS - 1);
564 mas_destroy(&mas);
565
566 mtree_unlock(mt);
567}
568
569static noinline void check_rev_seq(struct maple_tree *mt, unsigned long max,
570 bool verbose)
571{
572 unsigned long i = max, j;
573
574 MT_BUG_ON(mt, !mtree_empty(mt));
575
576 mt_zero_nr_tallocated();
577 while (i) {
578 MT_BUG_ON(mt, mtree_insert_index(mt, i, GFP_KERNEL));
579 for (j = i; j <= max; j++)
580 check_index_load(mt, j);
581
582 check_load(mt, i - 1, NULL);
583 mt_set_in_rcu(mt);
584 MT_BUG_ON(mt, !mt_height(mt));
585 mt_clear_in_rcu(mt);
586 MT_BUG_ON(mt, !mt_height(mt));
587 i--;
588 }
589 check_load(mt, max + 1, NULL);
590
591 if (verbose) {
592 rcu_barrier();
593 mt_dump(mt);
594 pr_info(" %s test of 0-%lu %luK in %d active (%d total)\n",
595 __func__, max, mt_get_alloc_size()/1024, mt_nr_allocated(),
596 mt_nr_tallocated());
597 }
598}
599
600static noinline void check_seq(struct maple_tree *mt, unsigned long max,
601 bool verbose)
602{
603 unsigned long i, j;
604
605 MT_BUG_ON(mt, !mtree_empty(mt));
606
607 mt_zero_nr_tallocated();
608 for (i = 0; i <= max; i++) {
609 MT_BUG_ON(mt, mtree_insert_index(mt, i, GFP_KERNEL));
610 for (j = 0; j <= i; j++)
611 check_index_load(mt, j);
612
613 if (i)
614 MT_BUG_ON(mt, !mt_height(mt));
615 check_load(mt, i + 1, NULL);
616 }
617 if (verbose) {
618 rcu_barrier();
619 mt_dump(mt);
620 pr_info(" seq test of 0-%lu %luK in %d active (%d total)\n",
621 max, mt_get_alloc_size()/1024, mt_nr_allocated(),
622 mt_nr_tallocated());
623 }
624}
625
626static noinline void check_lb_not_empty(struct maple_tree *mt)
627{
628 unsigned long i, j;
629 unsigned long huge = 4000UL * 1000 * 1000;
630
631
632 i = huge;
633 while (i > 4096) {
634 check_insert(mt, i, (void *) i);
635 for (j = huge; j >= i; j /= 2) {
636 check_load(mt, j-1, NULL);
637 check_load(mt, j, (void *) j);
638 check_load(mt, j+1, NULL);
639 }
640 i /= 2;
641 }
642 mtree_destroy(mt);
643}
644
645static noinline void check_lower_bound_split(struct maple_tree *mt)
646{
647 MT_BUG_ON(mt, !mtree_empty(mt));
648 check_lb_not_empty(mt);
649}
650
651static noinline void check_upper_bound_split(struct maple_tree *mt)
652{
653 unsigned long i, j;
654 unsigned long huge = 4000UL * 1000 * 1000;
655
656 MT_BUG_ON(mt, !mtree_empty(mt));
657
658 i = 4096;
659 while (i < huge) {
660 check_insert(mt, i, (void *) i);
661 for (j = i; j >= huge; j *= 2) {
662 check_load(mt, j-1, NULL);
663 check_load(mt, j, (void *) j);
664 check_load(mt, j+1, NULL);
665 }
666 i *= 2;
667 }
668 mtree_destroy(mt);
669}
670
671static noinline void check_mid_split(struct maple_tree *mt)
672{
673 unsigned long huge = 8000UL * 1000 * 1000;
674
675 check_insert(mt, huge, (void *) huge);
676 check_insert(mt, 0, xa_mk_value(0));
677 check_lb_not_empty(mt);
678}
679
680static noinline void check_rev_find(struct maple_tree *mt)
681{
682 int i, nr_entries = 200;
683 void *val;
684 MA_STATE(mas, mt, 0, 0);
685
686 for (i = 0; i <= nr_entries; i++)
687 mtree_store_range(mt, i*10, i*10 + 5,
688 xa_mk_value(i), GFP_KERNEL);
689
690 mas_set(&mas, 1000);
691 val = mas_find_rev(&mas, 1000);
692 MT_BUG_ON(mt, val != xa_mk_value(100));
693 val = mas_find_rev(&mas, 1000);
694 MT_BUG_ON(mt, val != NULL);
695
696 mas_set(&mas, 999);
697 val = mas_find_rev(&mas, 997);
698 MT_BUG_ON(mt, val != NULL);
699
700 mas_set(&mas, 1000);
701 val = mas_find_rev(&mas, 900);
702 MT_BUG_ON(mt, val != xa_mk_value(100));
703 val = mas_find_rev(&mas, 900);
704 MT_BUG_ON(mt, val != xa_mk_value(99));
705
706 mas_set(&mas, 20);
707 val = mas_find_rev(&mas, 0);
708 MT_BUG_ON(mt, val != xa_mk_value(2));
709 val = mas_find_rev(&mas, 0);
710 MT_BUG_ON(mt, val != xa_mk_value(1));
711 val = mas_find_rev(&mas, 0);
712 MT_BUG_ON(mt, val != xa_mk_value(0));
713 val = mas_find_rev(&mas, 0);
714 MT_BUG_ON(mt, val != NULL);
715}
716
717static noinline void check_find(struct maple_tree *mt)
718{
719 unsigned long val = 0;
720 unsigned long count = 20;
721 unsigned long max;
722 unsigned long last = 0, index = 0;
723 void *entry, *entry2;
724
725 MA_STATE(mas, mt, 0, 0);
726
727 /* Insert 0. */
728 MT_BUG_ON(mt, mtree_insert_index(mt, val++, GFP_KERNEL));
729
730 for (int i = 0; i <= count; i++) {
731 if (val != 64)
732 MT_BUG_ON(mt, mtree_insert_index(mt, val, GFP_KERNEL));
733 else
734 MT_BUG_ON(mt, mtree_insert(mt, val,
735 XA_ZERO_ENTRY, GFP_KERNEL));
736
737 val <<= 2;
738 }
739
740 val = 0;
741 mas_set(&mas, val);
742 mas_lock(&mas);
743 while ((entry = mas_find(&mas, 268435456)) != NULL) {
744 if (val != 64)
745 MT_BUG_ON(mt, xa_mk_value(val) != entry);
746 else
747 MT_BUG_ON(mt, entry != XA_ZERO_ENTRY);
748
749 val <<= 2;
750 /* For zero check. */
751 if (!val)
752 val = 1;
753 }
754 mas_unlock(&mas);
755
756 val = 0;
757 mas_set(&mas, val);
758 mas_lock(&mas);
759 mas_for_each(&mas, entry, ULONG_MAX) {
760 if (val != 64)
761 MT_BUG_ON(mt, xa_mk_value(val) != entry);
762 else
763 MT_BUG_ON(mt, entry != XA_ZERO_ENTRY);
764 val <<= 2;
765 /* For zero check. */
766 if (!val)
767 val = 1;
768 }
769 mas_unlock(&mas);
770
771 /* Test mas_pause */
772 val = 0;
773 mas_set(&mas, val);
774 mas_lock(&mas);
775 mas_for_each(&mas, entry, ULONG_MAX) {
776 if (val != 64)
777 MT_BUG_ON(mt, xa_mk_value(val) != entry);
778 else
779 MT_BUG_ON(mt, entry != XA_ZERO_ENTRY);
780 val <<= 2;
781 /* For zero check. */
782 if (!val)
783 val = 1;
784
785 mas_pause(&mas);
786 mas_unlock(&mas);
787 mas_lock(&mas);
788 }
789 mas_unlock(&mas);
790
791 val = 0;
792 max = 300; /* A value big enough to include XA_ZERO_ENTRY at 64. */
793 mt_for_each(mt, entry, index, max) {
794 MT_BUG_ON(mt, xa_mk_value(val) != entry);
795 val <<= 2;
796 if (val == 64) /* Skip zero entry. */
797 val <<= 2;
798 /* For zero check. */
799 if (!val)
800 val = 1;
801 }
802
803 val = 0;
804 max = 0;
805 index = 0;
806 MT_BUG_ON(mt, mtree_insert_index(mt, ULONG_MAX, GFP_KERNEL));
807 mt_for_each(mt, entry, index, ULONG_MAX) {
808 if (val == 4398046511104)
809 MT_BUG_ON(mt, entry !=
810 xa_mk_value(ULONG_MAX & LONG_MAX));
811 else
812 MT_BUG_ON(mt, xa_mk_value(val) != entry);
813 val <<= 2;
814 if (val == 64) /* Skip zero entry. */
815 val <<= 2;
816 /* For zero check. */
817 if (!val)
818 val = 1;
819 max++;
820 MT_BUG_ON(mt, max > 25);
821 }
822 mtree_erase_index(mt, ULONG_MAX);
823
824 mas_reset(&mas);
825 index = 17;
826 entry = mt_find(mt, &index, 512);
827 MT_BUG_ON(mt, xa_mk_value(256) != entry);
828
829 mas_reset(&mas);
830 index = 17;
831 entry = mt_find(mt, &index, 20);
832 MT_BUG_ON(mt, entry != NULL);
833
834
835 /* Range check.. */
836 /* Insert ULONG_MAX */
837 MT_BUG_ON(mt, mtree_insert_index(mt, ULONG_MAX, GFP_KERNEL));
838
839 val = 0;
840 mas_set(&mas, 0);
841 mas_lock(&mas);
842 mas_for_each(&mas, entry, ULONG_MAX) {
843 if (val == 64)
844 MT_BUG_ON(mt, entry != XA_ZERO_ENTRY);
845 else if (val == 4398046511104)
846 MT_BUG_ON(mt, entry != xa_mk_value(ULONG_MAX & LONG_MAX));
847 else
848 MT_BUG_ON(mt, xa_mk_value(val) != entry);
849 val <<= 2;
850
851 /* For zero check. */
852 if (!val)
853 val = 1;
854 mas_pause(&mas);
855 mas_unlock(&mas);
856 mas_lock(&mas);
857 }
858 mas_unlock(&mas);
859
860 mas_set(&mas, 1048576);
861 mas_lock(&mas);
862 entry = mas_find(&mas, 1048576);
863 mas_unlock(&mas);
864 MT_BUG_ON(mas.tree, entry == NULL);
865
866 /*
867 * Find last value.
868 * 1. get the expected value, leveraging the existence of an end entry
869 * 2. delete end entry
870 * 3. find the last value but searching for ULONG_MAX and then using
871 * prev
872 */
873 /* First, get the expected result. */
874 mas_lock(&mas);
875 mas_reset(&mas);
876 mas.index = ULONG_MAX; /* start at max.. */
877 entry = mas_find(&mas, ULONG_MAX);
878 entry = mas_prev(&mas, 0);
879 index = mas.index;
880 last = mas.last;
881
882 /* Erase the last entry. */
883 mas_reset(&mas);
884 mas.index = ULONG_MAX;
885 mas.last = ULONG_MAX;
886 mas_erase(&mas);
887
888 /* Get the previous value from MAS_START */
889 mas_reset(&mas);
890 entry2 = mas_prev(&mas, 0);
891
892 /* Check results. */
893 MT_BUG_ON(mt, entry != entry2);
894 MT_BUG_ON(mt, index != mas.index);
895 MT_BUG_ON(mt, last != mas.last);
896
897
898 mas.node = MAS_NONE;
899 mas.index = ULONG_MAX;
900 mas.last = ULONG_MAX;
901 entry2 = mas_prev(&mas, 0);
902 MT_BUG_ON(mt, entry != entry2);
903
904 mas_set(&mas, 0);
905 MT_BUG_ON(mt, mas_prev(&mas, 0) != NULL);
906
907 mas_unlock(&mas);
908 mtree_destroy(mt);
909}
910
911static noinline void check_find_2(struct maple_tree *mt)
912{
913 unsigned long i, j;
914 void *entry;
915
916 MA_STATE(mas, mt, 0, 0);
917 rcu_read_lock();
918 mas_for_each(&mas, entry, ULONG_MAX)
919 MT_BUG_ON(mt, true);
920 rcu_read_unlock();
921
922 for (i = 0; i < 256; i++) {
923 mtree_insert_index(mt, i, GFP_KERNEL);
924 j = 0;
925 mas_set(&mas, 0);
926 rcu_read_lock();
927 mas_for_each(&mas, entry, ULONG_MAX) {
928 MT_BUG_ON(mt, entry != xa_mk_value(j));
929 j++;
930 }
931 rcu_read_unlock();
932 MT_BUG_ON(mt, j != i + 1);
933 }
934
935 for (i = 0; i < 256; i++) {
936 mtree_erase_index(mt, i);
937 j = i + 1;
938 mas_set(&mas, 0);
939 rcu_read_lock();
940 mas_for_each(&mas, entry, ULONG_MAX) {
941 if (xa_is_zero(entry))
942 continue;
943
944 MT_BUG_ON(mt, entry != xa_mk_value(j));
945 j++;
946 }
947 rcu_read_unlock();
948 MT_BUG_ON(mt, j != 256);
949 }
950
951 /*MT_BUG_ON(mt, !mtree_empty(mt)); */
952}
953
954#define erase_ptr(i) entry[i%2]
955#define erase_check_load(mt, i) check_load(mt, set[i], entry[i%2])
956#define erase_check_insert(mt, i) check_insert(mt, set[i], entry[i%2])
957#define erase_check_erase(mt, i) check_erase(mt, set[i], entry[i%2])
958
959static noinline void check_erase_testset(struct maple_tree *mt)
960{
961 unsigned long set[] = { 5015, 5014, 5017, 25, 1000,
962 1001, 1002, 1003, 1005, 0,
963 6003, 6002, 6008, 6012, 6015,
964 7003, 7002, 7008, 7012, 7015,
965 8003, 8002, 8008, 8012, 8015,
966 9003, 9002, 9008, 9012, 9015,
967 10003, 10002, 10008, 10012, 10015,
968 11003, 11002, 11008, 11012, 11015,
969 12003, 12002, 12008, 12012, 12015,
970 13003, 13002, 13008, 13012, 13015,
971 14003, 14002, 14008, 14012, 14015,
972 15003, 15002, 15008, 15012, 15015,
973 };
974
975
976 void *ptr = &set;
977 void *entry[2] = { ptr, mt };
978 void *root_node;
979
980
981 rcu_register_thread();
982 mt_set_in_rcu(mt);
983 for (int i = 0; i < 4; i++)
984 erase_check_insert(mt, i);
985 for (int i = 0; i < 4; i++)
986 erase_check_load(mt, i);
987
988 mt_set_non_kernel(2);
989 erase_check_erase(mt, 1);
990 erase_check_load(mt, 0);
991 check_load(mt, set[1], NULL);
992 for (int i = 2; i < 4; i++)
993 erase_check_load(mt, i);
994
995
996 erase_check_erase(mt, 2);
997 erase_check_load(mt, 0);
998 check_load(mt, set[1], NULL);
999 check_load(mt, set[2], NULL);
1000
1001 erase_check_insert(mt, 1);
1002 erase_check_insert(mt, 2);
1003
1004 for (int i = 0; i < 4; i++)
1005 erase_check_load(mt, i);
1006
1007 /* Check erase and load without an allocation. */
1008 erase_check_load(mt, 3);
1009 erase_check_erase(mt, 1);
1010 erase_check_load(mt, 0);
1011 check_load(mt, set[1], NULL);
1012 for (int i = 2; i < 4; i++)
1013 erase_check_load(mt, i);
1014
1015 /*
1016 * Set the newly erased node. This will produce a different allocated
1017 * node to avoid busy slots.
1018 */
1019 root_node = mt->ma_root;
1020 erase_check_insert(mt, 1);
1021
1022 erase_check_load(mt, 0);
1023 check_load(mt, 5016, NULL);
1024 erase_check_load(mt, 1);
1025 check_load(mt, 5013, NULL);
1026 erase_check_load(mt, 2);
1027 check_load(mt, 5018, NULL);
1028 erase_check_load(mt, 3);
1029
1030 erase_check_erase(mt, 2); /* erase 5017 to check append */
1031 erase_check_load(mt, 0);
1032 check_load(mt, 5016, NULL);
1033 erase_check_load(mt, 1);
1034 check_load(mt, 5013, NULL);
1035 check_load(mt, set[2], NULL);
1036 check_load(mt, 5018, NULL);
1037
1038 erase_check_load(mt, 3);
1039
1040 root_node = mt->ma_root;
1041 erase_check_insert(mt, 2);
1042
1043 erase_check_load(mt, 0);
1044 check_load(mt, 5016, NULL);
1045 erase_check_load(mt, 1);
1046 check_load(mt, 5013, NULL);
1047 erase_check_load(mt, 2);
1048 check_load(mt, 5018, NULL);
1049 erase_check_load(mt, 3);
1050
1051 mt_set_non_kernel(1);
1052 erase_check_erase(mt, 2); /* erase 5017 to check append */
1053 erase_check_load(mt, 0);
1054 check_load(mt, 5016, NULL);
1055 check_load(mt, set[2], NULL);
1056 erase_check_erase(mt, 0); /* erase 5015 to check append */
1057 check_load(mt, set[0], NULL);
1058 check_load(mt, 5016, NULL);
1059 erase_check_insert(mt, 4); /* 1000 < Should not split. */
1060 check_load(mt, set[0], NULL);
1061 check_load(mt, 5016, NULL);
1062 erase_check_load(mt, 1);
1063 check_load(mt, 5013, NULL);
1064 check_load(mt, set[2], NULL);
1065 check_load(mt, 5018, NULL);
1066 erase_check_load(mt, 4);
1067 check_load(mt, 999, NULL);
1068 check_load(mt, 1001, NULL);
1069 erase_check_load(mt, 4);
1070 if (mt_in_rcu(mt))
1071 MT_BUG_ON(mt, root_node == mt->ma_root);
1072 else
1073 MT_BUG_ON(mt, root_node != mt->ma_root);
1074
1075 /* Should not have split. */
1076 MT_BUG_ON(mt, !mte_is_leaf(mt->ma_root));
1077
1078
1079 /* Coalesce testing */
1080 erase_check_insert(mt, 0);
1081 erase_check_insert(mt, 2);
1082
1083 for (int i = 5; i < 25; i++) {
1084 erase_check_insert(mt, i);
1085 for (int j = i; j >= 0; j--)
1086 erase_check_load(mt, j);
1087 }
1088
1089 erase_check_erase(mt, 14); /*6015 */
1090 for (int i = 0; i < 25; i++) {
1091 if (i == 14)
1092 check_load(mt, set[i], NULL);
1093 else
1094 erase_check_load(mt, i);
1095 }
1096 erase_check_erase(mt, 16); /*7002 */
1097 for (int i = 0; i < 25; i++) {
1098 if (i == 16 || i == 14)
1099 check_load(mt, set[i], NULL);
1100 else
1101 erase_check_load(mt, i);
1102 }
1103
1104
1105 mt_set_non_kernel(1);
1106 erase_check_erase(mt, 13); /*6012 */
1107 for (int i = 0; i < 25; i++) {
1108 if (i == 16 || i == 14 || i == 13)
1109 check_load(mt, set[i], NULL);
1110 else
1111 erase_check_load(mt, i);
1112 }
1113
1114 erase_check_erase(mt, 15); /*7003 */
1115 for (int i = 0; i < 25; i++) {
1116 if (i <= 16 && i >= 13)
1117 check_load(mt, set[i], NULL);
1118 else
1119 erase_check_load(mt, i);
1120 }
1121
1122 mt_set_non_kernel(2);
1123 erase_check_erase(mt, 17); /*7008 *should* cause coalesce. */
1124 for (int i = 0; i < 25; i++) {
1125 if (i <= 17 && i >= 13)
1126 check_load(mt, set[i], NULL);
1127 else
1128 erase_check_load(mt, i);
1129 }
1130
1131 erase_check_erase(mt, 18); /*7012 */
1132 for (int i = 0; i < 25; i++) {
1133 if (i <= 18 && i >= 13)
1134 check_load(mt, set[i], NULL);
1135 else
1136 erase_check_load(mt, i);
1137 }
1138
1139 mt_set_non_kernel(2);
1140 erase_check_erase(mt, 19); /*7015 */
1141 for (int i = 0; i < 25; i++) {
1142 if (i <= 19 && i >= 13)
1143 check_load(mt, set[i], NULL);
1144 else
1145 erase_check_load(mt, i);
1146 }
1147
1148 erase_check_erase(mt, 20); /*8003 */
1149 for (int i = 0; i < 25; i++) {
1150 if (i <= 20 && i >= 13)
1151 check_load(mt, set[i], NULL);
1152 else
1153 erase_check_load(mt, i);
1154 }
1155
1156 erase_check_erase(mt, 21); /*8002 */
1157 for (int i = 0; i < 25; i++) {
1158 if (i <= 21 && i >= 13)
1159 check_load(mt, set[i], NULL);
1160 else
1161 erase_check_load(mt, i);
1162 }
1163
1164 mt_set_non_kernel(2);
1165 erase_check_erase(mt, 22); /*8008 */
1166 for (int i = 0; i < 25; i++) {
1167 if (i <= 22 && i >= 13)
1168 check_load(mt, set[i], NULL);
1169 else
1170 erase_check_load(mt, i);
1171 }
1172 for (int i = 23; i < 25; i++)
1173 erase_check_erase(mt, i);
1174
1175 for (int i = 0; i < 25; i++) {
1176 if (i <= 25 && i >= 13)
1177 check_load(mt, set[i], NULL);
1178 else
1179 erase_check_load(mt, i);
1180 }
1181
1182 /* Shrinking tree test. */
1183
1184 for (int i = 13; i < ARRAY_SIZE(set); i++)
1185 erase_check_insert(mt, i);
1186
1187 mt_set_non_kernel(99);
1188 for (int i = 18; i < ARRAY_SIZE(set); i++) {
1189 erase_check_erase(mt, i);
1190 for (int j = 0; j < ARRAY_SIZE(set); j++) {
1191 if (j < 18 || j > i)
1192 erase_check_load(mt, j);
1193 else
1194 check_load(mt, set[j], NULL);
1195 }
1196 }
1197 mt_set_non_kernel(35);
1198 for (int i = 0; i < 18; i++) {
1199 erase_check_erase(mt, i);
1200 for (int j = 0; j < ARRAY_SIZE(set); j++) {
1201 if (j < 18 && j > i)
1202 erase_check_load(mt, j);
1203 else
1204 check_load(mt, set[j], NULL);
1205 }
1206 }
1207 erase_check_insert(mt, 8);
1208 erase_check_insert(mt, 9);
1209 erase_check_erase(mt, 8);
1210 rcu_unregister_thread();
1211}
1212
1213#define erase_check_store_range(mt, a, i, ptr) mtree_test_store_range(mt, \
1214 a[(i)], a[(i + 1)], ptr)
1215#define STORE 1
1216#define SNULL 2
1217#define ERASE 3
1218#define ec_type_str(x) \
1219 (((x) == STORE) ? \
1220 "STORE" : \
1221 (((x) == SNULL) ? \
1222 "SNULL" : "ERASE") \
1223 )
1224#define check_erase2_debug 0
1225void *mas_next(struct ma_state *mas, unsigned long max);
1226
1227/* Calculate the overwritten entries. */
1228int mas_ce2_over_count(struct ma_state *mas_start, struct ma_state *mas_end,
1229 void *s_entry, unsigned long s_min,
1230 void *e_entry, unsigned long e_max,
1231 unsigned long *set, int i, bool null_entry)
1232{
1233 int count = 0, span = 0;
1234 unsigned long retry = 0;
1235 void *entry;
1236 struct ma_state tmp;
1237
1238
1239 /* count slots */
1240 memcpy(&tmp, mas_start, sizeof(tmp));
1241 entry = mas_next(&tmp, mas_end->last);
1242 while (entry) {
1243 BUG_ON(retry > 50); /* stop infinite retry on testing. */
1244 if (xa_is_zero(s_entry)) {
1245 retry++;
1246 continue;
1247 }
1248 count++;
1249 span++;
1250 entry = mas_next(&tmp, mas_end->last);
1251 }
1252
1253 if (null_entry) {
1254 /* Check splitting end. */
1255 if (e_entry && (e_max > mas_end->last))
1256 count--;
1257
1258 /* check overwrite of entire start */
1259 if (s_entry && (s_min == mas_start->index))
1260 count++;
1261 } else { /* !null_entry (store) */
1262 bool esplit = e_max > mas_end->last;
1263 bool ssplit = s_min != mas_start->index;
1264
1265 if (s_entry && e_entry) {
1266 if (esplit && ssplit)
1267 count--;
1268 else if (ssplit)
1269 count--;
1270 else if (esplit) {
1271 if (span)
1272 count--;
1273 }
1274 } else if (s_entry && !e_entry) {
1275 if (ssplit)
1276 count--;
1277 } else if (!s_entry && e_entry) {
1278 if (esplit)
1279 count--;
1280 count--;
1281 } else {
1282 count--;
1283 }
1284 }
1285 return count;
1286}
1287
1288/*
1289 * mas_node_walk() - Walk a maple node to offset of the index.
1290 * @mas: The maple state
1291 * @type: The maple node type
1292 * @*range_min: Pointer to store the minimum range of the offset
1293 * @*range_max: Pointer to store the maximum range of the offset
1294 *
1295 * The offset will be stored in the maple state.
1296 *
1297 */
1298static inline void mas_node_walk(struct ma_state *mas, struct maple_node *node,
1299 enum maple_type type, unsigned long *range_min,
1300 unsigned long *range_max)
1301
1302{
1303 unsigned long *pivots;
1304 unsigned char count;
1305 unsigned long prev, max;
1306 unsigned char offset;
1307 unsigned long index;
1308
1309 if (unlikely(ma_is_dense(type))) {
1310 (*range_max) = (*range_min) = mas->index;
1311 if (unlikely(ma_dead_node(node)))
1312 return;
1313
1314 mas->offset = mas->index = mas->min;
1315 return;
1316 }
1317
1318 pivots = ma_pivots(node, type);
1319 max = pivots[0];
1320 if (unlikely(ma_dead_node(node)))
1321 return;
1322
1323 offset = 0;
1324 prev = mas->min;
1325 index = mas->index;
1326 if (unlikely(index <= max))
1327 goto offset_zero;
1328
1329 count = mt_pivots[type];
1330 while (++offset < count) {
1331 prev = max;
1332 max = pivots[offset];
1333 if (unlikely(ma_dead_node(node)))
1334 return;
1335
1336 if (index <= max)
1337 goto offset_found;
1338 else if (unlikely(!max))
1339 goto mas_max;
1340 }
1341
1342 prev = max;
1343mas_max:
1344 max = mas->max;
1345offset_found:
1346 prev++;
1347offset_zero:
1348 mas->offset = offset;
1349 if (ma_is_leaf(type)) {
1350 *range_max = max;
1351 *range_min = prev;
1352 } else {
1353 mas->max = max;
1354 mas->min = prev;
1355 }
1356}
1357
1358/*
1359 * mas_descend_walk(): Locates a value and sets the mas->node and slot
1360 * accordingly. range_min and range_max are set to the range which the entry is
1361 * valid.
1362 * @mas: The maple state
1363 * @*range_min: A pointer to store the minimum of the range
1364 * @*range_max: A pointer to store the maximum of the range
1365 *
1366 * Check mas->node is still valid on return of any value.
1367 *
1368 * Return: true if pointing to a valid node and offset. False otherwise.
1369 */
1370static inline bool mas_descend_walk(struct ma_state *mas,
1371 unsigned long *range_min, unsigned long *range_max)
1372{
1373 struct maple_enode *next;
1374 struct maple_node *node;
1375 enum maple_type type;
1376
1377 next = mas->node;
1378 while (true) {
1379 node = mte_to_node(next);
1380 type = mte_node_type(next);
1381 mas_node_walk(mas, node, type, range_min, range_max);
1382 next = mas_slot(mas, ma_slots(node, type), mas->offset);
1383 if (unlikely(ma_dead_node(node)))
1384 return false;
1385
1386 if (unlikely(ma_is_leaf(type)))
1387 return true;
1388
1389 /* Descend. */
1390 mas->node = next;
1391 }
1392 return false;
1393}
1394
1395/*
1396 * mas_tree_walk() - Walk to @mas->index and set the range values.
1397 * @mas: The maple state.
1398 * @*range_min: The minimum range to be set.
1399 * @*range_max: The maximum range to be set.
1400 *
1401 * Ranges are only valid if there is a valid entry at @mas->index.
1402 *
1403 * Return: True if a value exists, false otherwise.
1404 */
1405static inline bool mas_tree_walk(struct ma_state *mas, unsigned long *range_min,
1406 unsigned long *range_max)
1407{
1408 bool ret;
1409
1410retry:
1411 ret = false;
1412 mas_start(mas);
1413 if (mas_is_none(mas))
1414 goto not_found;
1415
1416 if (mas_is_ptr(mas)) {
1417 *range_min = *range_max = 0;
1418 if (!mas->index)
1419 return true;
1420
1421 goto not_found;
1422 }
1423
1424 ret = mas_descend_walk(mas, range_min, range_max);
1425 if (unlikely(mte_dead_node(mas->node))) {
1426 mas->node = MAS_START;
1427 goto retry;
1428 }
1429
1430 return ret;
1431
1432not_found:
1433 mas->offset = MAPLE_NODE_SLOTS;
1434 return false;
1435}
1436
1437static inline void *mas_range_load(struct ma_state *mas,
1438 unsigned long *range_min, unsigned long *range_max)
1439
1440{
1441 void *entry = NULL;
1442 unsigned long index = mas->index;
1443
1444 if (mas_is_none(mas) || mas_is_paused(mas))
1445 mas->node = MAS_START;
1446retry:
1447 if (mas_tree_walk(mas, range_min, range_max))
1448 if (unlikely(mas->node == MAS_ROOT))
1449 return mas_root(mas);
1450
1451 if (likely(mas->offset != MAPLE_NODE_SLOTS))
1452 entry = mas_get_slot(mas, mas->offset);
1453
1454 if (mas_dead_node(mas, index))
1455 goto retry;
1456
1457 return entry;
1458}
1459static noinline void check_erase2_testset(struct maple_tree *mt,
1460 unsigned long *set, unsigned long size)
1461{
1462 int entry_count = 0;
1463 int check = 0;
1464 void *foo;
1465 unsigned long addr = 0;
1466 void *s_entry = NULL, *e_entry = NULL;
1467
1468 MA_STATE(mas, mt, 0, 0);
1469
1470 for (int i = 0; i < size; i += 3) {
1471 unsigned long s_min, s_max;
1472 unsigned long e_min, e_max;
1473 void *value = NULL;
1474
1475 MA_STATE(mas_start, mt, set[i+1], set[i+1]);
1476 MA_STATE(mas_end, mt, set[i+2], set[i+2]);
1477 mt_set_non_kernel(127);
1478#if check_erase2_debug
1479 pr_err("%s: %d %s %lu - %lu\n", __func__, i,
1480 ec_type_str(set[i]),
1481 set[i+1], set[i+2]);
1482#endif
1483 s_entry = mas_range_load(&mas_start, &s_min, &s_max);
1484 e_entry = mas_range_load(&mas_end, &e_min, &e_max);
1485
1486 switch (set[i]) {
1487 case SNULL:
1488 if ((s_min == set[i+1]) && (s_max == set[i+2])) {
1489 if (s_entry)
1490 entry_count--;
1491 } else if ((s_min != set[i+1]) && (s_max != set[i+2])) {
1492 entry_count++;
1493 } else if ((mas_start.node != mas_end.node) ||
1494 (mas_start.offset != mas_end.offset)) {
1495 entry_count -=
1496 mas_ce2_over_count(&mas_start, &mas_end,
1497 s_entry, s_min,
1498 e_entry, e_max, set, i,
1499 true);
1500 }
1501
1502
1503 erase_check_store_range(mt, set, i + 1, value);
1504 break;
1505 case STORE:
1506 value = xa_mk_value(set[i + 1]);
1507 if (mas_start.offset > mt_slot_count(mas_start.node)) {
1508 entry_count++; /* appending an entry. */
1509 } else if ((s_min == e_min) && (s_max == e_max)) {
1510 if (!entry_count)
1511 entry_count++;
1512
1513 else if (s_entry) {
1514 if (e_max > mas_end.last)
1515 entry_count++;
1516
1517 if (s_min < mas_start.index)
1518 entry_count++;
1519
1520 } else {
1521 entry_count++;
1522 }
1523 } else {
1524 entry_count -=
1525 mas_ce2_over_count(&mas_start, &mas_end,
1526 s_entry, s_min,
1527 e_entry, e_max, set, i,
1528 false);
1529 }
1530
1531 erase_check_store_range(mt, set, i + 1, value);
1532 break;
1533 case ERASE:
1534 if (!s_entry)
1535 break;
1536 check_erase(mt, set[i+1], xa_mk_value(set[i+1]));
1537 entry_count--;
1538 break;
1539 }
1540 mt_validate(mt);
1541 if (entry_count)
1542 MT_BUG_ON(mt, !mt_height(mt));
1543#if check_erase2_debug > 1
1544 mt_dump(mt);
1545#endif
1546#if check_erase2_debug
1547 pr_err("Done\n");
1548#endif
1549
1550 check = 0;
1551 addr = 0;
1552 mt_for_each(mt, foo, addr, ULONG_MAX) {
1553 check++;
1554#if check_erase2_debug > 2
1555 pr_err("mt: %lu -> %p (%d)\n", addr+1, foo, check);
1556#endif
1557 if (check > entry_count)
1558 break;
1559 }
1560
1561#if check_erase2_debug > 2
1562 pr_err("mt_for_each %d and count %d\n", check, entry_count);
1563#endif
1564
1565 MT_BUG_ON(mt, check != entry_count);
1566
1567 check = 0;
1568 addr = 0;
1569 mas_reset(&mas);
1570 mas.index = 0;
1571 rcu_read_lock();
1572 mas_for_each(&mas, foo, ULONG_MAX) {
1573 if (xa_is_zero(foo)) {
1574 if (addr == mas.index) {
1575 mt_dump(mas.tree);
1576 pr_err("retry failed %lu - %lu\n",
1577 mas.index, mas.last);
1578 MT_BUG_ON(mt, 1);
1579 }
1580 addr = mas.index;
1581 continue;
1582 }
1583#if check_erase2_debug > 2
1584 pr_err("mas: %lu -> %p\n", mas.index, foo);
1585#endif
1586 check++;
1587 if (check > entry_count)
1588 break;
1589 }
1590 rcu_read_unlock();
1591#if check_erase2_debug > 2
1592 pr_err("mas_for_each %d and count %d\n", check, entry_count);
1593 mt_validate(mt);
1594#endif
1595
1596 MT_BUG_ON(mt, check != entry_count);
1597
1598 MT_BUG_ON(mt, mtree_load(mas.tree, 0) != NULL);
1599 }
1600}
1601
1602
1603/* These tests were pulled from kvm tests. */
1604static noinline void check_erase2_sets(struct maple_tree *mt)
1605{
1606 void *entry;
1607 unsigned long start = 0;
1608 unsigned long set[] = {
1609STORE, 140737488347136, 140737488351231,
1610STORE, 140721266458624, 140737488351231,
1611ERASE, 140721266458624, 140737488351231,
1612STORE, 140721266458624, 140721266462719,
1613STORE, 94735788949504, 94735789121535,
1614ERASE, 94735788949504, 94735789121535,
1615STORE, 94735788949504, 94735788965887,
1616STORE, 94735788965888, 94735789121535,
1617ERASE, 94735788965888, 94735789121535,
1618STORE, 94735788965888, 94735789068287,
1619STORE, 94735789068288, 94735789109247,
1620STORE, 94735789109248, 94735789121535,
1621STORE, 140253902692352, 140253902864383,
1622ERASE, 140253902692352, 140253902864383,
1623STORE, 140253902692352, 140253902696447,
1624STORE, 140253902696448, 140253902864383,
1625 };
1626 unsigned long set2[] = {
1627STORE, 140737488347136, 140737488351231,
1628STORE, 140735933583360, 140737488351231,
1629ERASE, 140735933583360, 140737488351231,
1630STORE, 140735933583360, 140735933587455,
1631STORE, 94811003260928, 94811003432959,
1632ERASE, 94811003260928, 94811003432959,
1633STORE, 94811003260928, 94811003277311,
1634STORE, 94811003277312, 94811003432959,
1635ERASE, 94811003277312, 94811003432959,
1636STORE, 94811003277312, 94811003379711,
1637STORE, 94811003379712, 94811003420671,
1638STORE, 94811003420672, 94811003432959,
1639STORE, 140277094653952, 140277094825983,
1640ERASE, 140277094653952, 140277094825983,
1641STORE, 140277094653952, 140277094658047,
1642STORE, 140277094658048, 140277094825983,
1643ERASE, 140277094658048, 140277094825983,
1644STORE, 140277094658048, 140277094780927,
1645STORE, 140277094780928, 140277094813695,
1646STORE, 140277094813696, 140277094821887,
1647STORE, 140277094821888, 140277094825983,
1648STORE, 140735933906944, 140735933911039,
1649 };
1650 unsigned long set3[] = {
1651STORE, 140737488347136, 140737488351231,
1652STORE, 140735790264320, 140737488351231,
1653ERASE, 140735790264320, 140737488351231,
1654STORE, 140735790264320, 140735790268415,
1655STORE, 94016597282816, 94016597454847,
1656ERASE, 94016597282816, 94016597454847,
1657STORE, 94016597282816, 94016597299199,
1658STORE, 94016597299200, 94016597454847,
1659ERASE, 94016597299200, 94016597454847,
1660STORE, 94016597299200, 94016597401599,
1661STORE, 94016597401600, 94016597442559,
1662STORE, 94016597442560, 94016597454847,
1663STORE, 140496959283200, 140496959455231,
1664ERASE, 140496959283200, 140496959455231,
1665STORE, 140496959283200, 140496959287295,
1666STORE, 140496959287296, 140496959455231,
1667ERASE, 140496959287296, 140496959455231,
1668STORE, 140496959287296, 140496959410175,
1669STORE, 140496959410176, 140496959442943,
1670STORE, 140496959442944, 140496959451135,
1671STORE, 140496959451136, 140496959455231,
1672STORE, 140735791718400, 140735791722495,
1673STORE, 140735791706112, 140735791718399,
1674STORE, 47135835713536, 47135835721727,
1675STORE, 47135835721728, 47135835729919,
1676STORE, 47135835729920, 47135835893759,
1677ERASE, 47135835729920, 47135835893759,
1678STORE, 47135835729920, 47135835742207,
1679STORE, 47135835742208, 47135835893759,
1680STORE, 47135835840512, 47135835893759,
1681STORE, 47135835742208, 47135835840511,
1682ERASE, 47135835742208, 47135835840511,
1683STORE, 47135835742208, 47135835840511,
1684STORE, 47135835885568, 47135835893759,
1685STORE, 47135835840512, 47135835885567,
1686ERASE, 47135835840512, 47135835885567,
1687STORE, 47135835840512, 47135835893759,
1688ERASE, 47135835840512, 47135835893759,
1689STORE, 47135835840512, 47135835885567,
1690STORE, 47135835885568, 47135835893759,
1691 };
1692
1693 unsigned long set4[] = {
1694STORE, 140737488347136, 140737488351231,
1695STORE, 140728251703296, 140737488351231,
1696ERASE, 140728251703296, 140737488351231,
1697STORE, 140728251703296, 140728251707391,
1698STORE, 94668429205504, 94668429377535,
1699ERASE, 94668429205504, 94668429377535,
1700STORE, 94668429205504, 94668429221887,
1701STORE, 94668429221888, 94668429377535,
1702ERASE, 94668429221888, 94668429377535,
1703STORE, 94668429221888, 94668429324287,
1704STORE, 94668429324288, 94668429365247,
1705STORE, 94668429365248, 94668429377535,
1706STORE, 47646523273216, 47646523445247,
1707ERASE, 47646523273216, 47646523445247,
1708STORE, 47646523273216, 47646523277311,
1709STORE, 47646523277312, 47646523445247,
1710ERASE, 47646523277312, 47646523445247,
1711STORE, 47646523277312, 47646523400191,
1712 };
1713
1714 unsigned long set5[] = {
1715STORE, 140737488347136, 140737488351231,
1716STORE, 140726874062848, 140737488351231,
1717ERASE, 140726874062848, 140737488351231,
1718STORE, 140726874062848, 140726874066943,
1719STORE, 94248892870656, 94248893042687,
1720ERASE, 94248892870656, 94248893042687,
1721STORE, 94248892870656, 94248892887039,
1722STORE, 94248892887040, 94248893042687,
1723ERASE, 94248892887040, 94248893042687,
1724STORE, 94248892887040, 94248892989439,
1725STORE, 94248892989440, 94248893030399,
1726STORE, 94248893030400, 94248893042687,
1727STORE, 47884786266112, 47884786438143,
1728ERASE, 47884786266112, 47884786438143,
1729STORE, 47884786266112, 47884786270207,
1730STORE, 47884786270208, 47884786438143,
1731ERASE, 47884786270208, 47884786438143,
1732STORE, 47884786270208, 47884786393087,
1733STORE, 47884786393088, 47884786425855,
1734STORE, 47884786425856, 47884786434047,
1735STORE, 47884786434048, 47884786438143,
1736STORE, 140726874513408, 140726874517503,
1737STORE, 140726874501120, 140726874513407,
1738STORE, 47884786438144, 47884786446335,
1739STORE, 47884786446336, 47884786454527,
1740STORE, 47884786454528, 47884786618367,
1741ERASE, 47884786454528, 47884786618367,
1742STORE, 47884786454528, 47884786466815,
1743STORE, 47884786466816, 47884786618367,
1744STORE, 47884786565120, 47884786618367,
1745STORE, 47884786466816, 47884786565119,
1746ERASE, 47884786466816, 47884786565119,
1747STORE, 47884786466816, 47884786565119,
1748STORE, 47884786610176, 47884786618367,
1749STORE, 47884786565120, 47884786610175,
1750ERASE, 47884786565120, 47884786610175,
1751STORE, 47884786565120, 47884786618367,
1752ERASE, 47884786565120, 47884786618367,
1753STORE, 47884786565120, 47884786610175,
1754STORE, 47884786610176, 47884786618367,
1755ERASE, 47884786610176, 47884786618367,
1756STORE, 47884786610176, 47884786618367,
1757STORE, 47884786618368, 47884789669887,
1758STORE, 47884787163136, 47884789669887,
1759STORE, 47884786618368, 47884787163135,
1760ERASE, 47884787163136, 47884789669887,
1761STORE, 47884787163136, 47884789448703,
1762STORE, 47884789448704, 47884789669887,
1763STORE, 47884788858880, 47884789448703,
1764STORE, 47884787163136, 47884788858879,
1765ERASE, 47884787163136, 47884788858879,
1766STORE, 47884787163136, 47884788858879,
1767STORE, 47884789444608, 47884789448703,
1768STORE, 47884788858880, 47884789444607,
1769ERASE, 47884788858880, 47884789444607,
1770STORE, 47884788858880, 47884789444607,
1771STORE, 47884789653504, 47884789669887,
1772STORE, 47884789448704, 47884789653503,
1773ERASE, 47884789448704, 47884789653503,
1774STORE, 47884789448704, 47884789653503,
1775ERASE, 47884789653504, 47884789669887,
1776STORE, 47884789653504, 47884789669887,
1777STORE, 47884789669888, 47884791508991,
1778STORE, 47884789809152, 47884791508991,
1779STORE, 47884789669888, 47884789809151,
1780ERASE, 47884789809152, 47884791508991,
1781STORE, 47884789809152, 47884791468031,
1782STORE, 47884791468032, 47884791508991,
1783STORE, 47884791152640, 47884791468031,
1784STORE, 47884789809152, 47884791152639,
1785ERASE, 47884789809152, 47884791152639,
1786STORE, 47884789809152, 47884791152639,
1787STORE, 47884791463936, 47884791468031,
1788STORE, 47884791152640, 47884791463935,
1789ERASE, 47884791152640, 47884791463935,
1790STORE, 47884791152640, 47884791463935,
1791STORE, 47884791492608, 47884791508991,
1792STORE, 47884791468032, 47884791492607,
1793ERASE, 47884791468032, 47884791492607,
1794STORE, 47884791468032, 47884791492607,
1795ERASE, 47884791492608, 47884791508991,
1796STORE, 47884791492608, 47884791508991,
1797STORE, 47884791508992, 47884791644159,
1798ERASE, 47884791508992, 47884791644159,
1799STORE, 47884791508992, 47884791533567,
1800STORE, 47884791533568, 47884791644159,
1801STORE, 47884791595008, 47884791644159,
1802STORE, 47884791533568, 47884791595007,
1803ERASE, 47884791533568, 47884791595007,
1804STORE, 47884791533568, 47884791595007,
1805STORE, 47884791619584, 47884791644159,
1806STORE, 47884791595008, 47884791619583,
1807ERASE, 47884791595008, 47884791619583,
1808STORE, 47884791595008, 47884791644159,
1809ERASE, 47884791595008, 47884791644159,
1810STORE, 47884791595008, 47884791619583,
1811STORE, 47884791619584, 47884791644159,
1812STORE, 47884791627776, 47884791644159,
1813STORE, 47884791619584, 47884791627775,
1814ERASE, 47884791619584, 47884791627775,
1815STORE, 47884791619584, 47884791627775,
1816ERASE, 47884791627776, 47884791644159,
1817STORE, 47884791627776, 47884791644159,
1818STORE, 47884791644160, 47884791664639,
1819ERASE, 47884791644160, 47884791664639,
1820STORE, 47884791644160, 47884791648255,
1821STORE, 47884791648256, 47884791664639,
1822STORE, 47884791652352, 47884791664639,
1823STORE, 47884791648256, 47884791652351,
1824ERASE, 47884791648256, 47884791652351,
1825STORE, 47884791648256, 47884791652351,
1826STORE, 47884791656448, 47884791664639,
1827STORE, 47884791652352, 47884791656447,
1828ERASE, 47884791652352, 47884791656447,
1829STORE, 47884791652352, 47884791664639,
1830ERASE, 47884791652352, 47884791664639,
1831STORE, 47884791652352, 47884791656447,
1832STORE, 47884791656448, 47884791664639,
1833ERASE, 47884791656448, 47884791664639,
1834STORE, 47884791656448, 47884791664639,
1835STORE, 47884791664640, 47884791672831,
1836ERASE, 47884791468032, 47884791492607,
1837STORE, 47884791468032, 47884791484415,
1838STORE, 47884791484416, 47884791492607,
1839ERASE, 47884791656448, 47884791664639,
1840STORE, 47884791656448, 47884791660543,
1841STORE, 47884791660544, 47884791664639,
1842ERASE, 47884791619584, 47884791627775,
1843STORE, 47884791619584, 47884791623679,
1844STORE, 47884791623680, 47884791627775,
1845 };
1846
1847 unsigned long set6[] = {
1848STORE, 140737488347136, 140737488351231,
1849STORE, 140722999021568, 140737488351231,
1850ERASE, 140722999021568, 140737488351231,
1851STORE, 140722999021568, 140722999025663,
1852STORE, 94901500268544, 94901500440575,
1853ERASE, 94901500268544, 94901500440575,
1854STORE, 94901500268544, 94901500284927,
1855STORE, 94901500284928, 94901500440575,
1856ERASE, 94901500284928, 94901500440575,
1857STORE, 94901500284928, 94901500387327,
1858STORE, 94901500387328, 94901500428287,
1859STORE, 94901500428288, 94901500440575,
1860STORE, 47430426660864, 47430426832895,
1861ERASE, 47430426660864, 47430426832895,
1862STORE, 47430426660864, 47430426664959,
1863STORE, 47430426664960, 47430426832895,
1864ERASE, 47430426664960, 47430426832895,
1865STORE, 47430426664960, 47430426787839,
1866STORE, 47430426787840, 47430426820607,
1867STORE, 47430426820608, 47430426828799,
1868STORE, 47430426828800, 47430426832895,
1869STORE, 140722999115776, 140722999119871,
1870STORE, 140722999103488, 140722999115775,
1871STORE, 47430426832896, 47430426841087,
1872STORE, 47430426841088, 47430426849279,
1873STORE, 47430426849280, 47430427013119,
1874ERASE, 47430426849280, 47430427013119,
1875STORE, 47430426849280, 47430426861567,
1876STORE, 47430426861568, 47430427013119,
1877STORE, 47430426959872, 47430427013119,
1878STORE, 47430426861568, 47430426959871,
1879ERASE, 47430426861568, 47430426959871,
1880STORE, 47430426861568, 47430426959871,
1881STORE, 47430427004928, 47430427013119,
1882STORE, 47430426959872, 47430427004927,
1883ERASE, 47430426959872, 47430427004927,
1884STORE, 47430426959872, 47430427013119,
1885ERASE, 47430426959872, 47430427013119,
1886STORE, 47430426959872, 47430427004927,
1887STORE, 47430427004928, 47430427013119,
1888ERASE, 47430427004928, 47430427013119,
1889STORE, 47430427004928, 47430427013119,
1890STORE, 47430427013120, 47430430064639,
1891STORE, 47430427557888, 47430430064639,
1892STORE, 47430427013120, 47430427557887,
1893ERASE, 47430427557888, 47430430064639,
1894STORE, 47430427557888, 47430429843455,
1895STORE, 47430429843456, 47430430064639,
1896STORE, 47430429253632, 47430429843455,
1897STORE, 47430427557888, 47430429253631,
1898ERASE, 47430427557888, 47430429253631,
1899STORE, 47430427557888, 47430429253631,
1900STORE, 47430429839360, 47430429843455,
1901STORE, 47430429253632, 47430429839359,
1902ERASE, 47430429253632, 47430429839359,
1903STORE, 47430429253632, 47430429839359,
1904STORE, 47430430048256, 47430430064639,
1905STORE, 47430429843456, 47430430048255,
1906ERASE, 47430429843456, 47430430048255,
1907STORE, 47430429843456, 47430430048255,
1908ERASE, 47430430048256, 47430430064639,
1909STORE, 47430430048256, 47430430064639,
1910STORE, 47430430064640, 47430431903743,
1911STORE, 47430430203904, 47430431903743,
1912STORE, 47430430064640, 47430430203903,
1913ERASE, 47430430203904, 47430431903743,
1914STORE, 47430430203904, 47430431862783,
1915STORE, 47430431862784, 47430431903743,
1916STORE, 47430431547392, 47430431862783,
1917STORE, 47430430203904, 47430431547391,
1918ERASE, 47430430203904, 47430431547391,
1919STORE, 47430430203904, 47430431547391,
1920STORE, 47430431858688, 47430431862783,
1921STORE, 47430431547392, 47430431858687,
1922ERASE, 47430431547392, 47430431858687,
1923STORE, 47430431547392, 47430431858687,
1924STORE, 47430431887360, 47430431903743,
1925STORE, 47430431862784, 47430431887359,
1926ERASE, 47430431862784, 47430431887359,
1927STORE, 47430431862784, 47430431887359,
1928ERASE, 47430431887360, 47430431903743,
1929STORE, 47430431887360, 47430431903743,
1930STORE, 47430431903744, 47430432038911,
1931ERASE, 47430431903744, 47430432038911,
1932STORE, 47430431903744, 47430431928319,
1933STORE, 47430431928320, 47430432038911,
1934STORE, 47430431989760, 47430432038911,
1935STORE, 47430431928320, 47430431989759,
1936ERASE, 47430431928320, 47430431989759,
1937STORE, 47430431928320, 47430431989759,
1938STORE, 47430432014336, 47430432038911,
1939STORE, 47430431989760, 47430432014335,
1940ERASE, 47430431989760, 47430432014335,
1941STORE, 47430431989760, 47430432038911,
1942ERASE, 47430431989760, 47430432038911,
1943STORE, 47430431989760, 47430432014335,
1944STORE, 47430432014336, 47430432038911,
1945STORE, 47430432022528, 47430432038911,
1946STORE, 47430432014336, 47430432022527,
1947ERASE, 47430432014336, 47430432022527,
1948STORE, 47430432014336, 47430432022527,
1949ERASE, 47430432022528, 47430432038911,
1950STORE, 47430432022528, 47430432038911,
1951STORE, 47430432038912, 47430432059391,
1952ERASE, 47430432038912, 47430432059391,
1953STORE, 47430432038912, 47430432043007,
1954STORE, 47430432043008, 47430432059391,
1955STORE, 47430432047104, 47430432059391,
1956STORE, 47430432043008, 47430432047103,
1957ERASE, 47430432043008, 47430432047103,
1958STORE, 47430432043008, 47430432047103,
1959STORE, 47430432051200, 47430432059391,
1960STORE, 47430432047104, 47430432051199,
1961ERASE, 47430432047104, 47430432051199,
1962STORE, 47430432047104, 47430432059391,
1963ERASE, 47430432047104, 47430432059391,
1964STORE, 47430432047104, 47430432051199,
1965STORE, 47430432051200, 47430432059391,
1966ERASE, 47430432051200, 47430432059391,
1967STORE, 47430432051200, 47430432059391,
1968STORE, 47430432059392, 47430432067583,
1969ERASE, 47430431862784, 47430431887359,
1970STORE, 47430431862784, 47430431879167,
1971STORE, 47430431879168, 47430431887359,
1972ERASE, 47430432051200, 47430432059391,
1973STORE, 47430432051200, 47430432055295,
1974STORE, 47430432055296, 47430432059391,
1975ERASE, 47430432014336, 47430432022527,
1976STORE, 47430432014336, 47430432018431,
1977STORE, 47430432018432, 47430432022527,
1978 };
1979 unsigned long set7[] = {
1980STORE, 140737488347136, 140737488351231,
1981STORE, 140729808330752, 140737488351231,
1982ERASE, 140729808330752, 140737488351231,
1983STORE, 140729808330752, 140729808334847,
1984STORE, 94629632020480, 94629632192511,
1985ERASE, 94629632020480, 94629632192511,
1986STORE, 94629632020480, 94629632036863,
1987STORE, 94629632036864, 94629632192511,
1988ERASE, 94629632036864, 94629632192511,
1989STORE, 94629632036864, 94629632139263,
1990STORE, 94629632139264, 94629632180223,
1991STORE, 94629632180224, 94629632192511,
1992STORE, 47439981776896, 47439981948927,
1993ERASE, 47439981776896, 47439981948927,
1994STORE, 47439981776896, 47439981780991,
1995STORE, 47439981780992, 47439981948927,
1996ERASE, 47439981780992, 47439981948927,
1997STORE, 47439981780992, 47439981903871,
1998STORE, 47439981903872, 47439981936639,
1999STORE, 47439981936640, 47439981944831,
2000STORE, 47439981944832, 47439981948927,
2001STORE, 140729808474112, 140729808478207,
2002STORE, 140729808461824, 140729808474111,
2003STORE, 47439981948928, 47439981957119,
2004STORE, 47439981957120, 47439981965311,
2005STORE, 47439981965312, 47439982129151,
2006ERASE, 47439981965312, 47439982129151,
2007STORE, 47439981965312, 47439981977599,
2008STORE, 47439981977600, 47439982129151,
2009STORE, 47439982075904, 47439982129151,
2010STORE, 47439981977600, 47439982075903,
2011ERASE, 47439981977600, 47439982075903,
2012STORE, 47439981977600, 47439982075903,
2013STORE, 47439982120960, 47439982129151,
2014STORE, 47439982075904, 47439982120959,
2015ERASE, 47439982075904, 47439982120959,
2016STORE, 47439982075904, 47439982129151,
2017ERASE, 47439982075904, 47439982129151,
2018STORE, 47439982075904, 47439982120959,
2019STORE, 47439982120960, 47439982129151,
2020ERASE, 47439982120960, 47439982129151,
2021STORE, 47439982120960, 47439982129151,
2022STORE, 47439982129152, 47439985180671,
2023STORE, 47439982673920, 47439985180671,
2024STORE, 47439982129152, 47439982673919,
2025ERASE, 47439982673920, 47439985180671,
2026STORE, 47439982673920, 47439984959487,
2027STORE, 47439984959488, 47439985180671,
2028STORE, 47439984369664, 47439984959487,
2029STORE, 47439982673920, 47439984369663,
2030ERASE, 47439982673920, 47439984369663,
2031STORE, 47439982673920, 47439984369663,
2032STORE, 47439984955392, 47439984959487,
2033STORE, 47439984369664, 47439984955391,
2034ERASE, 47439984369664, 47439984955391,
2035STORE, 47439984369664, 47439984955391,
2036STORE, 47439985164288, 47439985180671,
2037STORE, 47439984959488, 47439985164287,
2038ERASE, 47439984959488, 47439985164287,
2039STORE, 47439984959488, 47439985164287,
2040ERASE, 47439985164288, 47439985180671,
2041STORE, 47439985164288, 47439985180671,
2042STORE, 47439985180672, 47439987019775,
2043STORE, 47439985319936, 47439987019775,
2044STORE, 47439985180672, 47439985319935,
2045ERASE, 47439985319936, 47439987019775,
2046STORE, 47439985319936, 47439986978815,
2047STORE, 47439986978816, 47439987019775,
2048STORE, 47439986663424, 47439986978815,
2049STORE, 47439985319936, 47439986663423,
2050ERASE, 47439985319936, 47439986663423,
2051STORE, 47439985319936, 47439986663423,
2052STORE, 47439986974720, 47439986978815,
2053STORE, 47439986663424, 47439986974719,
2054ERASE, 47439986663424, 47439986974719,
2055STORE, 47439986663424, 47439986974719,
2056STORE, 47439987003392, 47439987019775,
2057STORE, 47439986978816, 47439987003391,
2058ERASE, 47439986978816, 47439987003391,
2059STORE, 47439986978816, 47439987003391,
2060ERASE, 47439987003392, 47439987019775,
2061STORE, 47439987003392, 47439987019775,
2062STORE, 47439987019776, 47439987154943,
2063ERASE, 47439987019776, 47439987154943,
2064STORE, 47439987019776, 47439987044351,
2065STORE, 47439987044352, 47439987154943,
2066STORE, 47439987105792, 47439987154943,
2067STORE, 47439987044352, 47439987105791,
2068ERASE, 47439987044352, 47439987105791,
2069STORE, 47439987044352, 47439987105791,
2070STORE, 47439987130368, 47439987154943,
2071STORE, 47439987105792, 47439987130367,
2072ERASE, 47439987105792, 47439987130367,
2073STORE, 47439987105792, 47439987154943,
2074ERASE, 47439987105792, 47439987154943,
2075STORE, 47439987105792, 47439987130367,
2076STORE, 47439987130368, 47439987154943,
2077STORE, 47439987138560, 47439987154943,
2078STORE, 47439987130368, 47439987138559,
2079ERASE, 47439987130368, 47439987138559,
2080STORE, 47439987130368, 47439987138559,
2081ERASE, 47439987138560, 47439987154943,
2082STORE, 47439987138560, 47439987154943,
2083STORE, 47439987154944, 47439987175423,
2084ERASE, 47439987154944, 47439987175423,
2085STORE, 47439987154944, 47439987159039,
2086STORE, 47439987159040, 47439987175423,
2087STORE, 47439987163136, 47439987175423,
2088STORE, 47439987159040, 47439987163135,
2089ERASE, 47439987159040, 47439987163135,
2090STORE, 47439987159040, 47439987163135,
2091STORE, 47439987167232, 47439987175423,
2092STORE, 47439987163136, 47439987167231,
2093ERASE, 47439987163136, 47439987167231,
2094STORE, 47439987163136, 47439987175423,
2095ERASE, 47439987163136, 47439987175423,
2096STORE, 47439987163136, 47439987167231,
2097STORE, 47439987167232, 47439987175423,
2098ERASE, 47439987167232, 47439987175423,
2099STORE, 47439987167232, 47439987175423,
2100STORE, 47439987175424, 47439987183615,
2101ERASE, 47439986978816, 47439987003391,
2102STORE, 47439986978816, 47439986995199,
2103STORE, 47439986995200, 47439987003391,
2104ERASE, 47439987167232, 47439987175423,
2105STORE, 47439987167232, 47439987171327,
2106STORE, 47439987171328, 47439987175423,
2107ERASE, 47439987130368, 47439987138559,
2108STORE, 47439987130368, 47439987134463,
2109STORE, 47439987134464, 47439987138559,
2110 };
2111 unsigned long set8[] = {
2112STORE, 140737488347136, 140737488351231,
2113STORE, 140722482974720, 140737488351231,
2114ERASE, 140722482974720, 140737488351231,
2115STORE, 140722482974720, 140722482978815,
2116STORE, 94121505034240, 94121505206271,
2117ERASE, 94121505034240, 94121505206271,
2118STORE, 94121505034240, 94121505050623,
2119STORE, 94121505050624, 94121505206271,
2120ERASE, 94121505050624, 94121505206271,
2121STORE, 94121505050624, 94121505153023,
2122STORE, 94121505153024, 94121505193983,
2123STORE, 94121505193984, 94121505206271,
2124STORE, 47708483284992, 47708483457023,
2125ERASE, 47708483284992, 47708483457023,
2126STORE, 47708483284992, 47708483289087,
2127STORE, 47708483289088, 47708483457023,
2128ERASE, 47708483289088, 47708483457023,
2129STORE, 47708483289088, 47708483411967,
2130STORE, 47708483411968, 47708483444735,
2131STORE, 47708483444736, 47708483452927,
2132STORE, 47708483452928, 47708483457023,
2133STORE, 140722483142656, 140722483146751,
2134STORE, 140722483130368, 140722483142655,
2135STORE, 47708483457024, 47708483465215,
2136STORE, 47708483465216, 47708483473407,
2137STORE, 47708483473408, 47708483637247,
2138ERASE, 47708483473408, 47708483637247,
2139STORE, 47708483473408, 47708483485695,
2140STORE, 47708483485696, 47708483637247,
2141STORE, 47708483584000, 47708483637247,
2142STORE, 47708483485696, 47708483583999,
2143ERASE, 47708483485696, 47708483583999,
2144STORE, 47708483485696, 47708483583999,
2145STORE, 47708483629056, 47708483637247,
2146STORE, 47708483584000, 47708483629055,
2147ERASE, 47708483584000, 47708483629055,
2148STORE, 47708483584000, 47708483637247,
2149ERASE, 47708483584000, 47708483637247,
2150STORE, 47708483584000, 47708483629055,
2151STORE, 47708483629056, 47708483637247,
2152ERASE, 47708483629056, 47708483637247,
2153STORE, 47708483629056, 47708483637247,
2154STORE, 47708483637248, 47708486688767,
2155STORE, 47708484182016, 47708486688767,
2156STORE, 47708483637248, 47708484182015,
2157ERASE, 47708484182016, 47708486688767,
2158STORE, 47708484182016, 47708486467583,
2159STORE, 47708486467584, 47708486688767,
2160STORE, 47708485877760, 47708486467583,
2161STORE, 47708484182016, 47708485877759,
2162ERASE, 47708484182016, 47708485877759,
2163STORE, 47708484182016, 47708485877759,
2164STORE, 47708486463488, 47708486467583,
2165STORE, 47708485877760, 47708486463487,
2166ERASE, 47708485877760, 47708486463487,
2167STORE, 47708485877760, 47708486463487,
2168STORE, 47708486672384, 47708486688767,
2169STORE, 47708486467584, 47708486672383,
2170ERASE, 47708486467584, 47708486672383,
2171STORE, 47708486467584, 47708486672383,
2172ERASE, 47708486672384, 47708486688767,
2173STORE, 47708486672384, 47708486688767,
2174STORE, 47708486688768, 47708488527871,
2175STORE, 47708486828032, 47708488527871,
2176STORE, 47708486688768, 47708486828031,
2177ERASE, 47708486828032, 47708488527871,
2178STORE, 47708486828032, 47708488486911,
2179STORE, 47708488486912, 47708488527871,
2180STORE, 47708488171520, 47708488486911,
2181STORE, 47708486828032, 47708488171519,
2182ERASE, 47708486828032, 47708488171519,
2183STORE, 47708486828032, 47708488171519,
2184STORE, 47708488482816, 47708488486911,
2185STORE, 47708488171520, 47708488482815,
2186ERASE, 47708488171520, 47708488482815,
2187STORE, 47708488171520, 47708488482815,
2188STORE, 47708488511488, 47708488527871,
2189STORE, 47708488486912, 47708488511487,
2190ERASE, 47708488486912, 47708488511487,
2191STORE, 47708488486912, 47708488511487,
2192ERASE, 47708488511488, 47708488527871,
2193STORE, 47708488511488, 47708488527871,

36114 more lines aren’t shown here.

lib/usercopy.c+2−1

This diff is large: its 11 lines aren’t shown here.

mm/Kconfig+27−7

This diff is large: its 55 lines aren’t shown here.

mm/Makefile+6−2

This diff is large: its 29 lines aren’t shown here.

mm/backing-dev.c+1−5

This diff is large: its 20 lines aren’t shown here.

mm/cma_debug.c+1−4

This diff is large: its 13 lines aren’t shown here.

mm/compaction.c+17−7

This diff is large: its 68 lines aren’t shown here.

mm/damon/Kconfig+3−0

This diff is large: its 10 lines aren’t shown here.

mm/damon/core-test.h+26−3

This diff is large: its 63 lines aren’t shown here.

mm/damon/core.c+184−97

This diff is large: its 520 lines aren’t shown here.

mm/damon/dbgfs.c+30−22

This diff is large: its 134 lines aren’t shown here.

mm/damon/lru_sort.c+87−293

This diff is large: its 447 lines aren’t shown here.

mm/damon/modules-common.h+46−0

This diff is large: its 47 lines aren’t shown here.

mm/damon/ops-common.c+8−42

This diff is large: its 76 lines aren’t shown here.

mm/damon/ops-common.h+1−1

This diff is large: its 9 lines aren’t shown here.

mm/damon/paddr.c+21−22

This diff is large: its 111 lines aren’t shown here.

mm/damon/reclaim.c+57−232

This diff is large: its 343 lines aren’t shown here.

mm/damon/sysfs.c+63−80

This diff is large: its 392 lines aren’t shown here.

mm/damon/vaddr-test.h+12−24

This diff is large: its 63 lines aren’t shown here.

mm/damon/vaddr.c+58−44

This diff is large: its 223 lines aren’t shown here.

mm/debug.c+6−8

This diff is large: its 44 lines aren’t shown here.

mm/filemap.c+66−58

This diff is large: its 247 lines aren’t shown here.

mm/folio-compat.c+6−0

This diff is large: its 13 lines aren’t shown here.

mm/gup.c+141−107

This diff is large: its 369 lines aren’t shown here.

mm/hmm.c+1−1

This diff is large: its 9 lines aren’t shown here.

mm/huge_memory.c+117−88

This diff is large: its 541 lines aren’t shown here.

mm/hugetlb.c+499−293

This diff is large: its 1626 lines aren’t shown here.

mm/hugetlb_cgroup.c+12−15

This diff is large: its 73 lines aren’t shown here.

mm/hugetlb_vmemmap.c+7−3

This diff is large: its 26 lines aren’t shown here.

mm/hwpoison-inject.c+2−2

This diff is large: its 16 lines aren’t shown here.

mm/init-mm.c+2−2

This diff is large: its 17 lines aren’t shown here.

mm/internal.h+11−37

This diff is large: its 100 lines aren’t shown here.

mm/kasan/Makefile+8−0

This diff is large: its 16 lines aren’t shown here.

mm/kasan/common.c+16−161

This diff is large: its 256 lines aren’t shown here.

mm/kasan/generic.c+143−11

This diff is large: its 172 lines aren’t shown here.

mm/kasan/hw_tags.c+1−38

This diff is large: its 70 lines aren’t shown here.

mm/kasan/kasan.h+117−54

This diff is large: its 292 lines aren’t shown here.

mm/kasan/kasan_test.crenamed from lib/test_kasan.c+25−1

This diff is large: its 47 lines aren’t shown here.

mm/kasan/kasan_test_module.crenamed from lib/test_kasan_module.c+1−1

This diff is large: its 9 lines aren’t shown here.

mm/kasan/report.c+69−69

This diff is large: its 239 lines aren’t shown here.

mm/kasan/report_generic.c+45−1

This diff is large: its 65 lines aren’t shown here.

mm/kasan/report_tags.c+94−29

This diff is large: its 137 lines aren’t shown here.

mm/kasan/sw_tags.c+4−1

This diff is large: its 12 lines aren’t shown here.

mm/kasan/tags.c+114−29

This diff is large: its 169 lines aren’t shown here.

mm/kfence/core.c+9−13

This diff is large: its 41 lines aren’t shown here.

mm/khugepaged.c+739−429

This diff is large: its 2018 lines aren’t shown here.

mm/kmemleak.c+9−12

This diff is large: its 57 lines aren’t shown here.

mm/kmsan/Makefile+28−0

This diff is large: its 29 lines aren’t shown here.

mm/kmsan/core.c+450−0

This diff is large: its 451 lines aren’t shown here.

mm/kmsan/hooks.c+384−0

This diff is large: its 385 lines aren’t shown here.

mm/kmsan/init.c+235−0

This diff is large: its 236 lines aren’t shown here.

mm/kmsan/instrumentation.c+307−0

This diff is large: its 308 lines aren’t shown here.

mm/kmsan/kmsan.h+209−0

This diff is large: its 210 lines aren’t shown here.

mm/kmsan/kmsan_test.c+581−0

This diff is large: its 582 lines aren’t shown here.

mm/kmsan/report.c+219−0

This diff is large: its 220 lines aren’t shown here.

mm/kmsan/shadow.c+298−0

This diff is large: its 299 lines aren’t shown here.

mm/ksm.c+190−185

This diff is large: its 1066 lines aren’t shown here.

mm/madvise.c+33−27

This diff is large: its 155 lines aren’t shown here.

mm/memblock.c+3−3

This diff is large: its 24 lines aren’t shown here.

mm/memcontrol.c+184−97

This diff is large: its 607 lines aren’t shown here.

mm/memory-failure.c+57−69

This diff is large: its 339 lines aren’t shown here.

mm/memory-tiers.c+732−0

This diff is large: its 733 lines aren’t shown here.

mm/memory.c+160−114

This diff is large: its 672 lines aren’t shown here.

mm/memory_hotplug.c+4−7

This diff is large: its 43 lines aren’t shown here.

mm/mempolicy.c+38−28

This diff is large: its 205 lines aren’t shown here.

mm/memremap.c+1−1

This diff is large: its 9 lines aren’t shown here.

mm/migrate.c+116−535

This diff is large: its 994 lines aren’t shown here.

mm/migrate_device.c+16−3

This diff is large: its 33 lines aren’t shown here.

mm/mlock.c+19−18

This diff is large: its 95 lines aren’t shown here.

mm/mm_init.c+4−2

This diff is large: its 19 lines aren’t shown here.

mm/mm_slot.h+55−0

This diff is large: its 56 lines aren’t shown here.

mm/mmap.c+1135−1124

This diff is large: its 3057 lines aren’t shown here.

mm/mmzone.c+2−0

This diff is large: its 9 lines aren’t shown here.

mm/mprotect.c+13−4

This diff is large: its 73 lines aren’t shown here.

mm/mremap.c+30−11

This diff is large: its 99 lines aren’t shown here.

mm/msync.c+1−1

This diff is large: its 9 lines aren’t shown here.

mm/nommu.c+141−119

This diff is large: its 462 lines aren’t shown here.

mm/oom_kill.c+5−6

This diff is large: its 43 lines aren’t shown here.

mm/page_alloc.c+105−91

This diff is large: its 613 lines aren’t shown here.

mm/page_counter.c+7−8

This diff is large: its 40 lines aren’t shown here.

mm/page_ext.c+108−9

This diff is large: its 206 lines aren’t shown here.

mm/page_io.c+24−19

This diff is large: its 107 lines aren’t shown here.

mm/page_isolation.c+8−9

This diff is large: its 52 lines aren’t shown here.

mm/page_owner.c+76−27

This diff is large: its 303 lines aren’t shown here.

mm/page_table_check.c+9−5

This diff is large: its 68 lines aren’t shown here.

mm/page_vma_mapped.c+3−3

This diff is large: its 27 lines aren’t shown here.

mm/pagewalk.c+10−2

This diff is large: its 26 lines aren’t shown here.

mm/rmap.c+106−78

This diff is large: its 326 lines aren’t shown here.

mm/rodata_test.c+3−5

This diff is large: its 31 lines aren’t shown here.

mm/secretmem.c+3−5

This diff is large: its 23 lines aren’t shown here.

mm/shmem.c+224−205

This diff is large: its 1082 lines aren’t shown here.

mm/shuffle.c+10−11

This diff is large: its 34 lines aren’t shown here.

mm/slab.h+1−0

This diff is large: its 8 lines aren’t shown here.

mm/slab_common.c+2−0

This diff is large: its 16 lines aren’t shown here.

mm/slub.c+41−0

This diff is large: its 90 lines aren’t shown here.

mm/swap.c+58−15

This diff is large: its 135 lines aren’t shown here.

mm/swap.h+7−11

This diff is large: its 52 lines aren’t shown here.

mm/swap_cgroup.c+6−0

This diff is large: its 20 lines aren’t shown here.

mm/swap_slots.c+1−1

This diff is large: its 9 lines aren’t shown here.

mm/swap_state.c+57−54

This diff is large: its 267 lines aren’t shown here.

mm/swapfile.c+90−88

This diff is large: its 371 lines aren’t shown here.

mm/truncate.c+1−1

This diff is large: its 9 lines aren’t shown here.

mm/userfaultfd.c+15−13

This diff is large: its 90 lines aren’t shown here.

mm/util.c+3−33

This diff is large: its 60 lines aren’t shown here.

mm/vmacache.c+0−117

This diff is large: its 118 lines aren’t shown here.

mm/vmalloc.c+26−9

This diff is large: its 109 lines aren’t shown here.

mm/vmscan.c+3184−372

This diff is large: its 4138 lines aren’t shown here.

mm/vmstat.c+1−8

This diff is large: its 51 lines aren’t shown here.

mm/workingset.c+108−2

This diff is large: its 146 lines aren’t shown here.

mm/zsmalloc.c+11−11

This diff is large: its 75 lines aren’t shown here.

mm/zswap.c+1−1

This diff is large: its 9 lines aren’t shown here.

scripts/Makefile.kmsan+8−0

This diff is large: its 9 lines aren’t shown here.

scripts/Makefile.lib+9−0

This diff is large: its 16 lines aren’t shown here.

security/Kconfig.hardening+4−0

This diff is large: its 32 lines aren’t shown here.

tools/include/asm-generic/hugetlb_encode.h+13−13

This diff is large: its 32 lines aren’t shown here.

tools/include/linux/slab.h+4−0

This diff is large: its 9 lines aren’t shown here.

tools/include/uapi/asm-generic/mman-common.h+2−0

This diff is large: its 9 lines aren’t shown here.

tools/objtool/check.c+20−0

This diff is large: its 27 lines aren’t shown here.

tools/testing/memblock/linux/mmzone.h+2−0

This diff is large: its 9 lines aren’t shown here.

tools/testing/radix-tree/.gitignore+2−0

This diff is large: its 6 lines aren’t shown here.

tools/testing/radix-tree/Makefile+7−2

This diff is large: its 38 lines aren’t shown here.

tools/testing/radix-tree/generated/autoconf.h+1−0

This diff is large: its 3 lines aren’t shown here.

tools/testing/radix-tree/linux.c+156−4

This diff is large: its 210 lines aren’t shown here.

tools/testing/radix-tree/linux/kernel.h+1−0

This diff is large: its 8 lines aren’t shown here.

tools/testing/radix-tree/linux/lockdep.h+2−0

This diff is large: its 7 lines aren’t shown here.

tools/testing/radix-tree/linux/maple_tree.h+7−0

This diff is large: its 8 lines aren’t shown here.

tools/testing/radix-tree/maple.c+59−0

This diff is large: its 60 lines aren’t shown here.

tools/testing/radix-tree/trace/events/maple_tree.h+5−0

This diff is large: its 6 lines aren’t shown here.

tools/testing/selftests/cgroup/config+0−1

This diff is large: its 6 lines aren’t shown here.

tools/testing/selftests/damon/Makefile+1−0

This diff is large: its 8 lines aren’t shown here.

tools/testing/selftests/damon/debugfs_duplicate_context_creation.sh+27−0

This diff is large: its 28 lines aren’t shown here.

tools/testing/selftests/vm/.gitignore+0−1

This diff is large: its 8 lines aren’t shown here.

tools/testing/selftests/vm/Makefile+3−20

This diff is large: its 47 lines aren’t shown here.

tools/testing/selftests/vm/check_config.sh+0−31

This diff is large: its 32 lines aren’t shown here.

tools/testing/selftests/vm/hmm-tests.c+73−35

This diff is large: its 185 lines aren’t shown here.

tools/testing/selftests/vm/khugepaged.c+861−334

This diff is large: its 1625 lines aren’t shown here.

tools/testing/selftests/vm/mremap_test.c+48−1

This diff is large: its 75 lines aren’t shown here.

tools/testing/selftests/vm/run_vmtests.sh+10−5

This diff is large: its 22 lines aren’t shown here.

tools/testing/selftests/vm/soft-dirty.c+1−1

This diff is large: its 9 lines aren’t shown here.

tools/testing/selftests/vm/split_huge_page_test.c+4−8

This diff is large: its 40 lines aren’t shown here.

tools/testing/selftests/vm/test_hmm.sh+0−10

This diff is large: its 22 lines aren’t shown here.

tools/testing/selftests/vm/userfaultfd.c+199−48

This diff is large: its 477 lines aren’t shown here.

tools/testing/selftests/vm/vm_util.c+27−9

This diff is large: its 68 lines aren’t shown here.

tools/testing/selftests/vm/vm_util.h+4−1

This diff is large: its 10 lines aren’t shown here.

tools/vm/page_owner_sort.c+6−1

This diff is large: its 14 lines aren’t shown here.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t