【发布时间】:2018-02-23 11:32:09
【问题描述】:
我正在查看 Linux 版本 4.9.31
还有一个slab和slub的kmalloc()函数
以下是include/linux/slab.h的kmalloc()函数
static __always_inline void *kmalloc(size_t size, gfp_t flags)
{
if (__builtin_constant_p(size)) {
if (size > KMALLOC_MAX_CACHE_SIZE)
return kmalloc_large(size, flags);
#ifndef CONFIG_SLOB
if (!(flags & GFP_DMA)) {
int index = kmalloc_index(size);
if (!index)
return ZERO_SIZE_PTR;
return kmem_cache_alloc_trace(kmalloc_caches[index],
flags, size);
}
#endif
}
return __kmalloc(size, flags);
}
在上面的代码中,当 __builtin_constant_p(size) 为真时调用 kmalloc_large()。
第一个问题。 __builtin_constant_p(size) 和 kmalloc_large() 是什么关系?不应该在运行时调用 kmalloc_large(),而不是在编译时调用?
以下是mm/slab.c的__kmalloc()和__do_kmalloc()
static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
unsigned long caller)
{
struct kmem_cache *cachep;
void *ret;
cachep = kmalloc_slab(size, flags);
if (unlikely(ZERO_OR_NULL_PTR(cachep)))
return cachep;
ret = slab_alloc(cachep, flags, caller);
kasan_kmalloc(cachep, ret, size, flags);
trace_kmalloc(caller, ret,
size, cachep->size, flags);
return ret;
}
void *__kmalloc(size_t size, gfp_t flags)
{
return __do_kmalloc(size, flags, _RET_IP_);
}
以下是mm/slub.c的__kmalloc()
void *__kmalloc(size_t size, gfp_t flags)
{
struct kmem_cache *s;
void *ret;
if (unlikely(size > KMALLOC_MAX_CACHE_SIZE))
return kmalloc_large(size, flags);
s = kmalloc_slab(size, flags);
if (unlikely(ZERO_OR_NULL_PTR(s)))
return s;
ret = slab_alloc(s, flags, _RET_IP_);
trace_kmalloc(_RET_IP_, ret, size, s->size, flags);
kasan_kmalloc(s, ret, size, flags);
return ret;
}
第二个问题。 为什么slub __kmalloc() 会在运行时检查“size > KMALLOC_MAX_CACHE_SIZE”并调用kmalloc_large()?
【问题讨论】:
标签: linux memory-management linux-kernel