bootmem_free_node

该函数设置:

1.pgdata节点的成员

2.pgdata->zone的成员

3.初始化zone->free_area

4.初始化zone所包含的所有页对应的页框描述符page结构体

/*
为buddy系统设置为无可用的页。
初始化zone->free_area,设置为buddy系统中没有可用的页框。
*/
static void __init bootmem_free_node(int node, struct meminfo *mi)
    -->1.计算各个zone中的有效页框数及全部页框数(含空洞)
    -->free_area_init_node(node, zone_size, start_pfn, zhole_size);
        -->设置pglist_data结构体的成员(pgdat->node_start_pfn,node_spaned_pages,node_present_pages)
        /*
        为节点中的每一个页分配一个页框描述符page结构体,这些结构体所占用的内存
        调用bootmem分配器的API分配,alloc_bootmem_node
        */
        -->alloc_node_mem_map(pgdat); 
        -->free_area_init_core(pgdat, zones_size, zholes_size);
            -->unsigned long __meminitdata nr_kernel_pages;//内核可用的所有页框数
            -->unsigned long __meminitdata nr_all_pages;//所有页框数
            -->设置zone结构体的成员
            -->zone_pcp_init(zone);//初始化每CPU的冷热页缓存
            //把多个页框组织为一个pageblock,每个pageblock用几bit标记,为所有标记分配内存
            -->setup_usemap(pgdat, zone, size);
            -->init_currently_empty_zone(zone, zone_start_pfn,size, MEMMAP_EARLY);
                -->设置pglist_data->nr_zone
                -->zone_init_free_lists(zone);//初始化zone->free_area。设置为无空闲页可用
            -->memmap_init(size, nid, j, zone_start_pfn);
                -->memmap_init_zone((size), (nid), (zone), (start_pfn), MEMMAP_EARLY)
                    -->unsigned long highest_memmap_pfn//最大的页框号,线性映射区
                    -->struct page *page = pfn_to_page(pfn);
                    -->set_page_links(page, zone, nid, pfn);//设置page->flags
                    -->init_page_count(page);//page->_ncount=1
                    -->reset_page_mapcount(page); //page->_mapcount=-1
                    -->SetPageReserved(page); //设置page->flags PG_reserved位

 

注意上面的SetPageReserved(page)在代码中搜索不到该函数,在include/linux/page_flags.h中有下列宏用于定义page->flags相关的操作函数。

/*
 * Macros to create function definitions for page flags
 */
#define TESTPAGEFLAG(uname, lname)                    \
static inline int Page##uname(struct page *page)             \
            { return test_bit(PG_##lname, &page->flags); }

#define SETPAGEFLAG(uname, lname)                    \
static inline void SetPage##uname(struct page *page)            \
            { set_bit(PG_##lname, &page->flags); }

#define CLEARPAGEFLAG(uname, lname)                    \
static inline void ClearPage##uname(struct page *page)            \
            { clear_bit(PG_##lname, &page->flags); }

 

posted @ 2018-08-13 21:24  bluebluebluesky  阅读(239)  评论(0编辑  收藏  举报