当前位置: 首页 > Linux kernrl, 内存管理 > 正文

内存管理器(十二)kernel内存管理—-kmalloc/kfree

内存管理器(十二)kernel内存管理—-kmalloc/kfree

前言

上一篇说了页的获取与释放,既然是内核内存管理,内核自然也有自己的一套内存分配与释放函数。go on!

kmalloc( )–分配函数

这个函数是内核中用来分配内存的函数,它和malloc很像,当时这里多了一个flags标记。用它可以获得以字节为单位的一块内核内存。当然如果希望得到以页为单位的内存还是用__get_free_page()吧。


这里赋上一小段内核注释

/*kmalloc - allocate memory
* @size: how many bytes of memory are required.
* @flags: the type of memory to allocate.

*/

/*简单的说明了两个参数,一个是内存的大小,一个是标识,不知道标识是什么没有关系,一会说*/

 

static __always_inline void *kmalloc(size_t size, gfp_t flags)
{
if (__builtin_constant_p(size)) {
if (size > KMALLOC_MAX_CACHE_SIZE)
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);
}
#endif
}
return __kmalloc(size, flags);
}

下来说标识吧,一会儿再接着分析这个函数。

gfp_mask标志

其实再上次说页分配的时候也用到这个标识了,但是这里我们详细 说下。

先看下这里的源码注释,这里已经写了一些标识解释了,原则还是用什么学什么。


/* 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.
*                             尝试分配内存的时候不使用任何IO,不做任何页的交换
* %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.
*                      从DMA分配区开始分配内存,但是一般只有在分配高速缓存的时候才使用,毕竟直接寻址的区域并不大,为了保证效率(个人觉得Linux两大特点1:一切皆文件。 2:效率第一)
* 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.
*/

/*这里还注释了几句,这里的标识并不是完全的标识,所有的标识都在(linux/gfp.h)

因为kmalloc 牵扯到slab 缓存机制,暂且浅尝辄止,等后续明白了slab 之后再来看具体实现

kfree( )

这是一些释放的函数。


/*
* Common kmalloc functions provided by all allocators
*/
void * __must_check __krealloc(const void *, size_t, gfp_t);
void * __must_check krealloc(const void *, size_t, gfp_t);
void kfree(const void *);
void kzfree(const void *);
size_t ksize(const void *);

源代码中提供了很多,这个阶段我们只要会用就OK

这就想当与我们glibc  中的free 函数很类似,今天暂且不详细说,后边会分析源码的。

如果分配的空间不是kmalloc()分配的,我们一定不能使用这个函数释放,这将会导致严重的后果,但是这里调用free(NULL)确实安全的。

说了这么多,写个内核模块玩玩,全当消遣


#include<linux/module.h>
#include<linux/mm_types.h>
#include<linux/gfp.h>
#include<linux/mm.h>
#include<linux/slab.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("zmrlinux");
MODULE_DESCRIPTION("something about kmalloc");

static int __init KMALLOC(void){
char *temp;
printk("I want to malloc \n");
temp = (char *)kmalloc(sizeof(char) * 100,GFP_KERNEL);
if(NULL == temp){
printk("ERROR:alloc failed\n");
return -1;
}else{
printk("I malloc is OK\n");
}
kfree(temp);
return 0;
}

static void __exit KMALLOC_out(void){

printk("GOODBYE \n");

}

module_init(KMALLOC);
module_exit(KMALLOC_out);

&nbsp;

/*Makfile*/

obj-m := page_malloc.o
CURRENT_PATH := ${shell pwd}
CURRENT_KERNEL_PATH := ${shell uname -r}
LINUX_KERNEL_PATH := /usr/src/kernels/$(CURRENT_KERNEL_PATH)

all:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
rm *.o rm *.ko

&nbsp;

2015-11-06 18:11:21 的屏幕截图

 

OK !Done!!

本文固定链接: http://zmrlinux.com/2015/11/06/%e5%86%85%e5%ad%98%e7%ae%a1%e7%90%86%e5%99%a8%ef%bc%88%e5%8d%81%e4%ba%8c%ef%bc%89kernel%e5%86%85%e5%ad%98%e7%ae%a1%e7%90%86-kmallockfree/ | Kernel & Me

该日志由 root 于2015年11月06日发表在 Linux kernrl, 内存管理 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: 内存管理器(十二)kernel内存管理—-kmalloc/kfree | Kernel & Me