x86内存节点初始化的问题。
时间:2010-04-30
来源:互联网
内核版本2.6.24
对于某个节点的内存初始化:
[start_kernel->zone_sizes_init->free_area_init_nodes->free_area_init_node]
void __meminit free_area_init_node(int nid, struct pglist_data *pgdat,
unsigned long *zones_size, unsigned long node_start_pfn,
unsigned long *zholes_size)
{
pgdat->node_id = nid;
pgdat->node_start_pfn = node_start_pfn;
calculate_node_totalpages(pgdat, zones_size, zholes_size);
alloc_node_mem_map(pgdat);
free_area_init_core(pgdat, zones_size, zholes_size);
}
其中calculate_node_totalpages计算了该节点的内存总数,而alloc_node_mem_map里分配了该节点的页面描述符数组[pgdat->node_mem_map数组的内存分配]
函数free_area_init_core则是对该节点的每个区[DMA,NORMAL,HIGH]的的结构进行初始化。
在free_area_init_core中打印了以下的一些信息:
Entering add_active_range(0, 0, 3276 0 entries of 256 used
Zone PFN ranges:
DMA 0 -> 4096
Normal 4096 -> 32768
HighMem 32768 -> 32768
Movable zone start PFN for each node
early_node_map[1] active PFN ranges
0: 0 -> 32768
On node 0 totalpages: 32768
DMA zone: 32 pages used for memmap
DMA zone: 0 pages reserved
DMA zone: 4064 pages, LIFO batch:0
Normal zone: 224 pages used for memmap
Normal zone: 28448 pages, LIFO batch:7
HighMem zone: 0 pages used for memmap
Movable zone: 0 pages used for memmap
DMI present.
而free_area_init_core得部分代码是:
static void __meminit free_area_init_core(struct pglist_data *pgdat,
unsigned long *zones_size, unsigned long *zholes_size)
{
......//省略
for (j = 0; j < MAX_NR_ZONES; j++) {
struct zone *zone = pgdat->node_zones + j;
unsigned long size, realsize, memmap_pages;
size = zone_spanned_pages_in_node(nid, j, zones_size);
realsize = size - zone_absent_pages_in_node(nid, j,
zholes_size);
memmap_pages = (size * sizeof(struct page)) >> PAGE_SHIFT;
if (realsize >= memmap_pages) {
realsize -= memmap_pages;
printk(KERN_DEBUG
" %s zone: %lu pages used for memmap\n",
zone_names[j], memmap_pages);
} else
printk(KERN_WARNING
" %s zone: %lu pages exceeds realsize %lu\n",
zone_names[j], memmap_pages, realsize);
......//省略
}
其中计算区间[struct zone]的可用页面数页面realsize时,减去了memmap_pages的数量,而这个数量是本节点页面描述符数组的内存大小。
上面提到过内存节点初始化时就已经对本节点的所有页面描述符数组分配了内存。且这块内存得分配是优先在NORMAL区内[x86事实上也在该区内]。即在本函数里并没有真的分配内存,但
是这里计算节点可用页面数时,每个区间都减去了本区间页面描述符数组的内存大小。
我的虚拟机配置是128M的内存,计算的结果:
DMA zone: 32 pages used for memmap
DMA zone: 0 pages reserved
DMA zone: 4064 pages, LIFO batch:0
即这里的32个页面应该是在normal区内,而不是DMA区的内存。
以这种方式计算的结果就是区间可用页面数是不精确的。
我想知道,内核为什么不精确的去计算可用页面呢?
对于某个节点的内存初始化:
[start_kernel->zone_sizes_init->free_area_init_nodes->free_area_init_node]
void __meminit free_area_init_node(int nid, struct pglist_data *pgdat,
unsigned long *zones_size, unsigned long node_start_pfn,
unsigned long *zholes_size)
{
pgdat->node_id = nid;
pgdat->node_start_pfn = node_start_pfn;
calculate_node_totalpages(pgdat, zones_size, zholes_size);
alloc_node_mem_map(pgdat);
free_area_init_core(pgdat, zones_size, zholes_size);
}
其中calculate_node_totalpages计算了该节点的内存总数,而alloc_node_mem_map里分配了该节点的页面描述符数组[pgdat->node_mem_map数组的内存分配]
函数free_area_init_core则是对该节点的每个区[DMA,NORMAL,HIGH]的的结构进行初始化。
在free_area_init_core中打印了以下的一些信息:
Entering add_active_range(0, 0, 3276 0 entries of 256 used
Zone PFN ranges:
DMA 0 -> 4096
Normal 4096 -> 32768
HighMem 32768 -> 32768
Movable zone start PFN for each node
early_node_map[1] active PFN ranges
0: 0 -> 32768
On node 0 totalpages: 32768
DMA zone: 32 pages used for memmap
DMA zone: 0 pages reserved
DMA zone: 4064 pages, LIFO batch:0
Normal zone: 224 pages used for memmap
Normal zone: 28448 pages, LIFO batch:7
HighMem zone: 0 pages used for memmap
Movable zone: 0 pages used for memmap
DMI present.
而free_area_init_core得部分代码是:
static void __meminit free_area_init_core(struct pglist_data *pgdat,
unsigned long *zones_size, unsigned long *zholes_size)
{
......//省略
for (j = 0; j < MAX_NR_ZONES; j++) {
struct zone *zone = pgdat->node_zones + j;
unsigned long size, realsize, memmap_pages;
size = zone_spanned_pages_in_node(nid, j, zones_size);
realsize = size - zone_absent_pages_in_node(nid, j,
zholes_size);
memmap_pages = (size * sizeof(struct page)) >> PAGE_SHIFT;
if (realsize >= memmap_pages) {
realsize -= memmap_pages;
printk(KERN_DEBUG
" %s zone: %lu pages used for memmap\n",
zone_names[j], memmap_pages);
} else
printk(KERN_WARNING
" %s zone: %lu pages exceeds realsize %lu\n",
zone_names[j], memmap_pages, realsize);
......//省略
}
其中计算区间[struct zone]的可用页面数页面realsize时,减去了memmap_pages的数量,而这个数量是本节点页面描述符数组的内存大小。
上面提到过内存节点初始化时就已经对本节点的所有页面描述符数组分配了内存。且这块内存得分配是优先在NORMAL区内[x86事实上也在该区内]。即在本函数里并没有真的分配内存,但
是这里计算节点可用页面数时,每个区间都减去了本区间页面描述符数组的内存大小。
我的虚拟机配置是128M的内存,计算的结果:
DMA zone: 32 pages used for memmap
DMA zone: 0 pages reserved
DMA zone: 4064 pages, LIFO batch:0
即这里的32个页面应该是在normal区内,而不是DMA区的内存。
以这种方式计算的结果就是区间可用页面数是不精确的。
我想知道,内核为什么不精确的去计算可用页面呢?
作者: new_new_one 发布时间: 2010-04-30
怎么代码前的空格都没了啊,也不能编辑颜色。
作者: new_new_one 发布时间: 2010-04-30
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28