k/v/malloc
看以前的驱动hook代码,发现分配20Bytes的内存竟然使用vmalooc;这些人当时写代码太随意了,再次记录一下vmalloc kmalloc kmem_cache_alloc alloc_page 等的区别
Kmalloc: kmalloc是基于kmem_cache_alloc、 slab实现的,但是kmalloc 可以分配非固定大小的内存,kmem_cache_alloc 只能是固定的!!kmalloc 分配95Bytes时 虽然调用的是cache_alloc(96)从而对外提供了分配非固定大小的内存;kmem_cache_alloc大小都是 32 64 96 128 等Bytes
/** * kmalloc - allocate memory * @size: how many bytes of memory are required. * @flags: the type of memory to allocate. * * kmalloc is the normal method of allocating memory * for objects smaller than page size in the kernel. * * The @flags argument may be one of: * * %GFP_USER - Allocate memory on behalf of user. May sleep. * * %GFP_KERNEL - Allocate normal kernel ram. May sleep. * * %GFP_ATOMIC - Allocation will not sleep. May use emergency pools. * For example, use this inside interrupt handlers. * * %GFP_HIGHUSER - Allocate pages from high memory. * * %GFP_NOIO - Do not do any I/O at all while trying to get memory. * * %GFP_NOFS - Do not make any fs calls while trying to get memory. * * %GFP_NOWAIT - Allocation will not sleep. * * %__GFP_THISNODE - Allocate node-local memory only. * * %GFP_DMA - Allocation suitable for DMA. * Should only be used for kmalloc() caches. Otherwise, use a * slab created with SLAB_DMA. * * Also it is possible to set different flags by OR'ing * in one or more of the following additional @flags: * * %__GFP_COLD - Request cache-cold pages instead of * trying to return cache-warm pages. * * %__GFP_HIGH - This allocation has high priority and may use emergency pools. * * %__GFP_NOFAIL - Indicate that this allocation is in no way allowed to fail * (think twice before using). * * %__GFP_NORETRY - If memory is not immediately available, * then give up at once. * * %__GFP_NOWARN - If allocation fails, don't issue any warnings. * * %__GFP_REPEAT - If allocation fails initially, try once more before failing. * * There are other flags available as well, but these are not intended * for general use, and so are not documented here. For a full list of * potential flags, always refer to linux/gfp.h. */ /*__builtin_constant_p 判断是否为常量 believe that this asks the compiler whether its argument evaluates to a constant value. For instance, __builtin_constant_p(1234) has a value of 1, whereas __builtin_constant_p(x), where `x` is a variable, has a value of 0.This is sometimes useful when writing highly-optimized code.*/ static __always_inline void *kmalloc(size_t size, gfp_t flags) { if (__builtin_constant_p(size)) {//是否为常量 if (size > KMALLOC_MAX_CACHE_SIZE)// 大于 kmalloc cache size,就通过 alloc_pages 分配page 然后映射出虚拟内核地址 return kmalloc_large(size, flags); #ifndef CONFIG_SLOB if (!(flags & GFP_DMA)) { int index = kmalloc_index(size); if (!index) return ZERO_SIZE_PTR; return kmem_cache_alloc_trace(kmalloc_caches[index], flags, size);//通过 kmem_cache_alloc 分配除内存 比如kmalloc-32 kmalloc-64 } #endif } //动态数值:通过slab 等 return __kmalloc(size, flags); } /** * __do_kmalloc - allocate memory * @size: how many bytes of memory are required. * @flags: the type of memory to allocate (see kmalloc). * @caller: function caller for debug tracking of the caller */ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags, unsigned long caller) { struct kmem_cache *cachep; void *ret; cachep = kmalloc_slab(size, flags);// 也会校验 size的大小,超过kmalloc的大小,认为是错误的,通过size 返回kmalloc_cache的index if (unlikely(ZERO_OR_NULL_PTR(cachep))) return cachep; ret = slab_alloc(cachep, flags, caller); kasan_kmalloc(cachep, ret, size, flags); trace_kmalloc(caller, ret, size, cachep->size, flags); return ret; } /* * Find the kmem_cache structure that serves a given size of * allocation */ struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags) { int index; if (unlikely(size > KMALLOC_MAX_SIZE)) { WARN_ON_ONCE(!(flags & __GFP_NOWARN)); return NULL; } if (size <= 192) { if (!size) return ZERO_SIZE_PTR; index = size_index[size_index_elem(size)]; } else index = fls(size - 1); #ifdef CONFIG_ZONE_DMA if (unlikely((flags & GFP_DMA))) return kmalloc_dma_caches[index]; #endif return kmalloc_caches[index]; }
Vmalloc:可以看奔跑吧linux 内核这本书:
1,vmalloc分配的一般为高端内存,只有当内存不够的时候才分配低端内存;kmallco从低端内存分配。
2,vmalloc分配的物理地址一般不连续,而kmalloc分配的地址连续,两者分配的虚拟地址都是连续的;
3,vmalloc分配的一般为大块内存,而kmaooc一般分配的为小块内存,(一般不超过128k);
/* * vmalloc - allocate virtually contiguous memory * * @size: allocation size * * Allocate enough pages to cover @size from the page level * allocator and map them into contiguous kernel virtual space. * * For tight control over page level allocator and protection flags * use __vmalloc() instead. */ void *vmalloc(unsigned long size) { return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL); }
void *__vmalloc_node_range(unsigned long size, unsigned long align, unsigned long start, unsigned long end, gfp_t gfp_mask, pgprot_t prot, unsigned long vm_flags, int node, const void *caller) { struct vm_struct *area; void *addr; unsigned long real_size = size; size = PAGE_ALIGN(size);//page 对其,也就是size 是10Bytes,结果还是分配一个页 注意效率啊 if (!size || (size >> PAGE_SHIFT) > totalram_pages) goto fail; ------------------ area = __get_vm_area_node(size, align, VM_ALLOC | VM_UNINITIALIZED | vm_flags, start, end, node, gfp_mask, caller); ----- addr = __vmalloc_area_node(area, gfp_mask, prot, node); ----------------------------return addr; ---------- }
http代理服务器(3-4-7层代理)-网络事件库公共组件、内核kernel驱动 摄像头驱动 tcpip网络协议栈、netfilter、bridge 好像看过!!!!
但行好事 莫问前程
--身高体重180的胖子
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南