免费注册 查看新帖 |

Chinaunix

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

Linux内存管理之slab机制(初始化) 3........... [复制链接]

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










第二阶段代码分析
  1. Start_kernel()->kmem_cache_init_late()

  2. view plaincopy to clipboardprint?/*Slab系统初始化分两个部分,先初始化一些基本的,待系统初始化工作进行的差不多时,再配置一些特殊功能。*/  
  3. void __init kmem_cache_init_late(void)  
  4. {  
  5.     struct kmem_cache *cachep;  
  6.     /* 初始化阶段local cache的大小是固定的,要根据对象大小重新计算 */  
  7.     /* 6) resize the head arrays to their final sizes */  
  8.     mutex_lock(&cache_chain_mutex);  
  9.     list_for_each_entry(cachep, &cache_chain, next)  
  10.         if (enable_cpucache(cachep, GFP_NOWAIT))  
  11.             BUG();  
  12.     mutex_unlock(&cache_chain_mutex);  
  13.   
  14.     /* Done! */  
  15.     /* 大功告成,general cache终于全部建立起来了 */  
  16.     g_cpucache_up = FULL;  
  17.   
  18.     /* Annotate slab for lockdep -- annotate the malloc caches */  
  19.     init_lock_keys();  
  20.   
  21.     /*
  22.      * Register a cpu startup notifier callback that initializes
  23.      * cpu_cache_get for all new cpus
  24.      */  
  25.      /* 注册cpu up回调函数,cpu up时配置local cache */  
  26.     register_cpu_notifier(&cpucache_notifier);  
  27.   
  28.     /*
  29.      * The reap timers are started later, with a module init call: That part
  30.      * of the kernel is not yet operational.
  31.      */  
  32. }  
  33. /*Slab系统初始化分两个部分,先初始化一些基本的,待系统初始化工作进行的差不多时,再配置一些特殊功能。*/
  34. void __init kmem_cache_init_late(void)
  35. {
  36.         struct kmem_cache *cachep;
  37.         /* 初始化阶段local cache的大小是固定的,要根据对象大小重新计算 */
  38.         /* 6) resize the head arrays to their final sizes */
  39.         mutex_lock(&cache_chain_mutex);
  40.         list_for_each_entry(cachep, &cache_chain, next)
  41.                 if (enable_cpucache(cachep, GFP_NOWAIT))
  42.                         BUG();
  43.         mutex_unlock(&cache_chain_mutex);

  44.         /* Done! */
  45.         /* 大功告成,general cache终于全部建立起来了 */
  46.         g_cpucache_up = FULL;

  47.         /* Annotate slab for lockdep -- annotate the malloc caches */
  48.         init_lock_keys();

  49.         /*
  50.          * Register a cpu startup notifier callback that initializes
  51.          * cpu_cache_get for all new cpus
  52.          */
  53.          /* 注册cpu up回调函数,cpu up时配置local cache */
  54.         register_cpu_notifier(&cpucache_notifier);

  55.         /*
  56.          * The reap timers are started later, with a module init call: That part
  57.          * of the kernel is not yet operational.
  58.          */
  59. }view plaincopy to clipboardprint?/* Called with cache_chain_mutex held always */  
  60. /*local cache 初始化*/  
  61. static int enable_cpucache(struct kmem_cache *cachep, gfp_t gfp)  
  62. {  
  63.     int err;  
  64.     int limit, shared;  
  65.   
  66.     /*
  67.      * The head array serves three purposes:
  68.      * - create a LIFO ordering, i.e. return objects that are cache-warm
  69.      * - reduce the number of spinlock operations.
  70.      * - reduce the number of linked list operations on the slab and
  71.      *   bufctl chains: array operations are cheaper.
  72.      * The numbers are guessed, we should auto-tune as described by
  73.      * Bonwick.
  74.      */ /* 根据对象大小计算local cache中对象数目上限 */  
  75.     if (cachep->buffer_size > 131072)  
  76.         limit = 1;  
  77.     else if (cachep->buffer_size > PAGE_SIZE)  
  78.         limit = 8;  
  79.     else if (cachep->buffer_size > 1024)  
  80.         limit = 24;  
  81.     else if (cachep->buffer_size > 256)  
  82.         limit = 54;  
  83.     else  
  84.         limit = 120;  
  85.   
  86.     /*
  87.      * CPU bound tasks (e.g. network routing) can exhibit cpu bound
  88.      * allocation behaviour: Most allocs on one cpu, most free operations
  89.      * on another cpu. For these cases, an efficient object passing between
  90.      * cpus is necessary. This is provided by a shared array. The array
  91.      * replaces Bonwick's magazine layer.
  92.      * On uniprocessor, it's functionally equivalent (but less efficient)
  93.      * to a larger limit. Thus disabled by default.
  94.      */  
  95.     shared = 0;  
  96.     /* 多核系统,设置shared local cache中对象数目 */  
  97.     if (cachep->buffer_size <= PAGE_SIZE && num_possible_cpus() > 1)  
  98.         shared = 8;  
  99.   
  100. #if DEBUG   
  101.     /*
  102.      * With debugging enabled, large batchcount lead to excessively long
  103.      * periods with disabled local interrupts. Limit the batchcount
  104.      */  
  105.     if (limit > 32)  
  106.         limit = 32;  
  107. #endif   
  108.     /* 配置local cache */  
  109.     err = do_tune_cpucache(cachep, limit, (limit + 1) / 2, shared, gfp);  
  110.     if (err)  
  111.         printk(KERN_ERR "enable_cpucache failed for %s, error %d.\n",  
  112.                cachep->name, -err);  
  113.     return err;  
  114. }  
  115. /* Called with cache_chain_mutex held always */
  116. /*local cache 初始化*/
  117. static int enable_cpucache(struct kmem_cache *cachep, gfp_t gfp)
  118. {
  119.         int err;
  120.         int limit, shared;

  121.         /*
  122.          * The head array serves three purposes:
  123.          * - create a LIFO ordering, i.e. return objects that are cache-warm
  124.          * - reduce the number of spinlock operations.
  125.          * - reduce the number of linked list operations on the slab and
  126.          *   bufctl chains: array operations are cheaper.
  127.          * The numbers are guessed, we should auto-tune as described by
  128.          * Bonwick.
  129.          */ /* 根据对象大小计算local cache中对象数目上限 */
  130.         if (cachep->buffer_size > 131072)
  131.                 limit = 1;
  132.         else if (cachep->buffer_size > PAGE_SIZE)
  133.                 limit = 8;
  134.         else if (cachep->buffer_size > 1024)
  135.                 limit = 24;
  136.         else if (cachep->buffer_size > 256)
  137.                 limit = 54;
  138.         else
  139.                 limit = 120;

  140.         /*
  141.          * CPU bound tasks (e.g. network routing) can exhibit cpu bound
  142.          * allocation behaviour: Most allocs on one cpu, most free operations
  143.          * on another cpu. For these cases, an efficient object passing between
  144.          * cpus is necessary. This is provided by a shared array. The array
  145.          * replaces Bonwick's magazine layer.
  146.          * On uniprocessor, it's functionally equivalent (but less efficient)
  147.          * to a larger limit. Thus disabled by default.
  148.          */
  149.         shared = 0;
  150.         /* 多核系统,设置shared local cache中对象数目 */
  151.         if (cachep->buffer_size <= PAGE_SIZE && num_possible_cpus() > 1)
  152.                 shared = 8;

  153. #if DEBUG
  154.         /*
  155.          * With debugging enabled, large batchcount lead to excessively long
  156.          * periods with disabled local interrupts. Limit the batchcount
  157.          */
  158.         if (limit > 32)
  159.                 limit = 32;
  160. #endif
  161.         /* 配置local cache */
  162.         err = do_tune_cpucache(cachep, limit, (limit + 1) / 2, shared, gfp);
  163.         if (err)
  164.                 printk(KERN_ERR "enable_cpucache failed for %s, error %d.\n",
  165.                        cachep->name, -err);
  166.         return err;
  167. }view plaincopy to clipboardprint?/* Always called with the cache_chain_mutex held */  
  168. /*配置local cache、shared local cache和slab三链*/  
  169. static int do_tune_cpucache(struct kmem_cache *cachep, int limit,  
  170.                 int batchcount, int shared, gfp_t gfp)  
  171. {  
  172.     struct ccupdate_struct *new;  
  173.     int i;  
  174.   
  175.     new = kzalloc(sizeof(*new), gfp);  
  176.     if (!new)  
  177.         return -ENOMEM;  
  178.     /* 为每个cpu分配新的struct array_cache对象 */  
  179.     for_each_online_cpu(i) {  
  180.         new->new[i] = alloc_arraycache(cpu_to_node(i), limit,  
  181.                         batchcount, gfp);  
  182.         if (!new->new[i]) {  
  183.             for (i--; i >= 0; i--)  
  184.                 kfree(new->new[i]);  
  185.             kfree(new);  
  186.             return -ENOMEM;  
  187.         }  
  188.     }  
  189.     new->cachep = cachep;  
  190.     /* 用新的struct array_cache对象替换旧的struct array_cache对象
  191.     ,在支持cpu热插拔的系统上,离线cpu可能没有释放local cache
  192.     ,使用的仍是旧local cache,参见__kmem_cache_destroy函数
  193.     。虽然cpu up时要重新配置local cache,也无济于事。考虑下面的情景
  194.     :共有Cpu A和Cpu B,Cpu B down后,destroy Cache X,由于此时Cpu B是down状态
  195.     ,所以Cache X中Cpu B的local cache未释放,过一段时间Cpu B又up了
  196.     ,更新cache_chain 链中所有cache的local cache,但此时Cache X对象已经释放回
  197.     cache_cache中了,其Cpu B local cache并未被更新。又过了一段时间
  198.     ,系统需要创建新的cache,将Cache X对象分配出去,其Cpu B仍然是旧的
  199.     local cache,需要进行更新。
  200.     */  
  201.     on_each_cpu(do_ccupdate_local, (void *)new, 1);  
  202.   
  203.     check_irq_on();  
  204.     cachep->batchcount = batchcount;  
  205.     cachep->limit = limit;  
  206.     cachep->shared = shared;  
  207.     /* 释放旧的local cache */  
  208.     for_each_online_cpu(i) {  
  209.         struct array_cache *ccold = new->new[i];  
  210.         if (!ccold)  
  211.             continue;  
  212.         spin_lock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock);  
  213.         /* 释放旧local cache中的对象 */  
  214.         free_block(cachep, ccold->entry, ccold->avail, cpu_to_node(i));  
  215.         spin_unlock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock);  
  216.         /* 释放旧的struct array_cache对象 */  
  217.         kfree(ccold);  
  218.     }  
  219.     kfree(new);  
  220.     /* 初始化shared local cache 和slab三链 */  
  221.     return alloc_kmemlist(cachep, gfp);  
  222. }  
  223. /* Always called with the cache_chain_mutex held */
  224. /*配置local cache、shared local cache和slab三链*/
  225. static int do_tune_cpucache(struct kmem_cache *cachep, int limit,
  226.                                 int batchcount, int shared, gfp_t gfp)
  227. {
  228.         struct ccupdate_struct *new;
  229.         int i;

  230.         new = kzalloc(sizeof(*new), gfp);
  231.         if (!new)
  232.                 return -ENOMEM;
  233.         /* 为每个cpu分配新的struct array_cache对象 */
  234.         for_each_online_cpu(i) {
  235.                 new->new[i] = alloc_arraycache(cpu_to_node(i), limit,
  236.                                                 batchcount, gfp);
  237.                 if (!new->new[i]) {
  238.                         for (i--; i >= 0; i--)
  239.                                 kfree(new->new[i]);
  240.                         kfree(new);
  241.                         return -ENOMEM;
  242.                 }
  243.         }
  244.         new->cachep = cachep;
  245.         /* 用新的struct array_cache对象替换旧的struct array_cache对象
  246.         ,在支持cpu热插拔的系统上,离线cpu可能没有释放local cache
  247.         ,使用的仍是旧local cache,参见__kmem_cache_destroy函数
  248.         。虽然cpu up时要重新配置local cache,也无济于事。考虑下面的情景
  249.         :共有Cpu A和Cpu B,Cpu B down后,destroy Cache X,由于此时Cpu B是down状态
  250.         ,所以Cache X中Cpu B的local cache未释放,过一段时间Cpu B又up了
  251.         ,更新cache_chain 链中所有cache的local cache,但此时Cache X对象已经释放回
  252.         cache_cache中了,其Cpu B local cache并未被更新。又过了一段时间
  253.         ,系统需要创建新的cache,将Cache X对象分配出去,其Cpu B仍然是旧的
  254.         local cache,需要进行更新。
  255.         */
  256.         on_each_cpu(do_ccupdate_local, (void *)new, 1);

  257.         check_irq_on();
  258.         cachep->batchcount = batchcount;
  259.         cachep->limit = limit;
  260.         cachep->shared = shared;
  261.         /* 释放旧的local cache */
  262.         for_each_online_cpu(i) {
  263.                 struct array_cache *ccold = new->new[i];
  264.                 if (!ccold)
  265.                         continue;
  266.                 spin_lock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock);
  267.                 /* 释放旧local cache中的对象 */
  268.                 free_block(cachep, ccold->entry, ccold->avail, cpu_to_node(i));
  269.                 spin_unlock_irq(&cachep->nodelists[cpu_to_node(i)]->list_lock);
  270.                 /* 释放旧的struct array_cache对象 */
  271.                 kfree(ccold);
  272.         }
  273.         kfree(new);
  274.         /* 初始化shared local cache 和slab三链 */
  275.         return alloc_kmemlist(cachep, gfp);
  276. }
