[Linux] slab allocator introduced

Introduction slab allocator

Dynamic Memory Management

Memory management goal is to provide a method for achieving various purposes to implement memory shared among various users. Memory management method should achieve the following two functions:

  • Minimize the time required to manage memory
  • Available memory (minimize management overhead) is maximized for general applications

Memory management is actually a zero-sum game about the trade-offs. You can use a small amount of memory for the development of a management algorithms, but it takes more time to manage the available memory. You can also develop an algorithm to efficiently manage memory, but uses more memory. Ultimately, the needs of a particular application will lead to the selection of such trade-offs.

Each memory manager uses a heap-based allocation strategy. In this method, large memory (referred to as  stack ) memory is used to provide user-defined purposes. When the user needs a memory, on his own request to allocate a certain amount of memory. The heap manager looks at the case of available memory (using a specific algorithm) and returns a block of memory. Some search algorithms are used during  First-Fit (heap memory block searched to satisfy the request of the first), and  Best-Fit (heap to satisfy the request using the most suitable memory block). After the user finished using the memory, the memory will be returned to the heap.

This fundamental problem of heap-based allocation strategy is fragmentation (fragmentation) . When the memory block allocated, they are returned in a different order at different times. This will leave some holes in the heap, it takes some time to effectively manage the free memory. This algorithm generally have higher memory efficiency (need to allocate memory), but it takes more time to manage the heap.

Another method is called  Buddy Memory Allocation , a faster memory allocation techniques, the memory will be divided into a power of 2 partitions, and use the best-fit method for allocating memory request. When the user releases the memory block buddy checks to see if its adjacent memory blocks have also been released. If so, the memory block to minimize the combined memory fragmentation. Higher time efficiency of the algorithm, but due to the use of best-fit method will produce wasted memory.

This article will focus on Linux kernel memory management, especially  slab allocation mechanisms.

slab cache

Foundation slab allocator used in Linux is an algorithm Jeff Bonwick for the SunOS operating system was first introduced. Jeff dispensers around the object cache of. In the kernel, allocates memory for the large finite set of objects (e.g. file descriptors and other common structures). Jeff ordinary objects found in the kernel time required to initialize more than the time required to be allocated and released. Therefore, he concluded that the memory should not be released back into a global pool of memory, but the memory will remain for a specific purpose and initialized state. For example, if the memory is assigned to a mutex, you only need to do when allocating memory for the first time a mutex mutex initialization function ( mutex_init) can be. No need to perform subsequent memory allocations this initialization function, because after release from the last and call the destructor, it is already in the desired state.

Linux slab allocator used this idea and other ideas to build in a space and time have efficient memory allocator.

Figure 1 shows a high-level organizational structure slab structure. At the top is  cache_chainthat this is a slab cache list of links. This is useful for best-fit algorithm can be used to find the most appropriate allocation of the required size of the cache (traversing the list). cache_chain Each element is a  kmem_cache reference structure (referred to as a  Cache ). It defines a given size to be managed object pool.

The main structure of the dispenser of FIG. 1. slab

The main structure of the dispenser of FIG. 1. slab

Each cache contains a  slabs  list, which is a contiguous block of memory (usually page). There are three slab:

slabs_full

Fully allocated slab

slabs_partial

Part of the allocation of the slab

slabs_empty

Empty slab, or no object is assigned

Note that  slabs_empty the list slab is recovered (Reaping) the main alternative object. It is through this process, slab used memory is returned to the operating system available to other users.

Each slab slab list is a contiguous block of memory (one or more consecutive pages), which is divided into one object. These objects are the basic elements of the allocation and release from a particular cache. Note slab slab allocator minimum allocation unit is operating, and therefore if the slab needs to be extended, which is the minimum extension. Typically, each slab is allocated to a plurality of objects.

Since the object is allocated and released from the slab, so that a single slab can be moved between a slab list. For example, when a slab of all the objects have been used up, it from  slabs_partial moving to the list  slabs_full in the list. When a slab with a fully allocated and the object is released it from  slabs_full moving to the list  slabs_partial in the list. Once all the objects have been released, it is from the  slabs_partial list to the slabs_empty list.

The motivation behind the slab

Compared with conventional memory management mode, slab cache allocator provides a number of advantages. First, the kernel is usually dependent on the allocation of small objects, they will be numerous distribution within the system life cycle. The slab cache allocator provides this functionality through an object similar to the size of the cache, thus avoiding the common problem of fragmentation. slab allocator also supports the initialization of a generic object, so as to avoid for the same purpose and to initialize an object repeated. Finally, the dispenser may also support the slab alignment hardware buffer and coloring, which allows different cache objects occupy the same cache line, thereby improving cache utilization and better performance.

API functions

Now look at the ability to create new slab caches, adding memory to the cache, the destruction of the cache application programming interface (API) function and object allocation and release operation of the slab.

The first step is to create slab cache structure, you can use it to create static:

1

struct struct kmem_cache *my_cachep;

Then the other slab cache functions will use the reference to create, delete, distribution and other operations. kmem_cache Each data structure contains a central processing unit (CPU), a group adjustable (proc file system can be accessed by) parameters, statistical information, and cache management slab essential element.

kmem_cache_create

Kernel function  kmem_cache_create used to create a new cache. This is usually performed when the kernel initialization or execution when it first loads the kernel modules. The prototype is defined as follows:

1

2

3

4

5

struct kmem_cache *

kmem_cache_create( const char *name, size_t size, size_t align,

                       unsigned long flags;

                       void (*ctor)(void*, struct kmem_cache *, unsigned long),

                       void (*dtor)(void*, struct kmem_cache *, unsigned long));

name Parameter defines the cache name, proc file system to use it to identify the cache (at / proc / slabinfo in). size Parameter specifies the objects created for the cache size  align parameter defines the necessary alignment of each object. flags Parameter specifies the option is enabled for the cache. These markers are shown in Table 1.

Table 1. kmem_cache_create Some options (specified in the flags parameter)

Options Explanation
SLAB_RED_ZONE The object header, the end flag is inserted to support check for buffer overflow.
SLAB_POISON The use of a known padding the slab, the cache allows for monitoring objects (objects all objects belong to, but can be modified externally).
SLAB_HWCACHE_ALIGN Specify the cache object must be aligned with the hardware cache line.

ctor And  dtor parameters define a selectable object constructors and destructors. Constructors and destructors user-supplied callback function. When allocating a new object from the cache may be initialized by the constructors.

After creating the cache,  kmem_cache_create the function returns a reference to it. Note that this function does not allocate any memory to cache. On the contrary, when attempting to allocate objects from the cache (initially empty), Refill  operation of memory allocated to it. When all objects have been used out, may be added to the cache memory by the same operation.

kmem_cache_destroy

Kernel function  kmem_cache_destroy is used to destroy the cache. This call is performed when being unloaded from the kernel module. When calling this function, the cache must be empty.

1

void kmem_cache_destroy( struct kmem_cache *cachep );

kmem_cache_alloc

From a named cache allocate an object, you can use  kmem_cache_alloc the function. The caller provides the cache as well as a set of flags from which to allocate an object:

1

void kmem_cache_alloc( struct kmem_cache *cachep, gfp_t flags );

This function returns an object from the cache. Note If the cache is currently empty, then this function is called  cache_alloc_refill to increase the memory to the cache. kmem_cache_alloc The flags options and  kmalloc the same option flags. Table 2 gives a partial list of flag options.

Table 2. kmem_cache_alloc and flag options kmalloc kernel function

Mark Explanation
GFP_USER Assigned to the user memory (this call may sleep).
GFP_KERNEL Allocate memory (this call may sleep) from the kernel RAM.
GFP_ATOMIC The call is cast in a non-sleep state (useful for interrupt handlers).
GFP_HIGHUSER Allocate memory from high memory.

kmem_cache_zalloc

Kernel functions  kmem_cache_zalloc with  kmem_cache_alloc similar, but it objects to perform  memset the operation, before the object is returned to the caller its cleanup.

kmem_cache_free

To release an object back slab, it can be used  kmem_cache_free. The caller provides an object cache and references to be released.

1

void kmem_cache_free( struct kmem_cache *cachep, void *objp );

kmalloc and kfree

The most common kernel memory management functions are  kmalloc and  kfree function. Prototype of these two functions are as follows:

1

2

void *kmalloc( size_t size, int flags );

void kfree( const void *objp );

Note that  kmalloc , the only two parameters are allocated to the object size and a set of flags (see  Table 2  part list). However,  kmalloc and  kfreeuse the previously defined function is similar to the slab cache. kmalloc Not to assign an object from which a slab cache name, but to find the cache cycle through available to meet the size limit of the cache. After finding it (using the  __kmem_cache_allocassignment of an object). To  kfree release the object from which the object cache can be allocated by calling  virt_to_cache OK. This function returns a reference to the cache, and then  __cache_free use the reference release the object call.

Other functions

