Chinaunix首页 | 论坛 | 博客
  • 博客访问: 378826
  • 博文数量: 124
  • 博客积分: 30
  • 博客等级: 民兵
  • 技术积分: 11
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-29 22:22
文章分类

全部博文(124)

文章存档

2016年(8)

2015年(52)

2014年(53)

2013年(11)

分类: LINUX

2014-04-17 17:26:25

摘要:本文主要讲述linux如何处理ARM cortex A9多核处理器的内存管理部分。包括对SLAB管理器的分析。
其实现在写的东西,几年前在看老版本代码时就注释过了。目前在看3.0代码,将以前的东西复习一下,顺便发表到CU上与大家共享,大家在看博客的时候,如果觉得有不清楚的地方,请先阅读《深入理解linux内核》一书。
 
法律声明LINUX3.0内核源代码分析》系列文章由谢宝友()发表于http://xiebaoyou.blog.chinaunix.net,文章中的LINUX3.0源代码遵循GPL协议。除此以外,文档中的其他内容由作者保留所有版权。谢绝转载。
 

    伙伴系统算法的基本内存区是页框,它适合于对大块内存的请求。但是对几十或者几百个字节的请求是不适合的。不可能为这种请求分配一个页框。正确的方法是:引入一种新的数据结构来描述如何在同一页框中如何分配小内存区。这就是SLAB分配器要完成的任务。

    SLAB分配器最早出现于SUN公司的solaris2.4操作系统,它把对象分组放进高速缓存。每个高速缓存都是同种类型对象的一种储备。包含高速缓存的主内存区被分成多个SLAB。每个SLAB由一个或多个连续的页框组成。这些页框中既包含已经分配的对象,也包含空闲的对象。内核周期性的扫描高速缓存并释放空slab对应的页框。


高速缓存描述符是kmem_cache_t。

点击(此处)折叠或打开

  1. /**
  2.  * 高速缓存描述符
  3.  */
  4. struct kmem_cache {
  5. /* 1) per-cpu data, touched during every alloc/free */
  6.     /**
  7.      * 每CPU指针数组,指向包含空闲对象的本地高速缓存。
  8.      * 在分配内存时,优先从本CPU缓存中分配。这样可以减少spinlock的使用。
  9.      */
  10.     struct array_cache *array[NR_CPUS];
  11. /* 2) Cache tunables. Protected by cache_chain_mutex */
  12.     /**
  13.      * 要转移进本地高速缓存或从本地高速缓存中转移出的大批对象的数量。
  14.      * 当每CPU缓存的数量不足或者过多时,向本地缓存中一次移入batchcount个内存对象。
  15.      */
  16.     unsigned int batchcount;
  17.     /**
  18.      * 本地高速缓存中空闲对象的最大数目。超过此值时,从本地缓存中归还batchcount个对象。
  19.      */
  20.     unsigned int limit;
  21.     unsigned int shared;

  22.     /**
  23.      * 每一个分配的内存区在slab中的大小。
  24.      */
  25.     unsigned int buffer_size;
  26.      /**
  27.       * 要计算每一个分配出去的内存区在slab中的索引,可以用该内存区在slab中的偏移位置及内存区大小进行除法运算而得到,使用本字段是为了避免除法运算。
  28.       */
  29.     u32 reciprocal_buffer_size;
  30. /* 3) touched by every alloc & free from the backend */

  31.     /**
  32.      * 描述高速缓存属性的一组标志
  33.      */
  34.     unsigned int flags;        /* constant flags */
  35.     /**
  36.      * 在一个单独slab中的包含的内存区的个数。
  37.      */
  38.     unsigned int num;        /* # of objs per slab */

  39. /* 4) cache_grow/shrink */
  40.     /* order of pgs per slab (2^n) */
  41.     /**
  42.      * 一个单独slab中包含的连续页框数目的对数。
  43.      */
  44.     unsigned int gfporder;

  45.     /* force GFP flags, e.g. GFP_DMA */
  46.     /**
  47.      * 分配页框时传递给伙伴系统函数的一组标志。
  48.      */
  49.     gfp_t gfpflags;

  50.     /**
  51.      * slab使用的颜色个数。
  52.      * 为了避免缓存抖动,每个slab使用不同的着色。本字段表示所有slab可以颜色个数。
  53.      */
  54.     size_t colour;            /* cache colouring range */
  55.     /**
  56.      * slab中的基本对齐偏移。如果没有特别指定,就是一个缓存行的大小。
  57.      * 如果某个slab中计算的颜色值超过此值,则取其模作为该slab的颜色值。
  58.      */
  59.     unsigned int colour_off;    /* colour offset */
  60.     /**
  61.      * 指向包含slab描述符的普通slab高速缓存。如果使用了内部slab描述符,则这个字段为NULL。
  62.      *
  63.      */
  64.     struct kmem_cache *slabp_cache;
  65.     /**
  66.      * 单个slab大小。只包含slab中管理数据区的大小。不含slab中的数据区域。
  67.      */
  68.     unsigned int slab_size;
  69.     /**
  70.      * 高速缓存动态属性标志。
  71.      */
  72.     unsigned int dflags;        /* dynamic flags */

  73.     /* constructor func */
  74.     /**
  75.      * 构造方法,当分配一个内存区时回调此方法。可以在此进行一些数据初始化工作。
  76.      */
  77.     void (*ctor)(void *obj);

  78. /* 5) cache creation/removal */
  79.     /**
  80.      * 高速缓存名称。
  81.      */
  82.     const char *name;
  83.     /**
  84.      * 高速缓存链表。通过此结构将数据区链接到全局高速缓存链表中去。
  85.      */
  86.     struct list_head next;

  87. /* 6) statistics */
  88.     /**
  89.      * 一些统计字段
  90.      */
  91. #ifdef CONFIG_DEBUG_SLAB
  92.     unsigned long num_active;
  93.     unsigned long num_allocations;
  94.     unsigned long high_mark;
  95.     unsigned long grown;
  96.     unsigned long reaped;
  97.     unsigned long errors;
  98.     unsigned long max_freeable;
  99.     unsigned long node_allocs;
  100.     unsigned long node_frees;
  101.     unsigned long node_overflow;
  102.     atomic_t allochit;
  103.     atomic_t allocmiss;
  104.     atomic_t freehit;
  105.     atomic_t freemiss;

  106.     /*
  107.      * If debugging is enabled, then the allocator can add additional
  108.      * fields and/or padding to every object. buffer_size contains the total
  109.      * object size including these internal fields, the following two
  110.      * variables contain the offset to the user object and its size.
  111.      */
  112.     int obj_offset;
  113.     int obj_size;
  114. #endif /* CONFIG_DEBUG_SLAB */

  115.     /*
  116.      * We put nodelists[] at the end of kmem_cache, because we want to size
  117.      * this array to nr_node_ids slots instead of MAX_NUMNODES
  118.      * (see kmem_cache_init())
  119.      * We still use [MAX_NUMNODES] and not [1] or [0] because cache_cache
  120.      * is statically defined, so we reserve the max number of nodes.
  121.      */
  122.     /**
  123.      * 记录每个NUMA节点上的空闲slab、部分空闲slab、完全使用的slab
  124.      */
  125.     struct kmem_list3 *nodelists[MAX_NUMNODES];
  126.     /*
  127.      * Do not add fields after nodelists[]
  128.      */
  129. };


未完待续

阅读(1026) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~