KERNEL VERSION:
STEP 1:
How is the zone be initiated?
start_kernel() > setup_arch() > paging init() > zone_sizes_init() > free_area_init_nodes() > free_area_init_node() > free_area_init_core() > init_currently_empty_zone() > zone_init_free_lists()
static void __meminit zone_init_free_lists(struct zone *zone)
{
int order, t;
for_each_migratetype_order(order, t) {
INIT_LIST_HEAD(&zone->free_area[order].free_list[t]);
zone->free_area[order].nr_free = 0;
}
}
|
__meminit int init_currently_empty_zone(struct zone *zone,
unsigned long zone_start_pfn,
unsigned long size,
enum memmap_context context)
{
struct pglist_data *pgdat = zone->zone_pgdat;
int ret;
ret = zone_wait_table_init(zone, size);
if (ret)
return ret;
pgdat->nr_zones = zone_idx(zone) + 1;
zone->zone_start_pfn = zone_start_pfn;
mminit_dprintk(MMINIT_TRACE, "memmap_init",
"Initialising map node %d zone %lu pfns %lu -> %lu\n",
pgdat->node_id,
(unsigned long)zone_idx(zone),
zone_start_pfn, (zone_start_pfn + size));
zone_init_free_lists(zone);
return 0;
}
|
STEP 2:
The kernel performs optimization if only a single page is to be allocated, that is, if the allocation order is 0 because 2^0 = 1. The page is not taken directly from the buddy system but from the per-CPU page cache.
STEP 3:
For buddy system, there are two helper function, which are the core of buddy system. They are:
buffered_rmqueue() and __rmqueue().
STEP 3:
related function, __free_one_page(), expand(), __rmqueue_smallest(), __rmqueue_fallback(), free_pages(), zone_init_free_lists().
阅读(1379) | 评论(1) | 转发(0) |