Slab原理及实现
-
整体关系图
注:SLAB,SLOB,SLUB都是内核提供的分配器,其前端接口都是一致的,其中SLAB是通用的分配器,SLOB针对微小的嵌入式系统,其算法较为简单(最先适配算法),SLUB是面向配备大量物理内存的大规模并行系统,通过也描述符中未使用的字段来管理页组,降低SLUB本身数据结构的内存开销。
1
-
相关数据结构
2.1缓存kmem_cache (/mm/slab.c)
structkmem_cache { structarray_cache *array[NR_CPUS]; unsignedint batchcount;//从本地高速缓存交换的对象的数量 unsignedint limit;//本地高速缓存中空闲对象的数量 unsignedint shared;//是否存在共享CPU高速缓存 unsigned int buffer_size;//对象长度+填充字节 u32reciprocal_buffer_size;//倒数,加快计算
unsignedint flags;/*高速缓存永久性的标志,当前只CFLGS_OFF_SLAB*/ unsignedint num;/*封装在一个单独的slab中的对象数目*/ unsigned int gfporder;/*每个slab包含的页框数取2为底的对数*/
gfp_tgfpflags;/* e.g. GFP_DMA分配页框是传递给伙伴系统的标志*/ size_tcolour; /* cache colouring range缓存的颜色个数free/aln*/
unsignedint colour_off; /*slab的基本对齐偏移,为aln的整数倍,用来计算left_over*/
structkmem_cache *slabp_cache; //slab描述符放在外部时使用,其指向的高速缓存来存储描述符 unsignedint slab_size;//单个slab头的大小,包括SLAB和对象描述符 unsignedint dflags; /*描述高速缓存动态属性,目前没用*/
/*构造函数*/ void(*ctor)(struct kmem_cache *, void *); constchar *name; structlist_head next;//高速缓存描述符双向链表指针
/*统计量*/ #ifSTATS unsignedlong num_active; unsignedlong num_allocations; unsignedlong high_mark; unsignedlong grown; unsignedlong reaped; unsignedlong errors; unsignedlong max_freeable; unsignedlong node_allocs; unsignedlong node_frees; unsignedlong node_overflow; atomic_tallochit; atomic_tallocmiss; atomic_tfreehit; atomic_tfreemiss; #endif #ifDEBUG intobj_offset;//对象间的偏移 intobj_size;//对象本身的大小, #endif //存放的是所有节点对应的相关数据。每个节点拥有各自的数据; structkmem_list3 *nodelists[MAX_NUMNODES];/ } |
2.2array_cache本地高速缓存,每个CPU对应一个该结构
/* * struct array_cache * *Purpose: * - LIFO ordering, to hand out cache-warm objectsfrom _alloc * - reduce the number of linked list operations * - reduce spinlock operations * * The limit is stored in the per-cpu structure toreduce the data cache * footprint. * */ struct array_cache { unsigned int avail;//可用对象数目 unsigned int limit;//可拥有的最大对象数目,和kmem_cache中一样 unsigned int batchcount;//同kmem_cache unsigned int touched;//是否在收缩后被访问过 spinlock_t lock; void *entry[]; /*伪数组,没有任何数据项,其后为释放的对象指针数组*/ }; |
2.3kmem_list3管理slab链表的数据结构
/* * The slab lists for all objects. */ struct kmem_list3 { struct list_head slabs_partial; /* partial listfirst, better asm code */ struct list_head slabs_full; struct list_head slabs_free; unsigned long free_objects;//半空和全空链表中对象的个数 unsigned int free_limit;//所有slab上允许未使用的对象最大数目 unsigned int colour_next; /* 下一个slab的颜色*/ spinlock_t list_lock; struct array_cache *shared; /* shared per node */ struct array_cache **alien; /* on other nodes */ unsigned long next_reap; /* 两次缓存收缩时的间隔,降低次数,提高性能*/ int free_touched; /* 0收缩1获取一个对象*/ }; |
2.4slab对象