What is the Linux kernel and what is the memory management subsystem? Chapter 7 – Small memory allocation (5)

Continuing from the previous article: What does the Linux kernel have and what does the memory management subsystem have? Chapter 6 – Small memory allocation (4)

References to this article:

linux process virtual address space

“Interesting Talk about the Core Principles of Linux Operating System: Part 4 Memory Management–Liu Chao”

4.6 In-depth understanding of Linux virtual memory management

Thanks!

2. Small memory allocation – brk and sbrk

1. brk source code analysis

When I talked about the sys_brk function code last time, I talked about struct vm_area_struct and introduced its related concepts in detail. Each vm_area_struct structure corresponds to a unique virtual memory area VMA in the virtual memory space. The virtual memory area is the above code segment (Text area), data segment (Data area), BSS segment (BSS area), heap, stack, etc. Each of them corresponds to a unique vm_area_struct structure (instance). As shown below:

This chapter provides a detailed analysis of the members of this structure. For ease of understanding, the definition of struct vm_area_struct is posted again. In include/linux/mm_types.h, the code is as follows:

/*
 * This struct describes a virtual memory area. There is one of these
 * per VM-area/task. A VM area is any part of the process virtual memory
 * space that has a special rule for the page-fault handlers (ie a shared
 * library, the executable area etc).
 */
struct vm_area_struct {
/* The first cache line has the info for VMA tree walking. */
 
unsigned long vm_start; /* Our start address within vm_mm. */
unsigned long vm_end; /* The first byte after our end address
within vm_mm. */
 
struct mm_struct *vm_mm; /* The address space we belong to. */
 
/*
* Access permissions of this VMA.
* See vmf_insert_mixed_prot() for discussion.
*/
pgprot_t vm_page_prot;
unsigned long vm_flags; /* Flags, see mm.h. */
 
/*
* For areas with an address space and backing store,
* linkage into the address_space->i_mmap interval tree.
*
* For private anonymous mappings, a pointer to a null terminated string
* containing the name given to the vma, or NULL if unnamed.
*/
 
union {
struct {
struct rb_node rb;
unsigned long rb_subtree_last;
} shared;
/*
* Serialized by mmap_sem. Never use directly because it is
* valid only when vm_file is NULL. Use anon_vma_name instead.
*/
struct anon_vma_name *anon_name;
};
 
/*
* A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma
* list, after a COW of one of the file pages. A MAP_SHARED vma
* can only be in the i_mmap tree. An anonymous MAP_PRIVATE, stack
* or brk vma (with NULL file) can only be in an anon_vma list.
*/
struct list_head anon_vma_chain; /* Serialized by mmap_lock & amp;
* page_table_lock */
struct anon_vma *anon_vma; /* Serialized by page_table_lock */
 
/* Function pointers to deal with this struct. */
const struct vm_operations_struct *vm_ops;
 
/* Information about our backing store: */
unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
units */
struct file * vm_file; /* File we map to (can be NULL). */
void * vm_private_data; /* was vm_pte (shared mem) */
 
#ifdef CONFIG_SWAP
atomic_long_t swap_readahead_info;
#endif
#ifndef CONFIG_MMU
struct vm_region *vm_region; /* NOMMU mapping region */
#endif
#ifdef CONFIG_NUMA
struct mempolicy *vm_policy; /* NUMA policy for the VMA */
#endif
struct vm_userfaultfd_ctx vm_userfaultfd_ctx;
} __randomize_layout;

The specific meanings of each member are as follows:

  • unsigned long vm_start

The starting address within vm_mm.

  • unsigned long vm_end

The first byte after the end address of vm_mm.

vm_start points to the starting address (lowest address) of this virtual memory area, and vm_start itself is included in this virtual memory area. vm_end points to the end address (highest address) of this virtual memory area, and vm_end itself is included outside this virtual memory area, so the vm_area_struct structure describes a virtual memory area [vm_start, vm_end] that is closed on the left and open on the right. .

  • struct mm_struct *vm_mm

