- 论坛徽章:
- 0
|
start_kernel(void) -> build_all_zonelists() -> build_zonelists
(1)
/mm/page_alloc.c
1674 void __init build_all_zonelists(void)
1675 {
1676 int i;
1677
1678 for_each_online_node(i)
1679 build_zonelists(NODE_DATA(i));
1680 printk("Built %i zonelists\n", num_online_nodes());
1681 cpuset_init_current_mems_allowed();
1682 }
struct zonelist {
271 struct zone *zones[MAX_NUMNODES * MAX_NR_ZONES + 1]; // NULL delimited
272 };
和2.6的内核对比一下,2.6中结构变成:
+---------+ zone_list
pgdat->node_zonelist |zone_list|-----> +--------+
+---------+ | nodes*3+
3个 + +
+---------+ | +
| n.d.h | +--------+
按优先级排列zonelist.
1584 static void __init build_zonelists(pg_data_t *pgdat)
1585 {
1586 int i, j, k, node, local_node;
1587 int prev_node, load;
1588 struct zonelist *zonelist;
1589 nodemask_t used_mask;
1590
1591 /* initialize zonelists */
1592 for (i = 0; i node_zonelists + i;
1594 zonelist->zones[0] = NULL;
1595 }
1596
1597 /* NUMA-aware ordering of nodes */
1598 local_node = pgdat->node_id;
1599 load = num_online_nodes();
1600 prev_node = local_node;
1601 nodes_clear(used_mask);
1602 while ((node = find_next_best_node(local_node, &used_mask)) >= 0) {
1603 int distance = node_distance(local_node, node);
1604
1605 /*
1606 * If another node is sufficiently far away then it is better
1607 * to reclaim pages in a zone before going off node.
1608 */
1609 if (distance > RECLAIM_DISTANCE)
1610 zone_reclaim_mode = 1;
1611
1612 /*
1613 * We don't want to pressure a particular node.
1614 * So adding penalty to the first node in same
1615 * distance group to make it round-robin.
1616 */
1617
1618 if (distance != node_distance(local_node, prev_node))
1619 node_load[node] += load;
1620 prev_node = node;
1621 load--;
1622 for (i = 0; i node_zonelists + i;
1624 for (j = 0; zonelist->zones[j] != NULL; j++);
1625
1626 k = highest_zone(i);
1627
1628 j = build_zonelists_node(NODE_DATA(node), zonelist, j, k);
1629 zonelist->zones[j] = NULL;
1630 }
1631 }
1632 }
(2)build_zonelists > build_zonelists_node
1487 static int __init build_zonelists_node(pg_data_t *pgdat,
1488 struct zonelist *zonelist, int nr_zones, int zone_type)
1489 {
1490 struct zone *zone;
1491
1492 BUG_ON(zone_type > ZONE_HIGHMEM);
1493
1494 do {
1495 zone = pgdat->node_zones + zone_type;
1496 if (populated_zone(zone)) {
1497 #ifndef CONFIG_HIGHMEM
1498 BUG_ON(zone_type > ZONE_NORMAL);
1499 #endif
1500 zonelist->zones[nr_zones++] = zone;
1501 check_highest_zone(zone_type);
1502 }
1503 zone_type--;
1504
1505 } while (zone_type >= 0);
1506 return nr_zones;
1507 }
(3)build_zonelists > find_next_best_node
5499 static int find_next_best_node(int node, unsigned long *used_nodes)
5500 {
5501 int i, n, val, min_val, best_node = 0;
5502
5503 min_val = INT_MAX;
5504
5505 for (i = 0; i
/* This is a matrix with "distances" between nodes, they should be
58 * proportional to the memory access latency ratios.
59 */
node_distance()
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/17526/showart_1079655.html |
|