slab函数分析之cache_grow

当向Slab缓存中提出对象申请的请求时,首先是找到相应的kmem_cache,然后从相应的
array cache中分配slab对象。当array cache中没有对象可以分配的时候,会批量向slab
缓存中提出对象申请来填满array cache,然后再从array cache中取出一个对象分配出去。
如果从slab缓存中分配对象的时候,发现kmem_list3中半满和空闲链表中都没有节点可以供
分配:entry == &l3->slabs_partial && entry == &l3->slabs_free,表示slab对象缓存需要
增长。下面就对slab对象缓存增长的函数进行分析。

static int cache_grow(struct kmem_cache *cachep, gfp_t flags, int nodeid)
{
 struct slab *slabp;
 void *objp;
 size_t offset;
 gfp_t local_flags;
 unsigned long ctor_flags;
 struct kmem_list3 *l3;
 
  标志位检查
 if (flags & ~(SLAB_DMA | SLAB_LEVEL_MASK | SLAB_NO_GROW))
  BUG();
 if (flags & SLAB_NO_GROW)
  return 0;

 ctor_flags = SLAB_CTOR_CONSTRUCTOR;
 local_flags = (flags & SLAB_LEVEL_MASK);
 if (!(local_flags & __GFP_WAIT))
  ctor_flags |= SLAB_CTOR_ATOMIC;

 check_irq_off();
 l3 = cachep->nodelists[nodeid];
 对kmem_list3进行加锁
 spin_lock(&l3->list_lock);
 
  取当前slab的颜色
 offset = l3->colour_next;
 计算下一个slab的颜色
 l3->colour_next++;
 if (l3->colour_next >= cachep->colour)
  l3->colour_next = 0;
 spin_unlock(&l3->list_lock);
  计算slab的着色偏移区
 offset *= cachep->colour_off;

 if (local_flags & __GFP_WAIT)
  local_irq_enable();

 kmem_flagcheck(cachep, flags);

  从伙伴系统中申请页面,返回页面的虚拟地址
 if (!(objp = kmem_getpages(cachep, flags, nodeid)))
  goto failed;

  为slab对象分配对象管理区
 if (!(slabp = alloc_slabmgmt(cachep, objp, offset, local_flags)))
  goto opps1;

 slabp->nodeid = nodeid;
  将该对象、slab缓存同页面建立联系:
  【page->lru.prev 指向引用该页面的slab的指针 page->lru.prev = (struct list_head *)slab】
 【page->lru.next 指向引用该页面的cache的指针 page->lru.next = (struct list_head *)cache】
 set_slab_attr(cachep, slabp, objp);

  对slab对象调用构造函数,并且初始化bufferctl数组。
 cache_init_objs(cachep, slabp, ctor_flags);

 if (local_flags & __GFP_WAIT)
  local_irq_disable();
 check_irq_off();
 spin_lock(&l3->list_lock);

  将slab管理区链入kmem_list3的空闲链表中。
 list_add_tail(&slabp->list, &(l3->slabs_free));
 STATS_INC_GROWN(cachep);
 调整空闲对象的数量
 l3->free_objects += cachep->num;
 spin_unlock(&l3->list_lock);
 return 1;
      opps1:
 kmem_freepages(cachep, objp);
      failed:
 if (local_flags & __GFP_WAIT)
  local_irq_disable();
 return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值