1.kamlloc
static __always_inline void *kmalloc(size_t size, gfp_t flags)
{
struct kmem_cache *cachep;
void *ret;
if (__builtin_constant_p(size)) { //__builtin_constant_p 是编译器gcc内置函数,用于判断一个值是否为编译时常量,如果是常数,返回1,否则返回0
int i = 0;
if (!size)
return ZERO_SIZE_PTR;
#define CACHE(x) \
if (size <= x) \
goto found; \
else \
i++;
#include <linux/kmalloc_sizes.h> //这里查询申请的size在哪个范围 从32乘2递增
#undef CACHE
return NULL;
found:
#ifdef CONFIG_ZONE_DMA
if (flags & GFP_DMA) //如果定义了dma,并且设置了dma标志则优先从dma_cache了申请。malloc_sizes的初始化在slab.c里
cachep = malloc_sizes[i].cs_dmacachep;
else
#endif
cachep = malloc_sizes[i].cs_cachep; //从指定的cache链表分配内存,不浪费空间。
ret = kmem_cache_alloc_trace(size, cachep, flags);
return ret;
}
return __kmalloc(size, flags);
}
kmem_cache_alloc_trace(size_t size, struct kmem_cache *cachep, gfp_t flags)
{
return kmem_cache_alloc(cachep, flags); //调用slab_alloc
}
void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags)
{
void *ret = slab_alloc(s, gfpflags, NUMA_NO_NODE, _RET_IP_);
trace_kmem_cache_alloc(_RET_IP_, ret, s->objsize, s->size, gfpflags); //跟踪调试会用到
return ret;
}
kmalloc最后主要调用了slab,下面看看<linux/kmalloc_sizes.h> 中的内容:
// <linux/kmalloc_sizes.h>
#if (PAGE_SIZE == 4096)
CACHE(32)
#endif
CACHE(64)
#if L1_CACHE_BYTES < 64
CACHE(96)
#endif
CACHE(128)
#if L1_CACHE_BYTES < 128
CACHE(192)
#endif
C