复制代码
更新本地cache
  1. view plaincopy to clipboardprint?/*更新每个cpu的struct array_cache对象*/  
  2. static void do_ccupdate_local(void *info)  
  3. {  
  4.     struct ccupdate_struct *new = info;  
  5.     struct array_cache *old;  
  6.   
  7.     check_irq_off();  
  8.     old = cpu_cache_get(new->cachep);  
  9.      /* 指向新的struct array_cache对象 */  
  10.     new->cachep->array[smp_processor_id()] = new->new[smp_processor_id()];  
  11.         /* 保存旧的struct array_cache对象 */  
  12.     new->new[smp_processor_id()] = old;  
  13. }  
  14. /*更新每个cpu的struct array_cache对象*/
  15. static void do_ccupdate_local(void *info)
  16. {
  17.         struct ccupdate_struct *new = info;
  18.         struct array_cache *old;

  19.         check_irq_off();
  20.         old = cpu_cache_get(new->cachep);
  21.          /* 指向新的struct array_cache对象 */
  22.         new->cachep->array[smp_processor_id()] = new->new[smp_processor_id()];
  23.             /* 保存旧的struct array_cache对象 */
  24.         new->new[smp_processor_id()] = old;
  25. }view plaincopy to clipboardprint?/*初始化shared local cache和slab三链,初始化完成后,slab三链中没有任何slab*/  
  26. static int alloc_kmemlist(struct kmem_cache *cachep, gfp_t gfp)  
  27. {  
  28.     int node;  
  29.     struct kmem_list3 *l3;  
  30.     struct array_cache *new_shared;  
  31.     struct array_cache **new_alien = NULL;  
  32.   
  33.     for_each_online_node(node) {  
  34.          /* NUMA相关 */  
  35.                 if (use_alien_caches) {  
  36.                         new_alien = alloc_alien_cache(node, cachep->limit, gfp);  
  37.                         if (!new_alien)  
  38.                                 goto fail;  
  39.                 }  
  40.   
  41.         new_shared = NULL;  
  42.         if (cachep->shared) {  
  43.             /* 分配shared local cache */  
  44.             new_shared = alloc_arraycache(node,  
  45.                 cachep->shared*cachep->batchcount,  
  46.                     0xbaadf00d, gfp);  
  47.             if (!new_shared) {  
  48.                 free_alien_cache(new_alien);  
  49.                 goto fail;  
  50.             }  
  51.         }  
  52.         /* 获得旧的slab三链 */  
  53.         l3 = cachep->nodelists[node];  
  54.         if (l3) {  
  55.             /* 就slab三链指针不为空,需要先释放旧的资源 */  
  56.             struct array_cache *shared = l3->shared;  
  57.   
  58.             spin_lock_irq(&l3->list_lock);  
  59.             /* 释放旧的shared local cache中的对象 */  
  60.             if (shared)  
  61.                 free_block(cachep, shared->entry,  
  62.                         shared->avail, node);  
  63.             /* 指向新的shared local cache */  
  64.             l3->shared = new_shared;  
  65.             if (!l3->alien) {  
  66.                 l3->alien = new_alien;  
  67.                 new_alien = NULL;  
  68.             }/* 计算cache中空闲对象的上限 */  
  69.             l3->free_limit = (1 + nr_cpus_node(node)) *  
  70.                     cachep->batchcount + cachep->num;  
  71.             spin_unlock_irq(&l3->list_lock);  
  72.             /* 释放旧shared local cache的struct array_cache对象 */  
  73.             kfree(shared);  
  74.             free_alien_cache(new_alien);  
  75.             continue;/*访问下一个节点*/  
  76.         }  
  77.          /* 如果没有旧的l3,分配新的slab三链 */  
  78.         l3 = kmalloc_node(sizeof(struct kmem_list3), gfp, node);  
  79.         if (!l3) {  
  80.             free_alien_cache(new_alien);  
  81.             kfree(new_shared);  
  82.             goto fail;  
  83.         }  
  84.          /* 初始化slab三链 */  
  85.         kmem_list3_init(l3);  
  86.         l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +  
  87.                 ((unsigned long)cachep) % REAPTIMEOUT_LIST3;  
  88.         l3->shared = new_shared;  
  89.         l3->alien = new_alien;  
  90.         l3->free_limit = (1 + nr_cpus_node(node)) *  
  91.                     cachep->batchcount + cachep->num;  
  92.         cachep->nodelists[node] = l3;  
  93.     }  
  94.     return 0;  
  95.   
  96. fail:  
  97.     if (!cachep->next.next) {  
  98.         /* Cache is not active yet. Roll back what we did */  
  99.         node--;  
  100.         while (node >= 0) {  
  101.             if (cachep->nodelists[node]) {  
  102.                 l3 = cachep->nodelists[node];  
  103.   
  104.                 kfree(l3->shared);  
  105.                 free_alien_cache(l3->alien);  
  106.                 kfree(l3);  
  107.                 cachep->nodelists[node] = NULL;  
  108.             }  
  109.             node--;  
  110.         }  
  111.     }  
  112.     return -ENOMEM;  
  113. }  
  114. /*初始化shared local cache和slab三链,初始化完成后,slab三链中没有任何slab*/
  115. static int alloc_kmemlist(struct kmem_cache *cachep, gfp_t gfp)
  116. {
  117.         int node;
  118.         struct kmem_list3 *l3;
  119.         struct array_cache *new_shared;
  120.         struct array_cache **new_alien = NULL;

  121.         for_each_online_node(node) {
  122.                  /* NUMA相关 */
  123.                 if (use_alien_caches) {
  124.                         new_alien = alloc_alien_cache(node, cachep->limit, gfp);
  125.                         if (!new_alien)
  126.                                 goto fail;
  127.                 }

  128.                 new_shared = NULL;
  129.                 if (cachep->shared) {
  130.                         /* 分配shared local cache */
  131.                         new_shared = alloc_arraycache(node,
  132.                                 cachep->shared*cachep->batchcount,
  133.                                         0xbaadf00d, gfp);
  134.                         if (!new_shared) {
  135.                                 free_alien_cache(new_alien);
  136.                                 goto fail;
  137.                         }
  138.                 }
  139.                 /* 获得旧的slab三链 */
  140.                 l3 = cachep->nodelists[node];
  141.                 if (l3) {
  142.                         /* 就slab三链指针不为空,需要先释放旧的资源 */
  143.                         struct array_cache *shared = l3->shared;

  144.                         spin_lock_irq(&l3->list_lock);
  145.                         /* 释放旧的shared local cache中的对象 */
  146.                         if (shared)
  147.                                 free_block(cachep, shared->entry,
  148.                                                 shared->avail, node);
  149.                         /* 指向新的shared local cache */
  150.                         l3->shared = new_shared;
  151.                         if (!l3->alien) {
  152.                                 l3->alien = new_alien;
  153.                                 new_alien = NULL;
  154.                         }/* 计算cache中空闲对象的上限 */
  155.                         l3->free_limit = (1 + nr_cpus_node(node)) *
  156.                                         cachep->batchcount + cachep->num;
  157.                         spin_unlock_irq(&l3->list_lock);
  158.                         /* 释放旧shared local cache的struct array_cache对象 */
  159.                         kfree(shared);
  160.                         free_alien_cache(new_alien);
  161.                         continue;/*访问下一个节点*/
  162.                 }
  163.                  /* 如果没有旧的l3,分配新的slab三链 */
  164.                 l3 = kmalloc_node(sizeof(struct kmem_list3), gfp, node);
  165.                 if (!l3) {
  166.                         free_alien_cache(new_alien);
  167.                         kfree(new_shared);
  168.                         goto fail;
  169.                 }
  170.                  /* 初始化slab三链 */
  171.                 kmem_list3_init(l3);
  172.                 l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
  173.                                 ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
  174.                 l3->shared = new_shared;
  175.                 l3->alien = new_alien;
  176.                 l3->free_limit = (1 + nr_cpus_node(node)) *
  177.                                         cachep->batchcount + cachep->num;
  178.                 cachep->nodelists[node] = l3;
  179.         }
  180.         return 0;

  181. fail:
  182.         if (!cachep->next.next) {
  183.                 /* Cache is not active yet. Roll back what we did */
  184.                 node--;
  185.                 while (node >= 0) {
  186.                         if (cachep->nodelists[node]) {
  187.                                 l3 = cachep->nodelists[node];

  188.                                 kfree(l3->shared);
  189.                                 free_alien_cache(l3->alien);
  190.                                 kfree(l3);
  191.                                 cachep->nodelists[node] = NULL;
  192.                         }
  193.                         node--;
  194.                 }
  195.         }
  196.         return -ENOMEM;
  197. }
