7.3. Memory Regions

Linux implements memory regions by means of descriptors of type vm_area_struct:

struct vm_area_struct { 
    struct mm_struct * vm_mm; 
    unsigned long vm_start; 
    unsigned long vm_end; 
    struct vm_area_struct *vm_next; 
    pgprot_t vm_page_prot; 
    unsigned short vm_flags; 
    short vm_avl_height; 
    struct vm_area_struct *vm_avl_left, *vm_avl_right; 
    struct vm_area_struct *vm_next_share, **vm_pprev_share; 
    struct vm_operations_struct * vm_ops; 
    unsigned long vm_offset; 
    struct file * vm_file; 
    unsigned long vm_pte; 
};

Each memory region descriptor identifies a linear address interval. The vm_start field contains the first linear address of the interval, while the vm_end field contains the first linear address outside of the interval; vm_end - vm_start thus denotes the length of the memory region. The vm_mm field points to the mm_struct memory descriptor of the process that owns the region. We shall describe the other fields of vm_area_struct later.

Memory regions owned by a process never overlap, and the kernel tries to merge regions when a new one is allocated right next to an existing one. Two adjacent regions can be merged if their access rights match.

As shown in Figure 7-1, when a new range of linear addresses is added to the process address space, the kernel checks whether an already existing memory region can be enlarged (case a). If not, a new memory region is created (case b). Similarly, if a range of linear addresses is removed from the process address space, the kernel resizes ...

Get Understanding the Linux Kernel now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.