当前位置: 首页 > Linux kernrl, 内存管理 > 正文

内存管理器(十七)kernel内存管理—-slab设计与实现(分配对象)

内存管理器(十七)kernel内存管理—-slab设计与实现(分配对象)

前言

上一篇主要写了slab的初始化与创建一个高速缓存。这一篇主要分析slab 是如何分配对象的。

void * kmem_cache_alloc(kmem_cache_t *cachep,gfp_t flags)  这个是主要分析的对象。

__start


/**
* kmem_cache_alloc - Allocate an object  分配一个对象
* @cachep: The cache to allocate from.   从哪一个缓存区分配
* @flags: See kmalloc().  ...这注释真是醉了,不过没关系,我在前边分析数据结构的时候已经分* 析过了,没看过的小伙伴去看看吧。
*
* Allocate an object from this cache. The flags are only relevant 分配一个对象从这个缓存区,如果没有空闲的对象那么这个标识也没有什么用。
* if the cache has no available objects.
*/
void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
{
   void *ret = slab_alloc(cachep, flags, _RET_IP_);

   trace_kmem_cache_alloc(_RET_IP_, ret,
       cachep->object_size, cachep->size, flags);
   /*一个追踪函数,调试时使用*/
   return ret;
}
EXPORT_SYMBOL(kmem_cache_alloc);


static __always_inline void *
slab_alloc(struct kmem_cache *cachep, gfp_t flags, unsigned long caller)
{
    unsigned long save_flags;
    void *objp; /*分配目标*/

    flags &= gfp_allowed_mask;

    lockdep_trace_alloc(flags); /*一个追踪函数*/

    if (slab_should_failslab(cachep, flags))  /*检查这个指定的标志,是否会导致不可分配*/
     return NULL;

    cachep = memcg_kmem_get_cache(cachep, flags);  /* 这个函数看下边第一个函数*/

    cache_alloc_debugcheck_before(cachep, flags);/*这个函数由两个作用:1:将标志设置为可以等待的(__GFP_WAIT).2:如果定义了调试(if DEBUG)用来调试标记
    local_irq_save(save_flags);/*本地中断中态保存保存*/
    objp = __do_cache_alloc(cachep, flags); /*分配主要函数,看下边有详解*/
    local_irq_restore(save_flags); /*恢复本地中断*/
    objp = cache_alloc_debugcheck_after(cachep, flags, objp, caller);/*DEBUG*/
    kmemleak_alloc_recursive(objp, cachep->object_size, 1, cachep->flags,flags);
    prefetchw(objp);

    if (likely(objp)) {
        kmemcheck_slab_alloc(cachep, flags, objp, cachep->object_size);
    if (unlikely(flags & __GFP_ZERO))
        memset(objp, 0, cachep->object_size);
    }

    memcg_kmem_put_cache(cachep);
        return objp;
}

各个函数分析

1.memcg_kmem_get_cache( )


/**
* memcg_kmem_get_cache: selects the correct per-memcg cache for allocation 从per-memcg 中选择一个正确的高* * 速缓存来分配内存
* @cachep: the original(原始) global kmem cache ;全局的缓存链表节点,双向循环链表可以从任意一个结点* 到任意的地方
* @gfp: allocation flags. 分配的标识
*
* All memory allocated from a per-memcg cache is charged to the owner memcg.
*/
static __always_inline struct kmem_cache *
memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp)
{
    if (!memcg_kmem_enabled()) /*当有如下四种情况的时候直接返回*/
        return cachep;
    if (gfp & __GFP_N