linux slab精细结构

来源:互联网 发布:中国企业数据 编辑:程序博客网 时间:2024/05/22 00:02

1. 数据结构




上面是用visio画的slab缓存的结构示意图,而且对标出了slab结构的成员的含义以及kmem_cache的主要成员的含义。看看如何从slab中获取对象,由上图可以清晰的看到,slab中的对象获取应该是通过free成员和bufctl数组中的索引来取得对象,从索引到对象转换通过s_mem偏移来确定:
static inline void *index_to_obj(struct kmem_cache *cache, struct slab *slab, unsigned int idx){return slab->s_mem + cache->buffer_size * idx;}
static inline unsigned int obj_to_index(const struct kmem_cache *cache,const struct slab *slab, void *obj){u32 offset = (obj - slab->s_mem);return reciprocal_divide(offset, cache->reciprocal_buffer_size);}
确实slab就是这么获取对象。
下面来看看如何从kmem_cache中分配对象,从kmem_cache分配对象的过程从上面的图以及注释中应该就可以看出的,kmem_cache中的缓存是array成员,这是一个per-cpu数组,如果说slab是对象的二级缓存,那array算是对象的一级缓存,分配对象应该就是先从当前cpu对应的array中取对象,若array中没有对象了,再从slab中取出batchcount个对象来填充array。基本流程应该是这样的,下面看看内核源码是不是这样的,下面这个函数分配对象的后台:
static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags){void *objp;struct array_cache *ac;check_irq_off();ac = cpu_cache_get(cachep); //从kmem_cache中获得当前cpu的arrayif (likely(ac->avail)) {STATS_INC_ALLOCHIT(cachep);ac->touched = 1;objp = ac->entry[--ac->avail]; //获得对象的指针并且将可以对象个数减1} else {STATS_INC_ALLOCMISS(cachep);objp = cache_alloc_refill(cachep, flags); //没有可用对象,则重新填充array/* * the 'ac' may be updated by cache_alloc_refill(), * and kmemleak_erase() requires its correct value. */ac = cpu_cache_get(cachep);}/* * To avoid a false negative, if an object that is in one of the * per-CPU caches is leaked, we need to make sure kmemleak doesn't * treat the array pointers as a reference to the object. */if (objp)kmemleak_erase(&ac->entry[ac->avail]);return objp;}
注释标出了分配内存的基本步骤,从slab和kmem_cache的两张图中应该就可以明白大部分的。释放对象基本上就是反过来的过程,多检查几个limit标志即可。



原创粉丝点击