build_all_zonelists

来源:互联网 发布:达内培训 php机构 编辑:程序博客网 时间:2024/06/05 19:46

关键函数
1.__build_all_zonelists()
2.nr_free_pagecache_pages()

数据结构关系

__build_all_zonelists(void *data):
对于UMA系统这个函数执行的子函数主要有以下几个:(CONFIG_HAVE_MEMORYLESS_NODES 没有配置)
for_each_online_node(nid) {//循环找到系统的所有节点
pg_data_t *pgdat = NODE_DATA(nid);
build_zonelists(pgdat);
build_zonelist_cache(pgdat);
}
for_each_possible_cpu(cpu) {
setup_pageset(&per_cpu(boot_pageset, cpu), 0);
1.build_zonelists(pg_data_t *pgdat)完成了节点pgdat上zonelists的初始化工作, 它建立了备用层次

结构zonelists
主要调用的函数为:
build_zonelists_node

2.build_zonelist_cache
static void build_zonelist_cache(pg_data_t *pgdat)
{
pgdat->node_zonelists[0].zlcache_ptr = NULL;
}
3.setup_pageset
setup_pageset初始化了per-CPU缓存(冷热页面)
参考:http://www.360doc.com/content/13/0401/19/11635678_275349211.shtml
boot_pageset:
在内核启动之初per_cpu机制还没有初始化,用于动态分配per_cpu变量的空间还没有分配,所以定义了

一个静态的per_cpu变量boot_pageset,用以暂时管理内存域的per_cpu缓存
static DEFINE_PER_CPU(struct per_cpu_pageset, boot_pageset);

define per_cpu(var, cpu) \

(*SHIFT_PERCPU_PTR(&(var), per_cpu_offset(cpu)))
通过上面获取per_cpu_pageset 后填充 per_cpu_pages
static void setup_pageset(struct per_cpu_pageset *p, unsigned long batch)
{
struct per_cpu_pages *pcp;
int migratetype;

memset(p, 0, sizeof(*p));

pcp = &p->pcp;
pcp->count = 0;
pcp->high = 6 * batch;
pcp->batch = max(1UL, 1 * batch);
for (migratetype = 0; migratetype < MIGRATE_PCPTYPES; migratetype++)
INIT_LIST_HEAD(&pcp->lists[migratetype]);
}
nr_free_zone_pages:

static unsigned long nr_free_zone_pages(int offset)
{
struct zoneref *z;
struct zone *zone;

/* Just pick one node, since fallback list is circular */unsigned long sum = 0;struct zonelist *zonelist = node_zonelist(numa_node_id(), GFP_KERNEL);for_each_zone_zonelist(zone, z, zonelist, offset) {    unsigned long size = zone->managed_pages;    unsigned long high = high_wmark_pages(zone);    if (size > high)        sum += size - high;}return sum;

}