25.kmalloc的简单描述

kmalloc的实现
kmalloc的基础是一个数组,其中是一些分别用于不同内存长度的slab缓存。数组项是cache_sizes的实例,该数据结构定义如下:
<slab_def.h> 
struct cache_sizes { 
   size_t cs_size; 
   kmem_cache_t *cs_cachep; 
   kmem_cache_t *cs_dmacachep; 
#ifdef CONFIG_ZONE_DMA 
   struct kmem_cache *cs_dmacachep; 
#endif 
}
cs_size指定了该项负责的内存区的长度。每个长度对应于两个slab缓存,其中之一提供适合DMA访问的内存。
静态定义的malloc_sizes数组包括了所有可用的长度,基本上都是2的幂次,介乎25 =32和225=33 554 432之间,最大值依赖于KMALLOC_MAX_SIZE的设置。
mm/slab.c 
static 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 >= 33554432 
CACHE(33554432) 
CACHE(ULONG_MAX)
指向对应缓存的指针没有初始值。在kmem_cache_init进行初始化时,同时会对这些指针赋值。
kmalloc定义在<slab_def.h>,该函数首先检查是否用常数来指定所需分配内存的长度。在这种情况下,所需的缓存可以在编译时静态确定,这可以提高速度。否则,该函数调用__kmalloc查找长度匹配的缓存。后者是__do_kmalloc的前端,提供参数转换功能。
 
mm/slab.c 
void *__do_kmalloc(size_t size, gfp_t flags) 
{ 
  kmem_cache_t *cachep; 
  cachep = __find_general_cachep(size, flags); 
  if (unlikely(ZERO_OR_NULL_PTR(cachep))) 
    return NULL; 
  return __cache_alloc(cachep, flags); 
}
在__find_general_cachep找到适当的缓存后(遍历所有可能的kmalloc长度,找到一个匹配的缓存),主要的工作则委托给上文讨论过的__cache_alloc函数完成。
kfree的实现
mm/slab.c 
void kfree(const void *objp) 
{ 
  kmem_cache_t *c; 
  unsigned long flags; 
  if (unlikely(ZERO_OR_NULL_PTR(objp))) 
    return; 
  c = virt_to_cache(objp)); 
  __cache_free(c, (void*)objp); 
}
在找到与内存指针关联的缓存之后,kfree将实际工作移交上文讨论过的__cache_free函数完成。
 
posted @ 2022-03-23 00:43  while(true);;  阅读(61)  评论(0编辑  收藏  举报