LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1038|回复: 1

x86内存节点初始化的问题。

[复制链接]
发表于 2010-4-29 23:47:57 | 显示全部楼层 |阅读模式
内核版本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区的内存。

以这种方式计算的结果就是区间可用页面数是不精确的。

我想知道,内核为什么不精确的去计算可用页面呢?
 楼主| 发表于 2010-4-29 23:51:04 | 显示全部楼层
怎么代码前的空格都没了啊,也不能编辑颜色。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表