感谢支持
我们一直在努力

Linux内存管理之活动内存区

Linux内存活动区域其实就是全局变量e820中的内存块做了相关的检查和对其处理后的区域。在管理区初始化等地方有用到。


数据结构


  1. struct node_active_region {  

  2.     unsigned long start_pfn;  

  3.     unsigned long end_pfn;  

  4.     int nid;  

  5. };  

初始化


活动内存的初始化工作在setup_arch()->initmem_init()->e820_register_active_regions()


  1. /* Walk the e820 map and register active regions within a node */  

  2. void __init e820_register_active_regions(int nid, unsigned long start_pfn,  

  3.                      unsigned long last_pfn)  

  4. {  

  5.     unsigned long ei_startpfn;  

  6.     unsigned long ei_endpfn;  

  7.     int i;  

  8.   

  9.     for (i = 0; i < e820.nr_map; i++)  

  10.         if (e820_find_active_region(&e820.map[i],/*从全局变量e820中查找活动区*/  

  11.                         start_pfn, last_pfn,  

  12.                         &ei_startpfn, &ei_endpfn))  

  13.             add_active_range(nid, ei_startpfn, ei_endpfn);/*加入活动区*/  

  14. }  

 


  1. /* 

  2.  * Finds an active region in the address range from start_pfn to last_pfn and 

  3.  * returns its range in ei_startpfn and ei_endpfn for the e820 entry. 

  4.  */  

  5. int __init e820_find_active_region(const struct e820entry *ei,  

  6.                   unsigned long start_pfn,  

  7.                   unsigned long last_pfn,  

  8.                   unsigned long *ei_startpfn,  

  9.                   unsigned long *ei_endpfn)  

  10. {  

  11.     u64 align = PAGE_SIZE;  

  12.   

  13.     *ei_startpfn = round_up(ei->addr, align) >> PAGE_SHIFT;  

  14.     *ei_endpfn = round_down(ei->addr + ei->size, align) >> PAGE_SHIFT;  

  15.   

  16.     /* Skip map entries smaller than a page */  

  17.     if (*ei_startpfn >= *ei_endpfn)  

  18.         return 0;  

  19.   

  20.     /* Skip if map is outside the node */  

  21.     if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||  

  22.                     *ei_startpfn >= last_pfn)  

  23.         return 0;  

  24.   

  25.     /* Check for overlaps */  

  26.     if (*ei_startpfn < start_pfn)  

  27.         *ei_startpfn = start_pfn;  

  28.     if (*ei_endpfn > last_pfn)  

  29.         *ei_endpfn = last_pfn;  

  30.   

  31.     return 1;  

  32. }  

 


  1. /*添加活动区域,需要对原有的进行检查*/  

  2. void __init add_active_range(unsigned int nid, unsigned long start_pfn,  

  3.                         unsigned long end_pfn)  

  4. {  

  5.     int i;  

  6.   

  7.     mminit_dprintk(MMINIT_TRACE, “memory_register”,  

  8.             “Entering add_active_range(%d, %#lx, %#lx) “  

  9.             “%d entries of %d used\n”,  

  10.             nid, start_pfn, end_pfn,  

  11.             nr_nodemap_entries, MAX_ACTIVE_REGIONS);  

  12. //not set macro   

  13.     mminit_validate_memmodel_limits(&start_pfn, &end_pfn);  

  14.   

  15.     /* Merge with existing active regions if possible */  

  16.     for (i = 0; i < nr_nodemap_entries; i++) {  

  17.         if (early_node_map[i].nid != nid)  

  18.             continue;  

  19.   

  20.         /* Skip if an existing region covers this new one */  

  21.         if (start_pfn >= early_node_map[i].start_pfn &&  

  22.                 end_pfn <= early_node_map[i].end_pfn)  

  23.             return;  

  24.   

  25.         /* Merge forward if suitable */  

  26.         if (start_pfn <= early_node_map[i].end_pfn &&  

  27.                 end_pfn > early_node_map[i].end_pfn) {  

  28.             early_node_map[i].end_pfn = end_pfn;  

  29.             return;  

  30.         }  

  31.   

  32.         /* Merge backward if suitable */  

  33.         if (start_pfn < early_node_map[i].end_pfn &&  

  34.                 end_pfn >= early_node_map[i].start_pfn) {  

  35.             early_node_map[i].start_pfn = start_pfn;  

  36.             return;  

  37.         }  

  38.     }  

  39.   

  40.     /* Check that early_node_map is large enough */  

  41.     if (i >= MAX_ACTIVE_REGIONS) {  

  42.         printk(KERN_CRIT “More than %d memory regions, truncating\n”,  

  43.                             MAX_ACTIVE_REGIONS);  

  44.         return;  

  45.     }  

  46.   

  47.     early_node_map[i].nid = nid;  

  48.     early_node_map[i].start_pfn = start_pfn;  

  49.     early_node_map[i].end_pfn = end_pfn;  

  50.     nr_nodemap_entries = i + 1;  

  51. }  

赞(0) 打赏
转载请注明出处:服务器评测 » Linux内存管理之活动内存区
分享到: 更多 (0)

听说打赏我的人,都进福布斯排行榜啦!

支付宝扫一扫打赏

微信扫一扫打赏