I. Inside the kmalloc Function
The use of kmalloc is familiar. Its function prototype is:
1: #include <linux/slab.h>
2: void *kmalloc(size_t size, int flags);
The size indicates the size of the block to be allocated, and flags indicates the allocation. The two parameters are described in detail below:
* Size parameter
In fact, the minimum memory size allocated by nuclear energy is not arbitrary, but a predefined, fixed-size byte array. Linux creates a series of Memory Object pools, and the memory blocks in each pool are fixed and consistent. Therefore, the size of the applied memory may be larger than the size. The maximum size is 2 * size. In addition, the minimum memory block that kmalloc can process is 32 or 64, depending on the page size used by the architecture. Kmalloc should not allocate memory larger than kb.
* Flags Parameters
The most common identifier is gfp_kernel and gfp_atomic. The second is _ gfp_dma and _ gfp_highmem. Here, the concept of "green" is "get free page. The difference between gfp_kernel and gfp_atomic is that the former is used in the process context, and the latter is used outside the process context, such as the interrupt context. Therefore, the former may cause the process to sleep when there is no idle memory, while the latter cannot sleep.
Ii. lookaside Cache)
Linux high-speed cache management is implemented through the slab distributor. The high-speed cache implemented through slab has the kmem_cache_t type. The created function is as follows. This function is different from the book in 2.6.32 kernel. 2.6.32 is used for analysis here:
1: #include <linux/slab.h>
2: struct kmem_cache *kmem_cache_create (const char *name, size_t size, size_t align, unsigned long flags,
void (*ctor)(void *))
The parameters in the function have the following meanings:
* Name: the cache string is identified in/proc/slabinfo. Use cat slabinfo in the/proc directory to view the existing cache.
* Size: the size of each memory object in the cache.
* Align: Make sure that the allocated objects are in a special align.
* Flags: flags are allocated. There are mainly the following bit masks (the ones marked as debug are available only when config_slab_debug is set ):
1: #define SLAB_DEBUG_FREE 0x00000100UL /* DEBUG: Perform (expensive) checks on free */
2: #define SLAB_RED_ZONE 0x00000400UL /* DEBUG: Red zone objs in a cache */
3: #define SLAB_POISON 0x00000800UL /* DEBUG: Poison objects */
4: #define SLAB_HWCACHE_ALIGN 0x00002000UL /* Align objs on cache lines */
5: #define SLAB_CACHE_DMA 0x00004000UL /* Use GFP_DMA memory */
6: #define SLAB_STORE_USER 0x00010000UL /* DEBUG: Store the last owner for bug hunting */
7: #define SLAB_PANIC 0x00040000UL /* Panic if kmem_cache_creat() fails*/
* Ctor is the constructor of memory objects.
After the cache is created, you can call the kmem_cache_alloc function to allocate memory. to release a memory object, call the kmem_cache_free function. To release a cache, call the kmem_cache_destroy function. Note the differences between cache and memory objects. In addition, if the memory objects allocated in the cache are not all released, releasing the cache will fail, which will cause memory leakage. Therefore, the device driver must check the returned status of kmem_cache_destroy.
3. get_free_page and related functions
When you need to allocate a large block of memory, instead of using kmalloc, you should use get_free_page to allocate the entire page. The related functions are as follows:
1: get_zeroed_page (unsigned int flags); // allocates a page, returns a pointer to the page, and clears the page
2: _ get_free_page (unsigned int flags); // allocates a page and returns a pointer to the page, but is not cleared.
3: _ get_free_pages (unsigned int flags, unsigned int order);/* returns the pointer to the first byte in the memory area, not cleared */
The function for releasing the Memory Page is as follows:
1: void free_page(unsigned long addr);
2: void free_pages(unsigned long addr, unsigned long order);
Iv. vmalloc and its auxiliary functions
Vmalloc is used to allocate contiguous regions of virtual address space. Although physical disconnections may occur, the kernel considers them as consecutive addresses. The related functions are as follows:
1: #include <linux/vmalloc.h>
2: void *vmalloc(unsigned long size);
3: void vfree(void *addr);
4: void *ioremap(unsigned long offset, unsigned long size);
5: void iounmap(void *addr);
5. Per-CPU variable, the following content is from http://blogold.chinaunix.net/u/12325/showart.php? Id = 1274548
1. Introduction
2.6 kernel features, each processor has its own variable copy.
2. Advantages
Each processor can access its own copy without locking and can be put into its own cache, greatly improving the access and update efficiency. Commonly Used in counters.
3. Use
Related header files: <Linux/percpu. h>
(1) allocation during compilation
Statement:
Define_per_cpu (type, name );
To prevent a process from being switched to another processor when accessing a per-CPU variable or being preemptible by other processes:
Get_cpu_var (variable) ++;
Put_cpu_var (variable );
Use this macro to access the variable copies of Other Processors:
Per_cpu (variable, int cpu_id );
(2) Dynamic Allocation and release
Dynamically allocate per-CPU variables:
Void * alloc_percpu (type );
Void * _ alloc_percpu (size_t size, size_t align); // you can specify memory alignment.
Release the dynamically allocated per-CPU variable:
Free_percpu ();
Access to the dynamically allocated per-CPU variable is completed through per_cpu_ptr:
Per_cpu_ptr (void * per_cpu_var, int cpu_id );
To block preemption, use get_cpu () and put_cpu:
Int CPU = get_cpu ();
PTR = per_cpu_ptr (per_cpu_var, CPU );
Put_cpu ();
(3) export the per-CPU variable to the module
Export_per_cpu_symbol (per_cpu_var );
Export_per_cpu_symbol_gpl (per_cpu_var );
To access such a variable in the module, we should declare it as follows:
Declare_per_cpu (type, name );
4. Note
In some architectures, the address space available for per-CPU variables is limited, so keep these variables as small as possible.
5. Per-CPU variable implementation
Each CPU has a corresponding proprietary data zone. In start_kernel (), call setup_per_cpu_areas () for allocation and initialization. Access the per-CPU variable through the first address and offset of the Data zone.