点击(此处)折叠或打开
- /**
- * kmem_cache_alloc - Allocate an object
- * @cachep: The cache to allocate from.
- * @flags: See kmalloc().
- *
- * Allocate an object from this cache. The flags are only relevant
- * if the cache has no available objects.
- */
- void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
- {
/* __builtin_return_address是GCC内置函数,用于获取当前函数的返回地址 */ - void *ret = __cache_alloc(cachep, flags, __builtin_return_address(0));
- trace_kmem_cache_alloc(_RET_IP_, ret,
- obj_size(cachep), cachep->buffer_size, flags);
- return ret;
- }
点击(此处)折叠或打开
- __cache_alloc(struct kmem_cache *cachep, gfp_t flags, void *caller)
- {
- unsigned long save_flags;
- void *objp;
- flags &= gfp_allowed_mask;
- lockdep_trace_alloc(flags);
- if (slab_should_failslab(cachep, flags))
- return NULL;
- cache_alloc_debugcheck_before(cachep, flags);
- local_irq_save(save_flags);
- /* 在关硬中断的前提下,调用下面函数,完成实际的分配过程 */
- objp = __do_cache_alloc(cachep, flags);
- local_irq_restore(save_flags);
- objp = cache_alloc_debugcheck_after(cachep, flags, objp, caller);
- kmemleak_alloc_recursive(objp, obj_size(cachep), 1, cachep->flags,
- flags);
- prefetchw(objp);
- if (likely(objp))
- kmemcheck_slab_alloc(cachep, flags, objp, obj_size(cachep));
- if (unlikely((flags & __GFP_ZERO) && objp))
- memset(objp, 0, obj_size(cachep));
- return objp;
- }
点击(此处)折叠或打开
- static __always_inline void *
- __do_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
- {
- return ____cache_alloc(cachep, flags);
- }
点击(此处)折叠或打开
- static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags)
- {
- void *objp;
- struct array_cache *ac;
- check_irq_off();
- /* 获取local cache, array_cache数组 */
- ac = cpu_cache_get(cachep);
- /* 有空闲对象 */
- if (likely(ac->avail)) {
- STATS_INC_ALLOCHIT(cachep);
- /* 标示最近被访问 */
- ac->touched = 1;
- /* 分配一个对象,avail指向可用的空闲节点 */
- objp = ac->entry[--ac->avail];
- } else {
- STATS_INC_ALLOCMISS(cachep);
- /* local cache中无空闲对象,填充 */
- objp = cache_alloc_refill(cachep, flags);
- }
- /*
- * To avoid a false negative, if an object that is in one of the
- * per-CPU caches is leaked, we need to make sure kmemleak doesn't
- * treat the array pointers as a reference to the object.
- */
- kmemleak_erase(&ac->entry[ac->avail]);
- return objp;
- }