Principle of slab mechanism

Slab acquisition-the most efficient acquisition method

Allocating and freeing data structures is one of the most common operations in all kernels. In order to facilitate the frequent allocation and recovery of data, a space linked list is often used. It is equivalent to an object cache to quickly store frequently used object types. In the kernel, one of the main problems facing the free list is that it cannot be controlled globally. When the available memory becomes tight, the kernel cannot notify each free list to shrink the size of the cache in order to release some memory. In fact, the kernel has no idea that there is such a free offshore. In order to make up for this defect and to make the code more stable, the Linux kernel provides a slab layer (the so-called slab classifier), and the slab classifier plays the role of a general data structure cache layer. The slab distributor tries to find a balance among the following principles:

1. Frequently used data structures are also frequently allocated and released, so they should be cached.

2. Frequent allocation and recovery will inevitably lead to memory fragmentation. In order to avoid this situation, the cache of the free linked list will be stored continuously. Because the released data structure will be put back into the free list, it will not cause fragmentation. 3. The recovered objects can be immediately put into the next allocation, therefore, for frequent allocation and release, the free list can improve its performance. 4. If part of the cache is dedicated to a single processor, then allocation and release can be performed without SMP locks. 5. Color the stored objects to prevent multiple objects from being mapped to the same cache line.

The slab layer divides different objects into so-called cache groups, where each cache stores different types of objects, and each object type corresponds to a cache. The kmalloc() interface is built on the slab layer and uses a set of general-purpose caches. These caches are divided into slabs. The slab is composed of one or more physically continuous pages. In general, the slab is composed of only one page. Each cache can be composed of multiple slabs. Each slab contains some object members. The object here refers to the data structure being cached. Each slab is in one of three states: full, partially full, and empty. When a certain part of the kernel needs a new object, first allocate it from the partially full slab. If there is no partially full slab, it will be allocated from the empty slab. If there is no empty slab, a slab must be created.

slab allocation mechanism

The slab allocator is managed based on objects. The so-called objects are the data structures in the kernel (for example: task_struct, file_struct, etc.). Objects of the same type are classified into one category. Whenever applying for such an object, the slab allocator allocates a unit of this size from a slab list, and when it is to be released, it will be saved in the list again. Instead of returning directly to the partner system, thereby avoiding internal fragmentation. The slab allocator does not discard the allocated objects, but releases and saves them in memory. When slab allocates an object, it will use the memory block of the most recently released object, so the probability of it staying in the cpu cache will be greatly improved.

The main data structure of slab in the kernel

Insert picture description here

Briefly analyze the following figure: kmem_cache is a linked list of cache_chain, describing a cache, each cache contains a list of slabs, which is usually a continuous memory block. There are three kinds of slabs: slabs_full (fully allocated slab), slabs_partial (partially allocated slab), slabs_empty (empty slab, or no object is allocated). The slab is the smallest unit of the slab distributor. In the implementation, a slab consists of one or more consecutive physical pages (usually only one page). A single slab can be moved between the slab linked lists. For example, if a half-full slab becomes full after being allocated an object, it will be deleted from slabs_partial and inserted into slabs_full at the same time.

Principle of slab layer realization

The cache in linux is realized by the so-called slab layer, which is the mechanism for managing the cache in the kernel.

The principle of the entire slab layer is as follows:

The cache of various objects can be established in the memory (such as the cache of task_struct related to the process description).
In addition to the cache for specific objects, there are also caches for general objects.
Each cache contains multiple slabs, which are used by slabs. The object
slab used to manage the cache contains multiple cached objects, which are physically composed of one or more consecutive pages
. The relationship between cache->slab->cache objects is as follows:

Insert picture description here

Application of slab layer

For the definition of slab structure, see:

struct slab {
    
    
    struct list_head list;   /* 存放缓存对象,这个链表有 满,部分满,空 3种状态  */
    unsigned long colouroff; /* slab 着色的偏移量 */
    void *s_mem;             /* 在 slab 中的第一个对象 */
    unsigned int inuse;         /* slab 中已分配的对象数 */
    kmem_bufctl_t free;      /* 第一个空闲对象(如果有的话) */
    unsigned short nodeid;   /* 应该是在 NUMA 环境下使用 */
};

There are four main methods for the application of the slab layer:

Cache creation
Allocate objects
from the cache Release objects to the
cache Destruction of the cache

/**
 * 创建高速缓存
 */
struct kmem_cache *
kmem_cache_create (const char *name, size_t size, size_t align,
    unsigned long flags, void (*ctor)(void *))

/**
 * 从高速缓存中分配对象
 * @cachep - 指向高速缓存指针
 * @flags  - 之前讨论的 gfp_mask 标志,只有在高速缓存中所有slab都没有空闲对象时,
 *           需要申请新的空间时,这个标志才会起作用。
 *
 * 分配成功时,返回指向对象的指针
 */
void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)

/**
 * 向高速缓存释放对象
 * @cachep - 指向高速缓存指针
 * @objp   - 要释放的对象的指针
 */
void kmem_cache_free(struct kmem_cache *cachep, void *objp)

/**
 * 销毁高速缓存
 * @cachep - 指向高速缓存指针 
 */
void kmem_cache_destroy(struct kmem_cache *cachep)

Insert picture description here

[Article benefits] The editor recommends my own Linux and C/C++ technical exchange group: [960994558] I have compiled some learning books and video materials that I think are better for sharing (including C/C++, Linux, Nginx, ZeroMQ, MySQL) , Redis, fastdfs, MongoDB, ZK, streaming media, CDN, P2P, K8S, Docker, TCP/IP, coroutine, DPDK, etc.), you can add it yourself if you need it! ~

Guess you like

Origin blog.csdn.net/weixin_52622200/article/details/110875673