一. 总体说明
二.代码分析
2.1 在mm/slab.c中 L1577
-
void kfree (const void *objp) //传入参数objp=0xc210c280
-
{
-
kmem_cache_t *c;
-
unsigned long flags;
-
-
if (!objp)
-
return;
-
local_irq_save(flags);
-
CHECK_PAGE(virt_to_page(objp));
-
c = GET_PAGE_CACHE(virt_to_page(objp)); //获取到kmem_cache_t的地址=0xc210b080
-
__kmem_cache_free(c, (void*)objp); //2.2
-
local_irq_restore(flags);
-
}
说明一下GET_PAGE_CACHE的原理:
-
static int kmem_cache_grow (kmem_cache_t * cachep, int flags)
-
{
-
objp = kmem_getpages(cachep, flags); //申请一页内存之后
-
page = virt_to_page(objp); //将虚地址转为在mem_map中的page结构体的地址
-
do {
-
SET_PAGE_CACHE(page, cachep); //page->list.next = cachep=0xc210b080
-
SET_PAGE_SLAB(page, slabp); //page->list.pre=slabp=0xc210c000
-
PageSetSlab(page);
-
page++;
-
} while (--i);
-
}
2.1 在mm/slab.c中 L1473 kfree-->__kmem_cache_free
-
static inline void __kmem_cache_free (kmem_cache_t *cachep, void* objp)
-
{
-
#ifdef CONFIG_SMP
-
cpucache_t *cc = cc_data(cachep);
-
-
CHECK_PAGE(virt_to_page(objp));
-
if (cc) {
-
int batchcount;
-
if (cc->avail < cc->limit) {
-
STATS_INC_FREEHIT(cachep);
-
cc_entry(cc)[cc->avail++] = objp;
-
return;
-
}
-
STATS_INC_FREEMISS(cachep);
-
batchcount = cachep->batchcount;
-
cc->avail -= batchcount;
-
free_block(cachep,
-
&cc_entry(cc)[cc->avail],batchcount);
-
cc_entry(cc)[cc->avail++] = objp;
-
return;
-
} else {
-
free_block(cachep, &objp, 1);
-
}
-
#else
-
kmem_cache_free_one(cachep, objp);
-
#endif
-
}
free_block(cachep, &objp, 1);
-
static void free_block (kmem_cache_t* cachep, void** objpp, int len)
-
{
-
spin_lock(&cachep->spinlock);
-
__free_block(cachep, objpp, len);
-
spin_unlock(&cachep->spinlock);
-
}
-
static inline void __free_block (kmem_cache_t* cachep, void** objpp, int len)
-
{
-
for ( ; len > 0; len--, objpp++)
-
kmem_cache_free_one(cachep, *objpp);
-
}
-
(gdb) p *c
-
$2 = {slabs_full = {next = 0xc210b080, prev = 0xc210b080}, slabs_partial = {next = 0xc210c000, prev = 0xc210c000}, slabs_free = {next = 0xc210b090, prev = 0xc210b090},
-
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,
-
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>,
-
prev = 0xc210b1e8}, cpudata = {0x0 <repeats 32 times>}}
-
(gdb) p *slabp
-
$7 = {list = {next = 0xc210b088, prev = 0xc210b088}, colouroff = 256, s_mem = 0xc210c100, inuse = 7, free = 7}
在mm/slab.c中L1394
-
static inline void kmem_cache_free_one(kmem_cache_t *cachep, void *objp)
-
{
-
slab_t* slabp;
-
-
CHECK_PAGE(virt_to_page(objp));
-
slabp = GET_PAGE_SLAB(virt_to_page(objp)); //获取slabp的地址=0xc210c000
-
-
//objp=0xc210c280, slabp->s_mem=0xc210c100,差=0x180=384; objszie=64,所以objnr=6
-
unsigned int objnr = (objp-slabp->s_mem)/cachep->objsize;
-
slab_bufctl(slabp)[objnr] = slabp->free; //更新slabp管理区的下标,没有看出有变化
-
slabp->free = objnr;
-
-
STATS_DEC_ACTIVE(cachep);
-
-
//更新cachep的链表,按照这个顺序改变full-->partial-->free
-
{
-
int inuse = slabp->inuse;
-
if (unlikely(!--slabp->inuse)) {
-
/* Was partial or full, now empty. */
-
list_del(&slabp->list);
-
list_add(&slabp->list, &cachep->slabs_free);
-
} else if (unlikely(inuse == cachep->num)) {
-
/* Was full. */
-
list_del(&slabp->list);
-
list_add(&slabp->list, &cachep->slabs_partial);
-
}
-
}
-
}
阅读(1840) | 评论(0) | 转发(0) |