Original:high-end memory mapping of Linux kernel notes
On a 32-bit system, the kernel uses the linear address space of section 3gb~ 4GB, a total of 1GB size. The kernel directly maps the first 896MB of the 0~896MB to the physical memory, which is a linear map that takes the remaining 128M linear address space as a window to access higher than 896M of memory.
The main reason for the introduction of high-end memory mapping is that when we install more than 1G of memory, the 1G linear address space of the kernel cannot establish a full direct mapping to reach the entire physical memory space, while for 80x86, the maximum allowable physical memory can reach 64G. So the kernel frees up its last 128M of linear address space to complete a temporary mapping of high-end memory.
There is no such problem on a 64-bit system because the available linear address space is much larger than the installable memory. Describes how the kernel 1GB linear address space is divided.
Where Page_offset represents the starting point of the 1GB linear address used by the kernel (3GB), and the high_memory to the right represents high-end memory, 128M
a common linear address. The areas that can be used to accomplish the above mapping purposes are vmalloc area,persistent kernel mappings region and the Fix_kmap area in the fixed map linear address space, which correspond to the mapping mechanism of the three regions, respectively 非连续内存分配
永久内核映射
临时内核映射
.
Permanent Kernel mappings
When the kernel initializes the page table management mechanism, it specifically uses the pkmap_page_table variable to save the address of the Pkmap_base corresponding page table entry, and the pkmap_page_table to maintain the mapping of the page table entries for the permanent kernel map, the total number of page table entries is Last_ A pkmap.
The permanence here is not that the mapping relationship established by calling Kmap () will persist, but that this mapping will persist between calling Kunmap () de-mapping, as opposed to the temporary kernel mapping mechanism.
It is important to note that when there are no idle page table entries available for mapping in the permanent kernel mapping area, the process that requests the mappings is blocked, so the persistent kernel mapping request cannot occur in interrupts and deferred functions.
Temporary kernel mappings
The most important feature of a temporary kernel mapping versus a permanent kernel mapping is that it does not block the process of requesting a mapped page box, so the temporary kernel mapping request can occur in interrupts and deferred functions. Each CPU in the system has its own 13 temporary kernel mapping windows, depending on the requirements (for the kernel control path), choose a different window to create the mapping. Each CPU's mapping window collection enum km_type
is represented by a data structure in which each symbol, such as KM_BOUNCE_READ
, KM_USER0
or KM_PTE0
, identifies the linear address of the window, which is actually a subscript. When you want the kernel to establish a temporary mapping, the cpu_id
窗口下标
linear address is determined by and.
The implementation of a temporary kernel mapping is also simpler than a permanent kernel mapping, when a process requests a window to create a map, even if the window has already been mapped before, the new map will be built and overwrite the previous mappings, so the mapping mechanism is temporary and does not block the current process.
Non-contiguous memory allocation
Discontinuous memory allocation refers to the mapping of a page box with a discontinuous physical address to a linear address continuous linear address space, which is primarily used for large-capacity memory allocations. The main advantage of allocating memory in this way is to avoid external fragmentation, and the disadvantage is that the kernel page table must be scrambled and the access speed is slower than the contiguous allocation of physical page frames.
The linear address space for a non-contiguous memory allocation is from the VMALLOC_START
to VMALLOC_END
, whenever the kernel wants to use the function of the Vmalloc class for non-contiguous memory allocation, it will apply for a vm_struct structure to describe the corresponding Vmalloc area, The interval between two vmalloc zones is at least the size of one page box, or page_size.
Summarize
Due to the limited linear address space of the kernel, there are three ways to map high-end memory using the above mentioned methods. But the essence of each mapping is to create a link between a linear address and a physical address through a page table.
Both the permanent kernel mapping and the temporary kernel mapping are specified by the kernel for the pages that need to be mapped, that is, the page descriptor is specified (the relationship between the page descriptor and the physical page box is fixed and immutable). In the permanent kernel mapping, the kernel only needs to find the idle, that is, the non-mapped linear address of the page table entry in the Permanent kernel mapping area, and then assign it to pages, if not found will block the request to establish the mapping process, and the temporary kernel mapping is more direct, even the linear address of the mapping window is fixed, If it has been assigned to a page box, then the direct grab to use, so the previous map is covered, reflecting the temporary.
Non-contiguous memory allocation, the kernel does not specify a specific page box, just specify the size of the memory to be requested, the kernel will find a corresponding size virtual address space in the non-contiguous memory allocation area, and then the partner system to allocate the page box, but also through the slab allocator for some data structures to allocate memory, and finally in the same way ( Set the PTE table entry) to establish the mapping.
"Reprint" high-end memory mapping of Linux kernel notes