• 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. }  
  • 相关阅读:
    http://www.oschina.net/translate/elasticsearch-getting-started?cmp
    http://www.mxchip.com/talk/news/jishuwenzhang/2014-09-11/67.html
    深入理解JVM—性能监控工具
    Windows7查看本地Java安装是否成功和路径的方法
    Eclipse 编译错误 Access restriction:The type *** is not accessible due to restriction on... 解决方案
    PSYoungGen /PSOldGen/PSPermGen区别
    深入浅出Java并发包—锁机制(三)
    深入浅出Java并发包—锁机制(二)
    【转】Spring 注解学习手札(超好的springmvc注解教程)
    解决java.lang.NoClassDefFoundError: org.jdom.Content
  • 原文地址:https://www.cnblogs.com/hehehaha/p/6332941.html
Copyright © 2020-2023  润新知