内存管理之memblock管理之移除块
2017-03-06 09:56
609 查看
此函数是整个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); } }
相关文章推荐
- 内存管理之memblock管理之移除块memblock_reserve
- 内存管理之memblock管理之移除块 memblock_free
- 内存管理之memblock管理之移除块 memblock_remove
- Java内存管理及对Java对象管理
- Java的内存管理实际上就是对象的管理
- java虚拟机内存管理机制(三):我主管写的一些jvm内存管理知识
- 内存管理之bootmem管理之free_all_bootmem
- linux内核内存管理学习之二(物理内存管理--伙伴系统)
- 手动内存管理项目转ARC管理项目
- WinCE线程和内存管理之内存管理
- iOS 非ARC基本内存管理系列 2-多对象内存管理(1)
- box2d 内存管理: b2Shape 的管理
- c++windows内核编程笔记day12 硬盘逻辑分区管理、文件管理、内存管理
- Linux的内存管理主要分为两部分:物理地址到虚拟地址的映射,内核内存分配管理(主要基于slab)。
- 操作系统内存管理——分区、页式、段式管理、段页式
- 内存管理学习之存储管理技术
- C++内存管理------>以对象管理资源(Effective C++)
- c#的内存管理(托管及未托管对象管理)
- c++windows内核编程笔记day12 硬盘逻辑分区管理、文件管理、内存管理
- os内存管理之页式存储管理 http://blog.163.com/he_haoyi/blog/static/118698376200991542415238/