The base of
kmalloc is an array that groups
slab caches for memory areas of graded sizes. The array entries are instances of the
cache_sizes data structure that is defined as follows:
/* Size description struct for general caches. */
struct cache_sizes {
size_t cs_size;
struct kmem_cache *cs_cachep;
#ifdef CONFIG_ZONE_DMA
struct kmem_cache *cs_dmacachep;
#endif
};
|
cs_size specifies the size of the memory area for which the entry is responsible. There are two slab caches for each size, one of which supplies DMA-suitable memory.
The statically defined malloc_sizes array groups the available sizes essentially using powers of 2 between 25 = 32 and 225 = 131, 072, depending on the setting of KMALLOC_MAX_SIZE.
/* * These are the default caches for kmalloc(). Custom caches can have other sizes. */struct cache_sizes malloc_sizes[] = {#define CACHE(x) { .cs_size = (x) },#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 CACHE(256) CACHE(512) CACHE(1024) CACHE(2048) CACHE(4096) CACHE(8192) CACHE(16384) CACHE(32768) CACHE(65536) CACHE(131072)#if KMALLOC_MAX_SIZE >= 262144 CACHE(262144)#endif#if KMALLOC_MAX_SIZE >= 524288 CACHE(524288)#endif#if KMALLOC_MAX_SIZE >= 1048576 CACHE(1048576)#endif#if KMALLOC_MAX_SIZE >= 2097152 CACHE(2097152)#endif#if KMALLOC_MAX_SIZE >= 4194304 CACHE(4194304)#endif#if KMALLOC_MAX_SIZE >= 8388608 CACHE(8388608)#endif#if KMALLOC_MAX_SIZE >= 16777216 CACHE(16777216)#endif#if KMALLOC_MAX_SIZE >= 33554432 CACHE(33554432)#endif CACHE(ULONG_MAX)#undef CACHE};
kfree() hands over the actual work to the __cache_free().
/**
* kfree - free previously allocated memory
* @objp: pointer returned by kmalloc.
*
* If @objp is NULL, no operation is performed.
*
* Don't free memory not originally allocated by kmalloc()
* or you will run into trouble.
*/
void kfree(const void *objp)
{
struct kmem_cache *c;
unsigned long flags;
trace_kfree(_RET_IP_, objp);
if (unlikely(ZERO_OR_NULL_PTR(objp)))
return;
local_irq_save(flags);
kfree_debugcheck(objp);
c = virt_to_cache(objp);
debug_check_no_locks_freed(objp, obj_size(c));
debug_check_no_obj_freed(objp, obj_size(c));
__cache_free(c, (void *)objp);
local_irq_restore(flags);
}
EXPORT_SYMBOL(kfree);
|
阅读(642) | 评论(1) | 转发(0) |