免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1952 | 回复: 1
打印 上一主题 下一主题

Linux内存管理之slab机制(概述) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-01-12 12:01 |只看该作者 |倒序浏览
Linux内存管理之slab机制(概述)






通过前面所有代码的分析和总结,已经把各个部分熟悉了一遍,在此对Linux内核中slab机制做最后的总结。

伙伴系统算法采用页作为基本内存区,这适合于大块内存的请求。对于小内存区的申请,比如说几十或几百个字节,我们用slab机制。

Slab分配器把对象分组放进高速缓存。每个高速缓存都是同类型对象的一种“储备”。包含高速缓存的主内存区被划分为多个slab,每个slab由一个活多个连续的页组成,这些页中既包含已分配的对象,也包含空闲的对象。

1,cache对象管理器

Cache对象管理器为kmem_cache结构,如下:
  1. [cpp] view plaincopyprint?/*
  2. * struct kmem_cache
  3. *
  4. * manages a cache.
  5. */  
  6.   
  7. struct kmem_cache {  
  8. /* 1) per-cpu data, touched during every alloc/free */  
  9.     struct array_cache *array[NR_CPUS];/*local cache*/  
  10. /* 2) Cache tunables. Protected by cache_chain_mutex */  
  11.     unsigned int batchcount;  
  12.     unsigned int limit;  
  13.     unsigned int shared;  
  14.   
  15.     unsigned int buffer_size;/*slab中对象大小*/  
  16.     u32 reciprocal_buffer_size;/*slab中对象大小的倒数*/  
  17. /* 3) touched by every alloc & free from the backend */  
  18.   
  19.     unsigned int flags;     /* constant flags */  
  20.     unsigned int num;       /* # of objs per slab */  
  21.   
  22. /* 4) cache_grow/shrink */  
  23.     /* order of pgs per slab (2^n) */  
  24.     unsigned int gfporder;  
  25.   
  26.     /* force GFP flags, e.g. GFP_DMA */  
  27.     gfp_t gfpflags;  
  28.   
  29.     size_t colour;/*着色块个数*/ /* cache colouring range */  
  30.     unsigned int colour_off;/* cache的着色块的单位大小 */    /* colour offset */  
  31.     struct kmem_cache *slabp_cache;  
  32.     unsigned int slab_size;/*slab管理区大小,包含slab对象和kmem_bufctl_t数组*/  
  33.     unsigned int dflags;        /* dynamic flags */  
  34.   
  35.     /* constructor func */  
  36.     void (*ctor)(void *obj);  
  37.   
  38. /* 5) cache creation/removal */  
  39.     const char *name;  
  40.     struct list_head next;  
  41.   
  42. /* 6) statistics */  
  43. #ifdef CONFIG_DEBUG_SLAB   
  44.     unsigned long num_active;  
  45.     unsigned long num_allocations;  
  46.     unsigned long high_mark;  
  47.     unsigned long grown;  
  48.     unsigned long reaped;  
  49.     unsigned long errors;  
  50.     unsigned long max_freeable;  
  51.     unsigned long node_allocs;  
  52.     unsigned long node_frees;  
  53.     unsigned long node_overflow;  
  54.     atomic_t allochit;/*cache命中计数,在分配中更新*/  
  55.     atomic_t allocmiss;/*cache未命中计数,在分配中更新*/  
  56.     atomic_t freehit;  
  57.     atomic_t freemiss;  
  58.   
  59.     /*
  60.      * If debugging is enabled, then the allocator can add additional
  61.      * fields and/or padding to every object. buffer_size contains the total
  62.      * object size including these internal fields, the following two
  63.      * variables contain the offset to the user object and its size.
  64.      */  
  65.     int obj_offset;  
  66.     int obj_size;  
  67. #endif /* CONFIG_DEBUG_SLAB */   
  68.   
  69.     /*
  70.      * We put nodelists[] at the end of kmem_cache, because we want to size
  71.      * this array to nr_node_ids slots instead of MAX_NUMNODES
  72.      * (see kmem_cache_init())
  73.      * We still use [MAX_NUMNODES] and not [1] or [0] because cache_cache
  74.      * is statically defined, so we reserve the max number of nodes.
  75.      */  
  76.     struct kmem_list3 *nodelists[MAX_NUMNODES];  
  77.     /*
  78.      * Do not add fields after nodelists[]
  79.      */  
  80. };  
  81. /*
  82. * struct kmem_cache
  83. *
  84. * manages a cache.
  85. */

  86. struct kmem_cache {
  87. /* 1) per-cpu data, touched during every alloc/free */
  88.         struct array_cache *array[NR_CPUS];/*local cache*/
  89. /* 2) Cache tunables. Protected by cache_chain_mutex */
  90.         unsigned int batchcount;
  91.         unsigned int limit;
  92.         unsigned int shared;

  93.         unsigned int buffer_size;/*slab中对象大小*/
  94.         u32 reciprocal_buffer_size;/*slab中对象大小的倒数*/
  95. /* 3) touched by every alloc & free from the backend */

  96.         unsigned int flags;                /* constant flags */
  97.         unsigned int num;                /* # of objs per slab */

  98. /* 4) cache_grow/shrink */
  99.         /* order of pgs per slab (2^n) */
  100.         unsigned int gfporder;

  101.         /* force GFP flags, e.g. GFP_DMA */
  102.         gfp_t gfpflags;

  103.         size_t colour;/*着色块个数*/        /* cache colouring range */
  104.         unsigned int colour_off;/* cache的着色块的单位大小 */        /* colour offset */
  105.         struct kmem_cache *slabp_cache;
  106.         unsigned int slab_size;/*slab管理区大小,包含slab对象和kmem_bufctl_t数组*/
  107.         unsigned int dflags;                /* dynamic flags */

  108.         /* constructor func */
  109.         void (*ctor)(void *obj);

  110. /* 5) cache creation/removal */
  111.         const char *name;
  112.         struct list_head next;

  113. /* 6) statistics */
  114. #ifdef CONFIG_DEBUG_SLAB
  115.         unsigned long num_active;
  116.         unsigned long num_allocations;
  117.         unsigned long high_mark;
  118.         unsigned long grown;
  119.         unsigned long reaped;
  120.         unsigned long errors;
  121.         unsigned long max_freeable;
  122.         unsigned long node_allocs;
  123.         unsigned long node_frees;
  124.         unsigned long node_overflow;
  125.         atomic_t allochit;/*cache命中计数,在分配中更新*/
  126.         atomic_t allocmiss;/*cache未命中计数,在分配中更新*/
  127.         atomic_t freehit;
  128.         atomic_t freemiss;

  129.         /*
  130.          * If debugging is enabled, then the allocator can add additional
  131.          * fields and/or padding to every object. buffer_size contains the total
  132.          * object size including these internal fields, the following two
  133.          * variables contain the offset to the user object and its size.
  134.          */
  135.         int obj_offset;
  136.         int obj_size;
  137. #endif /* CONFIG_DEBUG_SLAB */

  138.         /*
  139.          * We put nodelists[] at the end of kmem_cache, because we want to size
  140.          * this array to nr_node_ids slots instead of MAX_NUMNODES
  141.          * (see kmem_cache_init())
  142.          * We still use [MAX_NUMNODES] and not [1] or [0] because cache_cache
  143.          * is statically defined, so we reserve the max number of nodes.
  144.          */
  145.         struct kmem_list3 *nodelists[MAX_NUMNODES];
  146.         /*
  147.          * Do not add fields after nodelists[]
  148.          */
  149. };