slab cache API also provides some other useful functions. kmem_cache_size This function returns the size of the cache managed object. You can also call  kmem_cache_name to retrieve the given name cache (defined when creating the cache). Cache can be contracted by releasing them idle slab. This can be by calling  kmem_cache_shrink achieved. Note that this operation (referred to as recovery) is performed automatically at regular intervals by the kernel (by  kswapd).

1

2

3

unsigned int kmem_cache_size( struct kmem_cache *cachep );

const char *kmem_cache_name( struct kmem_cache *cachep );

int kmem_cache_shrink( struct kmem_cache *cachep );

slab cache usage example

下面的代码片断展示了创建新 slab 缓存、从缓存中分配和释放对象然后销毁缓存的过程。首先,必须要定义一个 kmem_cache对象,然后对其进行初始化(请参看清单 1)。这个特定的缓存包含 32 字节的对象,并且是硬件缓存对齐的(由标志参数 SLAB_HWCACHE_ALIGN 定义)。

清单 1. 创建新 slab 缓存

1

2

3

4

5

6

7

8

9

10

11

12

13

14

static struct kmem_cache *my_cachep;

 

static void init_my_cache( void )

{

 

   my_cachep = kmem_cache_create(

                  "my_cache",            /* Name */

                  32,                    /* Object Size */

                  0,                     /* Alignment */

                  SLAB_HWCACHE_ALIGN,    /* Flags */

                  NULL, NULL );          /* Constructor/Deconstructor */

 

   return;

}

使用所分配的 slab 缓存,您现在可以从中分配一个对象了。清单 2 给出了一个从缓存中分配和释放对象的例子。它还展示了两个其他函数的用法。

清单 2. 分配和释放对象

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

int slab_test( void )

{

  void *object;

 

  printk( "Cache name is %s\n", kmem_cache_name( my_cachep ) );

  printk( "Cache object size is %d\n", kmem_cache_size( my_cachep ) );

 

  object = kmem_cache_alloc( my_cachep, GFP_KERNEL );

 

  if (object) {

 

    kmem_cache_free( my_cachep, object );

 

  }

 

  return 0;

}

最后,清单 3 演示了 slab 缓存的销毁。调用者必须确保在执行销毁操作过程中,不要从缓存中分配对象。

清单 3. 销毁 slab 缓存

1

2

3

4

5

6

7

static void remove_my_cache( void )

{

 

  if (my_cachep) kmem_cache_destroy( my_cachep );

 

  return;

}

slab 的 proc 接口

proc 文件系统提供了一种简单的方法来监视系统中所有活动的 slab 缓存。这个文件称为 /proc/slabinfo,它除了提供一些可以从用户空间访问的可调整参数之外,还提供了有关所有 slab 缓存的详细信息。当前版本的 slabinfo 提供了一个标题,这样输出结果就更具可读性。对于系统中的每个 slab 缓存来说,这个文件提供了对象数量、活动对象数量以及对象大小的信息(除了每个 slab 的对象和页面之外)。另外还提供了一组可调整的参数和 slab 数据。

要调优特定的 slab 缓存,可以简单地向 /proc/slabinfo 文件中以字符串的形式回转 slab 缓存名称和 3 个可调整的参数。下面的例子展示了如何增加 limit 和 batchcount 的值,而保留 shared factor 不变(格式为 “cache name limit batchcount shared factor”):

1

# echo "my_cache 128 64 8" > /proc/slabinfo

limit Field indicates the maximum number of each CPU can be cached objects. batchcount When the field is empty the cache is converted to the maximum number of global cache per CPU cache object. shared Parameter specifies behavior shared symmetric multiprocessor (Symmetric MultiProcessing, SMP) system.

Note that you must have superuser privileges to tune parameters for the slab cache in the proc file system.

SLOB distributor

For small embedded systems, the presence of a slab emulation layer, called SLOB. The slab alternatives have advantages in small embedded Linux system, but even if it holds 512KB of memory, remain fragmented and difficult to extend question. Disabled  CONFIG_SLAB , the kernel will return to this SLOB dispenser. For more information see  the Resources  section.

Conclusion

slab allocator cache of source code in the Linux kernel is actually part of a better readability. In addition to the indirect function call, the source code is very intuitive, in general, has good notes. If you want to know more about the slab cache allocator, it is recommended that you start from the source code, because it is the latest documentation on this mechanism. The following  reference  section provides reference information on a slab cache allocator, but unfortunately for now achieve 2.6, these documents are obsolete.

Guess you like

Origin blog.csdn.net/bible_reader/article/details/91371064