[Turn] kernel memory allocation: kmalloc, vmalloc, kzalloc, kcalloc, get_free_pages

Transfer: https: //www.cnblogs.com/yfz0/p/5829443.html

Kernel module for allocation of memory requires the use of special kernel API: kmalloc, vmalloc, kzalloc, kcalloc, get_free_pages; of course, the device driver is no exception;
for Providing MMU function processor, Linux offers complex memory management system, so that the process can access to 4GB of address space can be reached; 4GB space which has been divided into two parts: the regions 0GB ~ 3GB (PAGE_OFFSET, x86 is the value 0xC0000000) process is used user space region is used 3GB ~ 4GB kernel space;
in kernel space, using this address from the area between the physical vmalloc_start 3GB to memory mapped region, the inner region comprises a core segment map image, the physical page frame table mem_map and so on, for example, we use the system's physical memory is 160MB, then, 3GB ~ 3GB + region between vmalloc_start physical memory should be mapped; after the physical memory mapped area, is the virtual memory vmalloc area; for 160MB For a system, the position should be in the vicinity of vmalloc_start 3GB + 160MB position (between physical memory mapped region vmalloc_start there is a position of 8M g ap to prevent cross-border), vmalloc_end 4GB position close to the position (the area size will be retained in a specific page mapping 128KB at the last position);
a, kmalloc
#include <Linux / slab.h>
static inline void * kmalloc (size_t size, gfp_t flags);
parameters: size: Specifies the size of the block to be allocated, in bytes; flags: the specified control mode memory allocation;
this function is used to allocate memory space in the kernel, it is returned speed (unless blocked), and its memory allocation without any initializing (clearing) operations, the allocated memory area still retains his original content;
kmalloc application to obtain the physical memory, located in the physical memory map region, but is continuous in physical address; however kmalloc return memory address is a virtual address (linear address), and returns the virtual address (linear address) transactions differ only fixed offset value between a physical address; Accordingly, there is a relatively simple conversion between the virtual address of the first application is kmalloc physical address of the memory block its return; virt_to_phys function provided by kernel () may be implemented the conversion between the virtual address to the real kernel physical address:
#define __pa (X) ((unsigned Long) (X) -PAGE_OFFSET)
static inline unsigned Long virt_to_phys (volatile void * address)
{
 return __pa (address);
}
address is a virtual address parameter kmalloc returned; the conversion process is the virtual address minus 3GB (PAGE_OFFSET = 0xC0000000);
in general, PAGE_OFFSET = 3 * 1024 * 1024 * 1024 = 0xC0000000 (3G);
function corresponding thereto is phys_to_virt () for converting a virtual address to a physical address kernel:
#define __va (X) ((void *) ((unsigned Long) (X) + PAGE_OFFSET))
static inline * phys_to_virt void (unsigned Long address)
{
 return __va (address);
}
These two functions are defined in the include / asm-i386 / io.h in;
kmalloc () function is used to apply small memory Memory, the minimum application can be 32 or 64 bytes, the maximum memory that may apply 128KB-16, which is subtracted the 16 bytes for storing the page descriptor structure; they are dependent on page size used in the architecture; kmalloc memory application is continuous in physical address, it should be for DMA transfer device, it is very important;
kmalloc () memory allocation mechanism is implemented based on the slab, slab mechanism is an efficient mechanism for providing small memory allocated; however slab mechanism is not independent, it on the basis of the page itself is divided up distributor for more fine-grained memory used by the caller; that is, the system first continuous physical address of the page allocator smallest unit of a page, then, kmalloc () and then on this basis the need for the caller segmentation; Further, the slab mechanism for allocating memory in a virtual address and a physical address (linear address / logical address) are continuous;
for memory kmalloc () application, use kfree () function to release ;
Remarks: kmalloc mechanism is implemented based slab;
two, get_free_pages
#include <ASM / pages.h>
fastcall, unsigned Long __get_free_pages (gfp_t gfp_mask, unsigned int Order)
{
 struct Page Page *;
 Page alloc_pages = (gfp_mask, Order);
 IF (! Page)
  return 0;
 return (unsigned Long) page_address (Page);
}
Parameters gfp_mask control mode is specified for memory applications, order for the application to specify the number of pages; it is located in the application memory (PAGE_OFFSET, HIGH_MEMORY) between;
__get_free_pages () function is provided to the bottom of the page distributor caller memory allocation function, memory which the application is contiguous physical memory, is also located in the physical memory map area; it is buddy mechanism based implementation; using buddy mechanisms to achieve physical memory management system, the smallest allocation granularity (unit) is in units of pages; __get_free_pages in () internal to allocate physical memory pages by calling alloc_pages ();
__get_free_page () function to allocate physical memory is continuous, a continuous process is a physical address, but also return virtual address ( linear address); If you want to get the proper physical addresses is also required virt_to_phys () can be switched;
for memory __get_free_pages () function of the application, require the use of __free_pages () function to release;
Note: __ get_free_pages mechanism is based on buddy implementation;
three, vmalloc
#include <Linux / vmalloc.h>
void * vmalloc (unsigned Long size)
{
 return __vmall OC (size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
}
void * __vmalloc (unsigned Long size, gfp_t gfp_mask, pgprot_t Prot)
{
 return __vmalloc_node(size, gfp_mask, prot, -1);
}
void* __vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot, int node)
{
 struct vm_struct *area;
 size = PAGE_ALIGN(size);
 if(!size || (size >> PAGE_SHIFT) > num_physpages)
   return NULL;
 area = get_vm_area_node(size, VM_ALLOC, node);
 if(!area)
   return NULL;
 return __vmalloc_area_node(area, gfp_mask, prot, node);
}
void* __vmalloc_area_node(struct vm_struct* area, gfp_t gfp_mask, pgprot_t prot, int node);
void* __vmalloc_area(struct vm_struct* area, gfp_t gfp_mask, pgprot_t prot)
{
 return __vmalloc_area_node(area, gfp_mask, prot, -1);
}
vmalloc () function is also used for memory applications, but its application is located in the memory to the virtual memory vmalloc_start between VMALLOC_END; its application memory on a virtual address (linear address / logical address) is continuous, but not required in the continuous physical address, and not between the return addresses and physical addresses of the simple conversion relationship;
vmalloc () function works in the application environment of the large memory; application, but the memory can not be directly used for its DMA transfer; for DMA transfer requiring a physical address of contiguous memory blocks;
for memory vmalloc () application, use vfree () function to release;
NOTE: vmalloc based slab mechanism implemented;
IV Comparative
1) .kmalloc / __ get_free_pages allocated memory blocks in physical memory mapping area, i.e. between the (PAGE_OFFSET, hIGH_MEMORY), the processing is a physical address, and guaranteed to be contiguous in the physical address space; both virtual addresses are returned, if necessary to obtain the correct physical address , required virt_to_phys () conversion; however, kmalloc and vmalloc bytes are to apply, and __get_free_pages () is based on a single page Apply;
2) memory blocks .vmalloc function for the virtual memory mapping area is located, i.e. (VMALLOC_START, VMALLOC_END) between virtual memory are processed, and to ensure that the virtual address space is continuous, but the physical address space requirements are not continuous; Fair exchange region, memory usage module;
. 3) are based slab vmalloc .kmalloc and implementation mechanism, but faster than kmalloc vmalloc speed; __ get_free_pages mechanism is implemented based on buddy, speed faster;
4) .kmalloc small memory for application, generally, a memory block size can be between the application (32/64 bytes, 128KB-16); and vmalloc allocated chunk of memory may be used for the case;
5) .kmalloc application memory block in the physical address space is a continuous block of memory so that it may be used directly in applications DMA transfer; continuous block of memory, but does not require the physical address space in the virtual address space of the application vmalloc continuous block of memory so that the application can not be directly used for DMA transfer;
. 6) with a memory block .kmalloc kfree release applications; vfree release vmalloc memory block with the application; __ get_free_pages application memory page with __free_pages;
. 7) .kmalloc application is called the kernel address logical address, the address of application is referred vmalloc kernel virtual address;
V. other functions
1) .static inline void * kzalloc ( size_t size, gfp_t flags);
 this function is more than a feature kmalloc, application will initialize memory block is obtained is 0;