复制代码
在初始化的时候我们看到,为cache对象、三链结构、本地cache对象预留了三个cache共分配。其他为通用数据cache,整体结构如下图



其中,kmalloc使用的对象按照大小分属不同的cache,32、64、128、……,每种大小对应两个cache节点,一个用于DMA,一个用于普通分配。通过kmalloc分配的对象叫作通用数据对象。

可见通用数据cache是按照大小进行划分的,结构不同的对象,只要大小在同一个级别内,它们就会在同一个general cache中。专用cache指系统为特定结构创建的对象,比如struct file,此类cache中的对象来源于同一个结构。

2,slab对象管理器

Slab结构如下
  1. [cpp] view plaincopyprint?/*
  2. * struct slab
  3. *
  4. * Manages the objs in a slab. Placed either at the beginning of mem allocated
  5. * for a slab, or allocated from an general cache.
  6. * Slabs are chained into three list: fully used, partial, fully free slabs.
  7. */  
  8. struct slab {  
  9.     struct list_head list;  
  10.     /* 第一个对象的页内偏移,对于内置式slab,colouroff成员不仅包括着色区
  11.     ,还包括管理对象占用的空间
  12.     ,外置式slab,colouroff成员只包括着色区。*/  
  13.     unsigned long colouroff;  
  14.     void *s_mem;/* 第一个对象的虚拟地址 *//* including colour offset */  
  15.     unsigned int inuse;/*已分配的对象个数*/ /* num of objs active in slab */  
  16.     kmem_bufctl_t free;/* 第一个空闲对象索引*/  
  17.     unsigned short nodeid;  
  18. };  
  19. /*
  20. * struct slab
  21. *
  22. * Manages the objs in a slab. Placed either at the beginning of mem allocated
  23. * for a slab, or allocated from an general cache.
  24. * Slabs are chained into three list: fully used, partial, fully free slabs.
  25. */
  26. struct slab {
  27.         struct list_head list;
  28.         /* 第一个对象的页内偏移,对于内置式slab,colouroff成员不仅包括着色区
  29.         ,还包括管理对象占用的空间
  30.         ,外置式slab,colouroff成员只包括着色区。*/
  31.         unsigned long colouroff;
  32.         void *s_mem;/* 第一个对象的虚拟地址 *//* including colour offset */
  33.         unsigned int inuse;/*已分配的对象个数*/        /* num of objs active in slab */
  34.         kmem_bufctl_t free;/* 第一个空闲对象索引*/
  35.         unsigned short nodeid;
  36. };
复制代码
关于slab管理对象的整体框架以及slab管理对象与对象、页面之间的联系在前面的slab创建一文中已经总结的很清楚了。

3,slab着色

CPU访问内存时使用哪个cache line是通过低地址的若干位确定的,比如cache line大小为32,那么是从bit5开始的若干位。因此相距很远的内存地址,如果这些位的地址相同,还是会被映射到同一个cache line。Slab cache中存放的是相同大小的对象,如果没有着色区,那么同一个cache内,不同slab中具有相同slab内部偏移的对象,其低地址的若干位是相同的,映射到同一个cache line。如图所示。



如此一来,访问cache line冲突的对象时,就会出现cache miss,不停的在cache line和内存之间来回切换,与此同时,其他的cache line可能无所事事,严重影响了cache的效率。解决这一问题的方法是通过着色区使对象的slab内偏移各不相同,从而避免cache line冲突。

着色貌似很好的解决了问题,实质不然,当slab数目不多时,着色工作的很好,当slab数目很多时,着色发生了循环,仍然存在cache line冲突的问题。


论坛徽章:
0
2 [报告]
发表于 2012-01-12 12:01 |只看该作者
谢谢分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP