linux内存管理(十六)

您所在的位置:网站首页 pageaddress linux内存管理(十六)

linux内存管理(十六)

2023-02-20 21:10| 来源: 网络整理| 查看: 265

1. kmalloc

kmalloc函数解析:

static __always_inline void *kmalloc(size_t size, gfp_t flags) { if (__builtin_constant_p(size)) { #ifndef CONFIG_SLOB unsigned int index; #endif if (size > KMALLOC_MAX_CACHE_SIZE) return kmalloc_large(size, flags);//大于8k,从伙伴系统中分配内存 #ifndef CONFIG_SLOB index = kmalloc_index(size);//计算出需要从slab的那个层分配内存 if (!index) return ZERO_SIZE_PTR; return kmem_cache_alloc_trace( //小于8k,从slab管理器中分配内存 kmalloc_caches[kmalloc_type(flags)][index], flags, size); #endif } return __kmalloc(size, flags); }

kmalloc首先判断需要申请的内存大小,如果比较大,则调用kmalloc_large从伙伴系统中分配内存;如果比较小,则从slab管理器中分配内存。分界线是KMALLOC_MAX_CACHE_SIZE,根据我这边的实际情况,我们使用的是SLUB,也就是CONFIG_SLUB=y,所以定义如下:

#define KMALLOC_MAX_CACHE_SIZE (1UL void *ret = kmalloc_order(size, flags, order);//从伙伴系统分配页面内存的核心函数 trace_kmalloc(_RET_IP_, ret, size, PAGE_SIZE //分支预测,分配成功 ret = page_address(page);//获取页面的虚拟地址 mod_lruvec_page_state(page, NR_SLAB_UNRECLAIMABLE_B, PAGE_SIZE \ __typeof__(x) __page = x; \ u64 __idx = ((u64)__page - VMEMMAP_START) / sizeof(struct page);\ u64 __addr = PAGE_OFFSET + (__idx * PAGE_SIZE); \ (void *)__tag_set((const void *)__addr, page_kasan_tag(__page));\ }) static inline const void *__tag_set(const void *addr, u8 tag) { u64 __addr = (u64)addr & ~__tag_shifted(0xff); return (const void *)(__addr | __tag_shifted(tag)); } #define __tag_shifted(tag) 0UL #define VMEMMAP_START (-VMEMMAP_SIZE - SZ_2M)

根据这些宏,我们可以把lowmem_page_address函数看做:

static __always_inline void *lowmem_page_address(const struct page *page) { u64 __idx = ((u64)page - VMEMMAP_START) / sizeof(struct page); u64 __addr = PAGE_OFFSET + (__idx * PAGE_SIZE); return __addr ; }

看到这里我有点懵逼,需要捋一捋。

1.2 kmem_cache_alloc_trace(kmalloc_caches[kmalloc_type(flags)][index],flags, size) static __always_inline void *kmem_cache_alloc_trace(struct kmem_cache *s, gfp_t flags, size_t size) { void *ret = kmem_cache_alloc(s, flags); ret = kasan_kmalloc(s, ret, size, flags); return ret; }

kmem_cache_alloc_trace主要是调用kmem_cache_alloc从slab分配内存块,这个函数我们在之前的slab管理器中讲过,这里就不在多说了。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3