The address space it belongs to. Since the virtual address space of each process is independent and does not interfere with each other, each process has a unique mm_struct structure, which is a memory descriptor that specifically describes the virtual address space of the process. The specific virtual memory area (VMA) represented here is the virtual address space (vm_mm) to which the above code segment (Text area), data segment (Data area), BSS segment (BSS area), heap, stack, etc. belong.

  • pgprot_t vm_page_prot and unsigned long vm_flags

Access rights to this VMA (Virtual Memory Area). To explain in more detail, vm_page_prot and vm_flags are used to mark the access permissions and behavior specifications of the virtual memory area represented by the vm_area_struct structure. Since virtual memory will eventually be mapped one-to-one with physical memory, there is also a corresponding concept of virtual pages in the virtual memory space. Virtual pages in virtual memory are mapped to physical pages in physical memory. Whether in virtual memory space or in physical memory, the smallest unit of memory managed by the kernel is the page.

vm_page_prot prefers to define page-level access control permissions in the underlying memory management architecture. It can be directly applied to the underlying page table. It is a specific concept. The virtual memory area VMA is composed of many virtual pages (pages), and each virtual page needs to be converted through the page table to find the corresponding physical page. The access rights to memory pages in the page table are determined by vm_page_prot.

vm_flags prefers access permissions and behavior specifications for the entire virtual memory area. It describes the overall information in the virtual memory area, rather than a specific independent page in the virtual memory area. vm_flags is an abstract concept. Conversion to specific page access permission vm_page_prot can be achieved through vma->vm_page_prot = vm_get_page_prot(vma->vm_flags).

Commonly used vm_flags values and corresponding access permissions are shown in the following table:

vm_flags Access rights
VM_READ Readable
VM_WRITE Writable
VM_EXEC Executable
VM_SHARD Can be shared between multiple processes
VM_IO Can be mapped to device IO space
VM_RESERVED The memory area cannot be swapped out
VM_SEQ_READ The memory area may be sequenced Access
VM_RAND_READ Memory area May be accessed randomly
  • VM_READ, VM_WRITE, VM_EXEC

Defines whether the virtual memory area can be read, written, executed, etc.

As mentioned earlier, the permissions of the code segment (Code Segment / Text Segment) memory area are readable and executable, but not writable; the data segment (Data Segment) has Readable and writable permissions but not executable; Heap has readable, writable and executable permissions; Stack usually has readable and writable permissions, but rarely executable permissions; The file mapping and anonymous mapping areas store shared link libraries, so they also require executable permissions.

According to the instructions above, the permissions of each area are as shown below:

  • VM_SHARD

Used to specify whether the physical memory mapped by this virtual memory area can be shared between multiple processes to complete inter-process communication. Setting this value is mmap’s shared mapping, otherwise it is private mapping.

  • VM_IO

The setting of the VM_IO flag indicates that this virtual memory area can be mapped to the device IO space. The VM_IO flag is usually set when the device driver performs mmap for IO space mapping.

  • VM_RESERVED

The setting of the VM_RESERVED flag indicates that this virtual memory area is very important and cannot be swapped out to disk when memory is tight.

  • VM_SEQ_READ and VM_RAND_READ

The setting of VM_SEQ_READ is used to hint to the kernel that the application will sequentially read this virtual memory area. The kernel will decide to pre-read the subsequent number of memory pages based on the actual situation in order to speed up the next sequential access.

The setting of VM_RAND_READ will indicate to the kernel that the application will randomly read this virtual memory area, and the kernel will reduce the number of memory pages read ahead or even stop reading ahead according to the actual situation.

To sum up, vm_flags defines the access rights and behavior specifications of the entire virtual memory area. The smallest unit of memory in the memory area is page (4K). The virtual memory area contains many such virtual pages. For the virtual memory area VMA The set access rights are also copied to the memory pages contained in the region.

For a detailed analysis of the remaining members of the vm_area_struct structure, please see the next chapter.

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. CS entry skill treeLinux introductionFirst introduction to Linux38100 people are learning the system