linux内存管理之 ION 内存管理器浅析Ⅱ(system contig heap)

linux内存管理之 ION 内存管理器浅析Ⅱ(system contig heap)目录1systemcontigheap与systemheap2systemcontigheap创建3systemcontigheap内存分配4systemcontigheap内存释放1systemcontigheap与systemheap从代码中我们看到systemcontigheap与systemheap同属一个文件中,ion_system_heap.c相同点:它们都是根据用户传递的字节len,转换成order,从buddy中

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

目录

1 system contig heap 与 system heap

2 system contig heap创建

3 system contig heap内存分配

4 system contig heap内存释放


1 system contig heap 与 system heap

从代码中我们看到system contig heap与system heap同属一个文件中,ion_system_heap.c

相同点:它们都是根据用户传递的字节len,转换成order,从buddy中申请内存页

不同点:

  1. contig heap申请的是连续内存页,最大能到order 10(受限于buddy)。而system heap就只能通过order 8/4/0三种拼凑出来,凑够用户需要的内存
  2. contig heap没有自己的内存pool,释放时直接返还给buddy。system heap有自己的pool(分为order 8/4/0)。

2 system contig heap创建

//指定heap name,heap type和ops
static struct ion_heap *__ion_system_contig_heap_create(void)
{
	struct ion_heap *heap;

	heap = kzalloc(sizeof(*heap), GFP_KERNEL);
	if (!heap)
		return ERR_PTR(-ENOMEM);
	heap->ops = &kmalloc_ops;
	heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG;
	heap->name = "ion_system_contig_heap";
	return heap;
}

static int ion_system_contig_heap_create(void)
{
	struct ion_heap *heap;

	heap = __ion_system_contig_heap_create();
	if (IS_ERR(heap))
		return PTR_ERR(heap);
	//添加到ion dev,并且在/d/ion/heaps目录下创建debug节点,节点名以heap name命名:"ion_system_contig_heap"
	ion_device_add_heap(heap);
	return 0;
}
//开机过程中,驱动加载时创建,当然这只是参考代码,具体还要看不同平台的具体实现
device_initcall(ion_system_contig_heap_create);

Jetbrains全家桶1年46,售后保障稳定

3 system contig heap内存分配

static struct ion_heap_ops kmalloc_ops = {
	.allocate = ion_system_contig_heap_allocate,
	.free = ion_system_contig_heap_free,
	.map_kernel = ion_heap_map_kernel,
	.unmap_kernel = ion_heap_unmap_kernel,
	.map_user = ion_heap_map_user,
};

ion_system_contig_heap_allocate()函数分配:直接从buddy中分配连续的内存块

static int ion_system_contig_heap_allocate(struct ion_heap *heap,
					   struct ion_buffer *buffer,
					   unsigned long len,
					   unsigned long flags)
{
	int order = get_order(len);
	struct page *page;
	struct sg_table *table;
	unsigned long i;
	int ret;
    //直接从buddy中分配内存页
    //分配的内存页是可能比实际请求的大的,比如申请len是3个page大小,那么order就为2,实际申请了4个page
	page = alloc_pages(low_order_gfp_flags, order);
	if (!page)
		return -ENOMEM;
    //将申请到的连续内存页分割成一页页
	split_page(page, order);

    //由于在分配时可能多分配,因此需要将多余的page释放回去。比如申请3个page,实际分配了4个
	len = PAGE_ALIGN(len);
	for (i = len >> PAGE_SHIFT; i < (1 << order); i++)
		__free_page(page + i);
    //接着申请sg_table
	table = kmalloc(sizeof(*table), GFP_KERNEL);
	if (!table) {
		ret = -ENOMEM;
		goto free_pages;
	}
    //由于是连续的内存,因此只需要申请一个scatterlist
	ret = sg_alloc_table(table, 1, GFP_KERNEL);
	if (ret)
		goto free_table;
    //将连续内存首页地址存到sg_table中
	sg_set_page(table->sgl, page, len, 0);

	buffer->sg_table = table;

	return 0;

free_table:
	kfree(table);
free_pages:
	for (i = 0; i < len >> PAGE_SHIFT; i++)
		__free_page(page + i);

	return ret;
}

4 system contig heap内存释放

ion_system_contig_heap_free()函数:将内存全部返还给buddy

static void ion_system_contig_heap_free(struct ion_buffer *buffer)
{
	struct sg_table *table = buffer->sg_table;
	struct page *page = sg_page(table->sgl);
	unsigned long pages = PAGE_ALIGN(buffer->size) >> PAGE_SHIFT;
	unsigned long i;
    //释放时就直接将内存页归还给buddy
	for (i = 0; i < pages; i++)
		__free_page(page + i);
	sg_free_table(table);
	kfree(table);
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/203533.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 树莓派4B +远程SSH+远程桌面[通俗易懂]

    树莓派4B +远程SSH+远程桌面[通俗易懂]一、有线SSH连接树莓派我的实验环境是笔记本电脑+树莓派4B具体步骤为:1、电脑连接上无线网络,将电脑网线连接树莓派2、打开如下界面3、双击WLAN——>>点击属性——>>再点击共享选择以太网4、双击以太网——>>点击属性——>>IPV4——>>在选择下面的…

    2022年5月15日
    108
  • 可变长子网掩码划分例题_最小生成树是什么

    可变长子网掩码划分例题_最小生成树是什么北极的某区域共有 n 座村庄,每座村庄的坐标用一对整数 (x,y) 表示。为了加强联系,决定在村庄之间建立通讯网络,使每两座村庄之间都可以直接或间接通讯。通讯工具可以是无线电收发机,也可以是卫星设备。无线电收发机有多种不同型号,不同型号的无线电收发机有一个不同的参数 d,两座村庄之间的距离如果不超过 d,就可以用该型号的无线电收发机直接通讯,d 值越大的型号价格越贵。现在要先选择某一种型号的无线电收发机,然后统一给所有村庄配备,数量不限,但型号都是 相同的。配备卫星设备的两座村庄无论相距多远都可以直

    2022年8月9日
    5
  • js 闭包传参_JavaScript闭包演示

    js 闭包传参_JavaScript闭包演示有个网友问了个问题,如下的html,为什么每次输出都是5,而不是点击每个p,就alert出对应的1,2,3,4,5。闭包演示functioninit(){varpAry=document.getElementsByTagName(“p”);for(vari=0;ipAry[i].onclick=function(){alert(i);}}}产品一产品二产品三产品四产品五解决方…

    2022年6月15日
    66
  • Nginx 防攻击安全配置

    Nginx 防攻击安全配置网站安全配置(Nginx)防止网站被攻击(包括使用了CDN加速之后的配置方法)网站被攻击是一个永恒不变的话题,网站攻击的方式也是一个永恒不变的老套路。找几百个电脑(肉鸡),控制这些电脑同时访问你的网站,超过你网站的最大承载能力,然后你就瘫了。方法虽然老土,但却一直都很管用,就像怎么打败美帝国主义,最简单的方法就是13亿中国人都移民去美帝,吃他的、用他的、花他的,直接能让美帝破产,压根不需要用…

    2022年6月16日
    68
  • ModelAndView详解

    ModelAndView详解ModelAndView详解WebServlet应用服务器Spring浏览器 ModelAndView的构造方法有7个。但是它们都是相通的。这里使用无参构造函数来举例说明如何构造ModelAndView实例。   ModelAndView类别就如其名称所示,是代表了MVCWeb程序中Model与View的对象,不过它只是方便您一次返回这两个对象的h

    2022年7月18日
    28

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号