2) .static kcalloc inline void * (n-size_t, size_t size, gfp_t the flags)
   {
     IF (n-size = 0 &&> ULONG_MAX are / n-)!
        return NULL;
     return kzalloc ( n * size, the flags);
   }
   This function is used to apply a memory array, and applying the resulting memory is initialized to 0;
six, the GFP marker
kmalloc, kzalloc, kcalloc, vmalloc, get_free_pages function when a call has the flags gfp_t type control flag; this flag is used when controlling the memory allocation for memory control; #include <Linux / gfp.h>
the GFP labeled with in two ways: with a double underscore prefix and without double underscore prefix;
GFP sign without double underscore prefix:
GFP_ATOMIC: interruption for other code outside of the context and the context of the process of allocating memory; never sleep;
GFP_KERNEL: kernel properly allocate memory; may sleep;
GFP_USER: page for a user to allocate memory space; may sleep;
GFP_HIGHUSER: as GFP_USER, but it is to apply from high memory;
GFP_NOIO and GFP_NOFS: function as GFP_KERNEL, but Talia to increase the limit the kernel can do to satisfy the request; GFP_NOFS allocation does not allow any file system calls, and GFP_NOIO allocation did not allow any IO initialization; Talia is mainly used for file system and virtual memory code that allows a distribution sleep there, but recursive file system calls would be a bad idea;
GFP flag with a double underscore prefix:
__GFP_DMA: this Flags required memory area in the allocated memory capable of DMA; platform-dependent;
__GFP_HIGHMEM: This flag indicates the allocated memory may be located in the upper memory area; platform-dependent;
__GFP_COLD: Normally, trying to return to the memory allocator "buffer hot" page --- that might be found in the processor buffer page; the contrary, this flag requests a "cold" page --- page has not been used for some time; it has to do DMA read allocation page is useful, this It occurs when the processor is useless in the buffer;
__GFP_NOWARN: This flag stop when allocating memory for the kernel warning when an allocation request can not be met;
__GFP_HIGH: This flag identifies a high-priority request, it is allowed to consume even the kernel reserved for emergencies last memory page;
__GFP_REPEAT: distributor of motion; when the dispenser is difficult to satisfy when an allocation request, by way of repeated attempts to "try to try", but distribution operation is still likely to fail;
__GFP_NOFAIL: action dispenser; when the dispenser is difficult to meet when an allocation request, this flag tells the distributor do not fail, do our best to satisfy the allocation request;
__GFP_NORETRY: action distributor; when the dispenser is difficult to satisfy an allocation request, this flag tells the distributor immediately give up, no longer do any attempts;
typically, double-underlined prefixes with one or more bands or markers, to obtain the corresponding numerals without double underscore prefix; the
most commonly used marker is GFP_KERNEL, it means that the current running in kernel space allocated on behalf of the process carried out; in other words, this means that the function is invoked on behalf of Process calls in the implementation of a system; use GFP_KERNEL mark, it means that the current process can kmalloc in the case of less memory to wait for a memory page by sleep; therefore, a function GFP_KERNEL use must be reentrant, and can not running in atomic context; when the current process of sleep, the kernel take corrective action to locate some free memory page, or by flushing the cache to disk or swap out a user process's memory pages;
if a memory allocation action occurs in the interrupt processing, or when the timer in the kernel context, the current process can not be set to sleep, you can no longer use GFP_KERNEL mark, and this time should be used GFP_ATOMIC flag instead; normally, the kernel tries to keep some free pages in order to satisfy the allocation atoms ; when GFP_ATOMIC flag, kmalloc logo can use even the last free page; if this last free page does not exist, that allocation will fail;

Guess you like

Origin www.cnblogs.com/eleclsc/p/11531589.html