栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

kmalloc执行过程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

kmalloc执行过程

之前编写内核驱动时,经常会用到kmalloc系列函数分配内存,那么它是如何分配内存的?好吧,我们追踪一下源码。

kmalloc
static __always_inline __alloc_size(1) void *kmalloc(size_t size, gfp_t flags)
{
        if (__builtin_constant_p(size)) { // 判断size是否是常数
#ifndef CONFIG_SLOB
                unsigned int index;
#endif
                if (size > KMALLOC_MAX_CACHE_SIZE)
                        return kmalloc_large(size, flags);

  首先看下KMALLOC_MAX_CACHE_SIZE值:

#define KMALLOC_MAX_CACHE_SIZE	(1UL << KMALLOC_SHIFT_HIGH)

||
/    

#define KMALLOC_SHIFT_HIGH	((MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? 
				(MAX_ORDER + PAGE_SHIFT - 1) : 25)
				
||
/


#ifndef CONFIG_FORCE_MAX_ZONEORDER
#define MAX_ORDER 11
#else
#define MAX_ORDER CONFIG_FORCE_MAX_ZONEORDER
#endif
#define MAX_ORDER_NR_PAGES (1 << (MAX_ORDER - 1))

#define PAGE_SHIFT	12

||
/

 KMALLOC_MAX_CACHE_SIZE	(1UL << 22)

  在x86架构下KMALLOC_MAX_CACHE_SIZE为4MB,:

 if (size > KMALLOC_MAX_CACHE_SIZE) // size大于4MB
                        return kmalloc_large(size, flags);
                        
                   		||
                   		/
                   		
static __always_inline __alloc_size(1) void *kmalloc_large(size_t size, gfp_t flags)
{
        unsigned int order = get_order(size); 
        
        
        return kmalloc_order_trace(size, flags, order);
}

  进入kmalloc_order_trace函数:

static __always_inline __alloc_size(1) void *kmalloc_order_trace(size_t size, gfp_t flags,
                                                                 unsigned int order)
{       
        return kmalloc_order(size, flags, order);
}

||
/

void *kmalloc_order(size_t size, gfp_t flags, unsigned int order)
{
        void *ret = NULL;
        struct page *page;

        if (unlikely(flags & GFP_SLAB_BUG_MASK)) // 不使用slab分配器
                flags = kmalloc_fix_flags(flags);  // 去掉flags中的GFP_SLAB_BUG_MASK,执行dump_stack

        flags |= __GFP_COMP;
        page = alloc_pages(flags, order); // 分配 2 ^ order -  (2 ^ order - 1)数量的物理页面
        if (likely(page)) {
                ret = page_address(page); // 返回页面的虚拟地址
                mod_lruvec_page_state(page, NR_SLAB_UNRECLAIMABLE_B,
                                      PAGE_SIZE << order); // 更新lru状态
        }
        ret = kasan_kmalloc_large(ret, size, flags);  // 填充kasan
        
        kmemleak_alloc(ret, size, 1, flags);
        return ret;
}

  继续分析kmalloc:

        return __kmalloc(size, flags);
}

||
/ 

void *__kmalloc(size_t size, gfp_t flags)
{
        struct kmem_cache *s;
        void *ret;

        if (unlikely(size > KMALLOC_MAX_CACHE_SIZE))  // size大于4MB
                return kmalloc_large(size, flags); // 分配的物理页面,更新lru状态等
 
        s = kmalloc_slab(size, flags); // slab分配器分配缓冲内存

        if (unlikely(ZERO_OR_NULL_PTR(s)))
                return s;

        ret = slab_alloc(s, NULL, flags, _RET_IP_, size);

        trace_kmalloc(_RET_IP_, ret, size, s->size, flags);

        ret = kasan_kmalloc(s, ret, size, flags); // 填充kasan

        return ret;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1003102.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号