首页 > 系统相关 >内存管理之memblock管理之移除块

内存管理之memblock管理之移除块

时间:2023-06-04 13:07:05浏览次数:40  
标签:region base 内存 移除 type memblock rgn size


此函数是整个memblock中分配和释放内存的核心函数,主要是对region操作。详细实现如下:


static int __init_memblock memblock_remove_range(struct memblock_type *type,
					  phys_addr_t base, phys_addr_t size)
{
	int start_rgn, end_rgn;
	int i, ret;

//先确定移除的逻辑块所在的region,这步就是隔离isolate操作。
	ret = memblock_isolate_range(type, base, size, &start_rgn, &end_rgn);
	if (ret)
		return ret;

//把整个region从指定类型中移除。
	for (i = end_rgn - 1; i >= start_rgn; i--)
		memblock_remove_region(type, i);
	return 0;
}
 
 
/**
 * memblock_isolate_range - isolate given range into disjoint memblocks


把给出的范围内的逻辑块从以所在的块中脱离出来,这样会增加一个新的region。


* @type: memblock type to isolate range for
 * @base: base of range to isolate
 * @size: size of range to isolate
 * @start_rgn: out parameter for the start of isolated region
 * @end_rgn: out parameter for the end of isolated region
 *
 * Walk @type and ensure that regions don't cross the boundaries defined by
 * [@base,@base+@size).  Crossing regions are split at the boundaries,
 * which may create at most two more regions.  The index of the first
 * region inside the range is returned in *@start_rgn and end in *@end_rgn.
 *
 * RETURNS:
 * 0 on success, -errno on failure.
 */
 
region[min, max]
 
pre -->  memory:  min<--------------|----------------|-------------------->max


示例:

0x1000----------0x5000-----------0x8000---------------0xc0000
 
base:0x5000, size:0x3000,
 
 
 
region1[min, 0x5000]        region2[0x8000, max]
 
now -->  memory: min<----------->        hole     <------------------->max
 
0x1000--------0x5000             0x8000-------------0xc0000


 


static int memblock_isolate_range(struct memblock_type *type,
					phys_addr_t base, phys_addr_t size,
					int *start_rgn, int *end_rgn)
{
	phys_addr_t end = base + memblock_cap_size(base, &size);
	int idx;
	struct memblock_region *rgn;

	*start_rgn = *end_rgn = 0;

	if (!size)
		return 0;

	/* we'll create at most two more regions 太多region,目前最大支持128个*/
	while (type->cnt + 2 > type->max)
		if (memblock_double_array(type, base, size) < 0)
			return -ENOMEM;
//依次对每个region确定大小和覆盖范围。


for_each_memblock_type(type, rgn) {
		phys_addr_t rbase = rgn->base;
		phys_addr_t rend = rbase + rgn->size;


		if (rbase >= end)
			break;
		if (rend <= base)
			continue;


		if (rbase < base) {
			/*
			 * @rgn intersects from below.  Split and continue
			 * to process the next region - the new top half.
			 */
			rgn->base = base;
			rgn->size -= base - rbase;
			type->total_size -= base - rbase;
插入新的region
memblock_insert_region(type, idx, rbase, base - rbase,
					       memblock_get_region_node(rgn),
					       rgn->flags);
		} else if (rend > end) {
			/*
			 * @rgn intersects from above.  Split and redo the
			 * current region - the new bottom half.
			 */
			rgn->base = end;
			rgn->size -= end - rbase;
			type->total_size -= end - rbase;


另外一种插入方式


memblock_insert_region(type, idx--, rbase, end - rbase,
					       memblock_get_region_node(rgn),
					       rgn->flags);
		} else {
			/* @rgn is fully contained, record it */
			if (!*end_rgn)
				*start_rgn = idx;
			*end_rgn = idx + 1;
		}
	}


	return 0;
}



static void memblock_remove_region(struct memblock_type *type, unsigned long r)
{
	type->total_size -= type->regions[r].size;
	更新大小


memmove(&type->regions[r], &type->regions[r + 1],
		(type->cnt - (r + 1)) * sizeof(type->regions[r]));
	type->cnt--;


更新总的region大小

	/* Special case for empty arrays */
	if (type->cnt == 0) {
		WARN_ON(type->total_size != 0);
		type->cnt = 1;
		type->regions[0].base = 0;
		type->regions[0].size = 0;
		type->regions[0].flags = 0;
		memblock_set_region_node(&type->regions[0], MAX_NUMNODES);
	}
}

标签:region,base,内存,移除,type,memblock,rgn,size
From: https://blog.51cto.com/u_11860992/6410370

相关文章

  • Python潮流周刊#5:并发一百万个任务要用多少内存?
    你好,我是猫哥。这里记录每周值得分享的Python及通用技术内容,部分为英文,已在小标题注明。(标题取自其中一则分享,不代表全部内容都是该主题,特此声明。)博客原文:https://pythoncat.top/posts/2023-06-03-weekly5文章&教程1、并发一百万个任务要用多少内存?(英文)文中测试了主流的编......
  • linux 内存管理 ------ malloc 的内存分配
     低于128K的内存分配采用具有内存池缓存机制的brk方式,可以减少缺页中断、系统调用的次数。高于128K时采用匿名内存映射区的mmap方式,避免产生太大的内存碎片 如果分配后的虚拟内存没有被访问的话,虚拟内存是不会映射到物理内存的,这样就不会占用物理内存了。只有在访问已分配......
  • Java内存模型
    一、Java内存模型简介1.Java内存模型的“底层原理”从Java代码到CPU指令的变化过程是怎样的?最开始,我们编写的Java代码,即*.Java文件在执行编译Javac命令后,从刚才的*.Java文件会变出一个新的Java字节码文件,即*.class文件JVM会执行刚才生成的*.class字节码文件,并把字节码文......
  • 多线程-线程池与java内存模型
    多线程-线程池与java内存模型线程池的使用(思路:什么是线程池->他的基本构造以及参数含义->如何使用,使用过程中需要注意什么->有哪些好用的工具类)线程池的基笨概念:首先看一下的继承关系,其次看他的状态,它是利用int的高三位表示状态,比如111表示能接受任务,具体看下面第二章图接下来看......
  • 浪潮信息发布G7系列SAP HANA一体机,挑战内存计算极限性能
    2023年5月30日,浪潮信息“智算开新局·创新机”全国巡展济南站正式启航。会上,浪潮信息重磅发布基于G7算力平台的新一代SAPHANA一体机,为企业提供高性能、高可靠、高稳定性和绿色节能的数据平台。该方案针对 SAPHANA应用进行了深入优化,在SAP最新发布的IntelSapphireRapids双路计......
  • Presto——本质上是和spark内存计算框架一样 但不负责数据存储
    Presto入门介绍1,Presto基本认识1.1定义Presto是一个分布式的查询引擎,本身并不存储数据,但是可以接入多种数据源,并且支持跨数据源的级联查询。Presto是一个OLAP的工具,擅长对海量数据进行复杂的分析;但是对于OLTP场景,并不是Presto所擅长,所以不要把Presto当做数据库来使用。和大家熟悉......
  • 整数在内存中的天才存储方案
    加法和减法是计算机中最基本的运算,计算机时时刻刻都离不开它们,所以它们由硬件直接支持。为了提高加减法的运算效率,硬件电路要设计得尽量简单。对于有符号数,内存要区分符号位和数值位,对于人脑来说,很容易辨别,但是对于计算机来说,就要设计专门的电路:有符号加、减,这无疑增加了硬件的复......
  • Java的内存回收
     Java的内存回收http://blog.sina.com.cn/s/blog_4c925dca0100ilk0.html ......
  • 【C语言】动态内存管理函数的 深度解析 #是不是对数组不能变大变小而烦恼呢?学会动态内
    前言动态内存管理函数可以说很好用,但是有些小危险。所谓动态内存分配,就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不像数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序要求......
  • linux服务器cache占用内存过高导致内存不足
    问题描述linux服务器内存不足触发监控报警。K8S在创建pod之后启动失败,日志报错如下: 问题检查登录服务器发现服务器8G内存正在被使用的和空闲内存大概4G,还有大概4G被cache占用   这个cache占用了大量内存,那么这个cache时干什么用的?Linux中的缓存称为PageCache。它......