复制代码
看一个辅助函数
  1. view plaincopy to clipboardprint?/*分配struct array_cache对象。*/  
  2. static struct array_cache *alloc_arraycache(int node, int entries,  
  3.                         int batchcount, gfp_t gfp)  
  4. {  
  5.     /* struct array_cache后面紧接着的是entry数组,合在一起申请内存 */  
  6.     int memsize = sizeof(void *) * entries + sizeof(struct array_cache);  
  7.     struct array_cache *nc = NULL;  
  8.     /* 分配一个local cache对象,kmalloc从general cache中分配 */  
  9.     nc = kmalloc_node(memsize, gfp, node);  
  10.     /*
  11.      * The array_cache structures contain pointers to free object.
  12.      * However, when such objects are allocated or transfered to another
  13.      * cache the pointers are not cleared and they could be counted as
  14.      * valid references during a kmemleak scan. Therefore, kmemleak must
  15.      * not scan such objects.
  16.      */  
  17.     kmemleak_no_scan(nc);  
  18.      /* 初始化local cache */  
  19.     if (nc) {  
  20.         nc->avail = 0;  
  21.         nc->limit = entries;  
  22.         nc->batchcount = batchcount;  
  23.         nc->touched = 0;  
  24.         spin_lock_init(&nc->lock);  
  25.     }  
  26.     return nc;  
  27. }  
  28. /*分配struct array_cache对象。*/
  29. static struct array_cache *alloc_arraycache(int node, int entries,
  30.                                             int batchcount, gfp_t gfp)
  31. {
  32.         /* struct array_cache后面紧接着的是entry数组,合在一起申请内存 */
  33.         int memsize = sizeof(void *) * entries + sizeof(struct array_cache);
  34.         struct array_cache *nc = NULL;
  35.         /* 分配一个local cache对象,kmalloc从general cache中分配 */
  36.         nc = kmalloc_node(memsize, gfp, node);
  37.         /*
  38.          * The array_cache structures contain pointers to free object.
  39.          * However, when such objects are allocated or transfered to another
  40.          * cache the pointers are not cleared and they could be counted as
  41.          * valid references during a kmemleak scan. Therefore, kmemleak must
  42.          * not scan such objects.
  43.          */
  44.         kmemleak_no_scan(nc);
  45.          /* 初始化local cache */
  46.         if (nc) {
  47.                 nc->avail = 0;
  48.                 nc->limit = entries;
  49.                 nc->batchcount = batchcount;
  50.                 nc->touched = 0;
  51.                 spin_lock_init(&nc->lock);
  52.         }
  53.         return nc;
  54. }
复制代码
源代码中涉及了slab的分配、释放等操作在后面分析中陆续总结。slab相关数据结构、工作机制以及整体框架在分析完了slab的创建、释放工作后再做总结,这样可能会对slab机制有更好的了解。当然,从代码中看运行机制会更有说服了,也是一种习惯。

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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP