mm/mmap.c
Source file repositories/reference/linux-study-clean/mm/mmap.c
File Facts
- System
- Linux kernel
- Corpus path
mm/mmap.c- Extension
.c- Size
- 51223 bytes
- Lines
- 1922
- Domain
- Core OS
- Bucket
- Memory Management
- Inferred role
- Core OS: syscall or user/kernel boundary
- Status
- core implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Defines or participates in a user/kernel boundary; inspect argument validation, copy_from_user/copy_to_user, credentials, and dispatch target.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/slab.hlinux/backing-dev.hlinux/mm.hlinux/mm_inline.hlinux/shm.hlinux/mman.hlinux/pagemap.hlinux/swap.hlinux/syscalls.hlinux/capability.hlinux/init.hlinux/file.hlinux/fs.hlinux/personality.hlinux/security.hlinux/hugetlb.hlinux/shmem_fs.hlinux/profile.hlinux/export.hlinux/mount.hlinux/mempolicy.hlinux/rmap.hlinux/mmu_notifier.hlinux/mmdebug.hlinux/perf_event.hlinux/audit.hlinux/khugepaged.hlinux/uprobes.hlinux/notifier.hlinux/memory.hlinux/printk.h
Detected Declarations
syscall brksyscall mmap_pgoffsyscall old_mmapsyscall munmapsyscall remap_file_pagesstruct mmap_arg_structfunction vma_set_page_protfunction check_brk_limitsfunction round_hint_to_minfunction mlock_future_okfunction file_mmap_size_maxfunction file_mmap_okfunction do_mmapfunction ksys_mmap_pgofffunction stack_guard_placementfunction vm_unmapped_areafunction generic_get_unmapped_areafunction arch_get_unmapped_areafunction generic_get_unmapped_area_topdownfunction mmapfunction arch_get_unmapped_area_topdownfunction mm_get_unmapped_area_vmflagsfunction __get_unmapped_areafunction mm_get_unmapped_areafunction find_vma_intersectionfunction find_vmafunction find_vma_prevfunction cmdline_parse_stack_guard_gapfunction expand_stack_lockedfunction expand_stack_lockedfunction expand_stackfunction do_munmapfunction vm_munmapfunction remap_file_pagesfunction for_each_vma_rangefunction vm_brk_flagsfunction tear_down_vmasfunction exit_mmapfunction may_expand_vmfunction vm_stat_accountfunction special_mapping_closefunction special_mapping_mremapfunction special_mapping_splitfunction special_mapping_faultfunction vma_is_special_mappingfunction definedfunction mmap_initfunction min
Annotated Snippet
SYSCALL_DEFINE1(brk, unsigned long, brk)
{
unsigned long newbrk, oldbrk, origbrk;
struct mm_struct *mm = current->mm;
struct vm_area_struct *brkvma, *next = NULL;
unsigned long min_brk;
bool populate = false;
LIST_HEAD(uf);
struct vma_iterator vmi;
if (mmap_write_lock_killable(mm))
return -EINTR;
origbrk = mm->brk;
min_brk = mm->start_brk;
#ifdef CONFIG_COMPAT_BRK
/*
* CONFIG_COMPAT_BRK can still be overridden by setting
* randomize_va_space to 2, which will still cause mm->start_brk
* to be arbitrarily shifted
*/
if (!current->brk_randomized)
min_brk = mm->end_data;
#endif
if (brk < min_brk)
goto out;
/*
* Check against rlimit here. If this check is done later after the test
* of oldbrk with newbrk then it can escape the test and let the data
* segment grow beyond its set limit the in case where the limit is
* not page aligned -Ram Gupta
*/
if (check_data_rlimit(rlimit(RLIMIT_DATA), brk, mm->start_brk,
mm->end_data, mm->start_data))
goto out;
newbrk = PAGE_ALIGN(brk);
oldbrk = PAGE_ALIGN(mm->brk);
if (oldbrk == newbrk) {
mm->brk = brk;
goto success;
}
/* Always allow shrinking brk. */
if (brk <= mm->brk) {
/* Search one past newbrk */
vma_iter_init(&vmi, mm, newbrk);
brkvma = vma_find(&vmi, oldbrk);
if (!brkvma || brkvma->vm_start >= oldbrk)
goto out; /* mapping intersects with an existing non-brk vma. */
/*
* mm->brk must be protected by write mmap_lock.
* do_vmi_align_munmap() will drop the lock on success, so
* update it before calling do_vma_munmap().
*/
mm->brk = brk;
if (do_vmi_align_munmap(&vmi, brkvma, mm, newbrk, oldbrk, &uf,
/* unlock = */ true))
goto out;
goto success_unlocked;
}
if (check_brk_limits(oldbrk, newbrk - oldbrk))
goto out;
/*
* Only check if the next VMA is within the stack_guard_gap of the
* expansion area
*/
vma_iter_init(&vmi, mm, oldbrk);
next = vma_find(&vmi, newbrk + PAGE_SIZE + stack_guard_gap);
if (next && newbrk + PAGE_SIZE > vm_start_gap(next))
goto out;
brkvma = vma_prev_limit(&vmi, mm->start_brk);
/* Ok, looks good - let it rip. */
if (do_brk_flags(&vmi, brkvma, oldbrk, newbrk - oldbrk,
EMPTY_VMA_FLAGS) < 0)
goto out;
mm->brk = brk;
if (mm->def_flags & VM_LOCKED)
populate = true;
success:
mmap_write_unlock(mm);
success_unlocked:
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/slab.h`, `linux/backing-dev.h`, `linux/mm.h`, `linux/mm_inline.h`, `linux/shm.h`, `linux/mman.h`, `linux/pagemap.h`.
- Detected declarations: `syscall brk`, `syscall mmap_pgoff`, `syscall old_mmap`, `syscall munmap`, `syscall remap_file_pages`, `struct mmap_arg_struct`, `function vma_set_page_prot`, `function check_brk_limits`, `function round_hint_to_min`, `function mlock_future_ok`.
- Atlas domain: Core OS / Memory Management.
- Implementation status: core implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.