Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2179671
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: LINUX

2016-12-01 10:08:32

一. 总体说明


二.代码分析
2.1 在mm/slab.c中 L1577
  1. void kfree (const void *objp)   //传入参数objp=0xc210c280
  2. {
  3.     kmem_cache_t *c;
  4.     unsigned long flags;

  5.     if (!objp)
  6.         return;
  7.     local_irq_save(flags);
  8.     CHECK_PAGE(virt_to_page(objp));
  9.     c = GET_PAGE_CACHE(virt_to_page(objp));   //获取到kmem_cache_t的地址=0xc210b080
  10.     __kmem_cache_free(c, (void*)objp);    //2.2
  11.     local_irq_restore(flags);
  12. }
说明一下GET_PAGE_CACHE的原理:
  1. static int kmem_cache_grow (kmem_cache_t * cachep, int flags)
  2. {
  3.     objp = kmem_getpages(cachep, flags); //申请一页内存之后
  4.     page = virt_to_page(objp);           //将虚地址转为在mem_map中的page结构体的地址
  5.     do {
  6.         SET_PAGE_CACHE(page, cachep);    //page->list.next = cachep=0xc210b080
  7.         SET_PAGE_SLAB(page, slabp);      //page->list.pre=slabp=0xc210c000
  8.         PageSetSlab(page);
  9.         page++;
  10.     } while (--i);
  11. }

2.1 在mm/slab.c中 L1473 kfree-->__kmem_cache_free
  1. static inline void __kmem_cache_free (kmem_cache_t *cachep, void* objp)
  2. {
  3. #ifdef CONFIG_SMP
  4.     cpucache_t *cc = cc_data(cachep);

  5.     CHECK_PAGE(virt_to_page(objp));
  6.     if (cc) {
  7.         int batchcount;
  8.         if (cc->avail < cc->limit) {
  9.             STATS_INC_FREEHIT(cachep);
  10.             cc_entry(cc)[cc->avail++] = objp;
  11.             return;
  12.         }
  13.         STATS_INC_FREEMISS(cachep);
  14.         batchcount = cachep->batchcount;
  15.         cc->avail -= batchcount;
  16.         free_block(cachep,
  17.                     &cc_entry(cc)[cc->avail],batchcount);
  18.         cc_entry(cc)[cc->avail++] = objp;
  19.         return;
  20.     } else {
  21.         free_block(cachep, &objp, 1);
  22.     }
  23. #else
  24.     kmem_cache_free_one(cachep, objp);
  25. #endif
  26. }

free_block(cachep, &objp, 1);
  1. static void free_block (kmem_cache_t* cachep, void** objpp, int len)
  2. {
  3.     spin_lock(&cachep->spinlock);
  4.     __free_block(cachep, objpp, len);
  5.     spin_unlock(&cachep->spinlock);
  6. }



  1. static inline void __free_block (kmem_cache_t* cachepvoid** objpp, int len)
  2. {
  3.     for ( ; len > 0; len--, objpp++)
  4.         kmem_cache_free_one(cachep, *objpp);
  5. }


  1. (gdb) p *c
  2. $2 = {slabs_full = {next = 0xc210b080, prev = 0xc210b080}, slabs_partial = {next = 0xc210c000, prev = 0xc210c000}, slabs_free = {next = 0xc210b090, prev = 0xc210b090}, 
  3.   objsize = 64, flags = 139264, num = 58, spinlock = {lock = 1, magic = 3735899821}, batchcount = 0, gfporder = 0, gfpflags = 0, colour = 1, colour_off = 128, colour_next = 0, 
  4.   slabp_cache = 0x0, growing = 0, dflags = 1, ctor = 0x0, dtor = 0x0, failures = 0, name = "size-32", '\000' <repeats 12 times>, next = {next = 0xc02cf830 <cache_cache+112>, 
  5.     prev = 0xc210b1e8}, cpudata = {0x0 <repeats 32 times>}}


  1. (gdb) p *slabp
  2. $7 = {list = {next = 0xc210b088, prev = 0xc210b088}, colouroff = 256, s_mem = 0xc210c100, inuse = 7, free = 7}



在mm/slab.c中L1394
  1. static inline void kmem_cache_free_one(kmem_cache_t *cachep, void *objp)
  2. {
  3.     slab_t* slabp;

  4.     CHECK_PAGE(virt_to_page(objp));
  5.     slabp = GET_PAGE_SLAB(virt_to_page(objp));   //获取slabp的地址=0xc210c000

  6. //objp=0xc210c280, slabp->s_mem=0xc210c100,差=0x180=384; objszie=64,所以objnr=6
  7.     unsigned int objnr = (objp-slabp->s_mem)/cachep->objsize
  8.     slab_bufctl(slabp)[objnr] = slabp->free;    //更新slabp管理区的下标,没有看出有变化
  9.     slabp->free = objnr;

  10.     STATS_DEC_ACTIVE(cachep);
  11.     
  12. //更新cachep的链表,按照这个顺序改变full-->partial-->free
  13.       {
  14.         int inuse = slabp->inuse;
  15.         if (unlikely(!--slabp->inuse)) {
  16.             /* Was partial or full, now empty. */
  17.             list_del(&slabp->list);
  18.             list_add(&slabp->list, &cachep->slabs_free);
  19.         } else if (unlikely(inuse == cachep->num)) {
  20.             /* Was full. */
  21.             list_del(&slabp->list);
  22.             list_add(&slabp->list, &cachep->slabs_partial);
  23.         }
  24.     }
  25. }


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