Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm: abstract reading sysctl_max_map_count, and READ_ONCE()

Concurrent reads and writes of sysctl_max_map_count are possible, so we
should READ_ONCE() and WRITE_ONCE().

The sysctl procfs logic already enforces WRITE_ONCE(), so abstract the
read side with get_sysctl_max_map_count().

While we're here, also move the field to mm/internal.h and add the getter
there since only mm interacts with it, there's no need for anybody else to
have access.

Finally, update the VMA userland tests to reflect the change.

Link: https://lkml.kernel.org/r/0715259eb37cbdfde4f9e5db92a20ec7110a1ce5.1773249037.git.ljs@kernel.org
Signed-off-by: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Cc: Jann Horn <jannh@google.com>
Cc: Jianzhou Zhao <luckd0g@163.com>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Lorenzo Stoakes (Oracle) and committed by
Andrew Morton
2d1e54aa 9b9b8d4a

+24 -12
-2
include/linux/mm.h
··· 207 207 #define MAPCOUNT_ELF_CORE_MARGIN (5) 208 208 #define DEFAULT_MAX_MAP_COUNT (USHRT_MAX - MAPCOUNT_ELF_CORE_MARGIN) 209 209 210 - extern int sysctl_max_map_count; 211 - 212 210 extern unsigned long sysctl_user_reserve_kbytes; 213 211 extern unsigned long sysctl_admin_reserve_kbytes; 214 212
+6
mm/internal.h
··· 1863 1863 1864 1864 #endif /* CONFIG_MMU_NOTIFIER */ 1865 1865 1866 + extern int sysctl_max_map_count; 1867 + static inline int get_sysctl_max_map_count(void) 1868 + { 1869 + return READ_ONCE(sysctl_max_map_count); 1870 + } 1871 + 1866 1872 #endif /* __MM_INTERNAL_H */
+1 -1
mm/mmap.c
··· 375 375 return -EOVERFLOW; 376 376 377 377 /* Too many mappings? */ 378 - if (mm->map_count > sysctl_max_map_count) 378 + if (mm->map_count > get_sysctl_max_map_count()) 379 379 return -ENOMEM; 380 380 381 381 /*
+2 -2
mm/mremap.c
··· 1045 1045 * which may not merge, then (if MREMAP_DONTUNMAP is not set) unmap the 1046 1046 * source, which may split, causing a net increase of 2 mappings. 1047 1047 */ 1048 - if (current->mm->map_count + 2 > sysctl_max_map_count) 1048 + if (current->mm->map_count + 2 > get_sysctl_max_map_count()) 1049 1049 return -ENOMEM; 1050 1050 1051 1051 if (vma->vm_ops && vma->vm_ops->may_split) { ··· 1813 1813 * net increased map count of 2. In move_vma() we check for headroom of 1814 1814 * 2 additional mappings, so check early to avoid bailing out then. 1815 1815 */ 1816 - if (current->mm->map_count + 4 > sysctl_max_map_count) 1816 + if (current->mm->map_count + 4 > get_sysctl_max_map_count()) 1817 1817 return -ENOMEM; 1818 1818 1819 1819 return 0;
+1 -1
mm/nommu.c
··· 1317 1317 return -ENOMEM; 1318 1318 1319 1319 mm = vma->vm_mm; 1320 - if (mm->map_count >= sysctl_max_map_count) 1320 + if (mm->map_count >= get_sysctl_max_map_count()) 1321 1321 return -ENOMEM; 1322 1322 1323 1323 region = kmem_cache_alloc(vm_region_jar, GFP_KERNEL);
+3 -3
mm/vma.c
··· 590 590 static int split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma, 591 591 unsigned long addr, int new_below) 592 592 { 593 - if (vma->vm_mm->map_count >= sysctl_max_map_count) 593 + if (vma->vm_mm->map_count >= get_sysctl_max_map_count()) 594 594 return -ENOMEM; 595 595 596 596 return __split_vma(vmi, vma, addr, new_below); ··· 1394 1394 * its limit temporarily, to help free resources as expected. 1395 1395 */ 1396 1396 if (vms->end < vms->vma->vm_end && 1397 - vms->vma->vm_mm->map_count >= sysctl_max_map_count) { 1397 + vms->vma->vm_mm->map_count >= get_sysctl_max_map_count()) { 1398 1398 error = -ENOMEM; 1399 1399 goto map_count_exceeded; 1400 1400 } ··· 2868 2868 if (!may_expand_vm(mm, vm_flags, len >> PAGE_SHIFT)) 2869 2869 return -ENOMEM; 2870 2870 2871 - if (mm->map_count > sysctl_max_map_count) 2871 + if (mm->map_count > get_sysctl_max_map_count()) 2872 2872 return -ENOMEM; 2873 2873 2874 2874 if (security_vm_enough_memory_mm(mm, len >> PAGE_SHIFT))
-3
tools/testing/vma/include/custom.h
··· 21 21 #define VM_BUG_ON(_expr) (BUG_ON(_expr)) 22 22 #define VM_BUG_ON_VMA(_expr, _vma) (BUG_ON(_expr)) 23 23 24 - /* We hardcode this for now. */ 25 - #define sysctl_max_map_count 0x1000000UL 26 - 27 24 #define TASK_SIZE ((1ul << 47)-PAGE_SIZE) 28 25 29 26 /*
+9
tools/testing/vma/include/dup.h
··· 419 419 420 420 #define EMPTY_VMA_FLAGS ((vma_flags_t){ }) 421 421 422 + #define MAPCOUNT_ELF_CORE_MARGIN (5) 423 + #define DEFAULT_MAX_MAP_COUNT (USHRT_MAX - MAPCOUNT_ELF_CORE_MARGIN) 424 + 422 425 /* What action should be taken after an .mmap_prepare call is complete? */ 423 426 enum mmap_action_type { 424 427 MMAP_NOTHING, /* Mapping is complete, no further action. */ ··· 1344 1341 get_file(file); 1345 1342 swap(vma->vm_file, file); 1346 1343 fput(file); 1344 + } 1345 + 1346 + extern int sysctl_max_map_count; 1347 + static inline int get_sysctl_max_map_count(void) 1348 + { 1349 + return READ_ONCE(sysctl_max_map_count); 1347 1350 }
+2
tools/testing/vma/main.c
··· 14 14 #include "tests/mmap.c" 15 15 #include "tests/vma.c" 16 16 17 + int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT; 18 + 17 19 /* Helper functions which utilise static kernel functions. */ 18 20 19 21 struct vm_area_struct *merge_existing(struct vma_merge_struct *vmg)