diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/page_alloc.c | 78 |
1 files changed, 20 insertions, 58 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index eac31a6059c0..bfb73e025e02 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -3614,68 +3614,30 @@ static void build_zonelists_in_zone_order(pg_data_t *pgdat, int nr_nodes) | |||
3614 | zonelist->_zonerefs[pos].zone_idx = 0; | 3614 | zonelist->_zonerefs[pos].zone_idx = 0; |
3615 | } | 3615 | } |
3616 | 3616 | ||
3617 | #if defined(CONFIG_64BIT) | ||
3618 | /* | ||
3619 | * Devices that require DMA32/DMA are relatively rare and do not justify a | ||
3620 | * penalty to every machine in case the specialised case applies. Default | ||
3621 | * to Node-ordering on 64-bit NUMA machines | ||
3622 | */ | ||
3623 | static int default_zonelist_order(void) | ||
3624 | { | ||
3625 | return ZONELIST_ORDER_NODE; | ||
3626 | } | ||
3627 | #else | ||
3628 | /* | ||
3629 | * On 32-bit, the Normal zone needs to be preserved for allocations accessible | ||
3630 | * by the kernel. If processes running on node 0 deplete the low memory zone | ||
3631 | * then reclaim will occur more frequency increasing stalls and potentially | ||
3632 | * be easier to OOM if a large percentage of the zone is under writeback or | ||
3633 | * dirty. The problem is significantly worse if CONFIG_HIGHPTE is not set. | ||
3634 | * Hence, default to zone ordering on 32-bit. | ||
3635 | */ | ||
3617 | static int default_zonelist_order(void) | 3636 | static int default_zonelist_order(void) |
3618 | { | 3637 | { |
3619 | int nid, zone_type; | ||
3620 | unsigned long low_kmem_size, total_size; | ||
3621 | struct zone *z; | ||
3622 | int average_size; | ||
3623 | /* | ||
3624 | * ZONE_DMA and ZONE_DMA32 can be very small area in the system. | ||
3625 | * If they are really small and used heavily, the system can fall | ||
3626 | * into OOM very easily. | ||
3627 | * This function detect ZONE_DMA/DMA32 size and configures zone order. | ||
3628 | */ | ||
3629 | /* Is there ZONE_NORMAL ? (ex. ppc has only DMA zone..) */ | ||
3630 | low_kmem_size = 0; | ||
3631 | total_size = 0; | ||
3632 | for_each_online_node(nid) { | ||
3633 | for (zone_type = 0; zone_type < MAX_NR_ZONES; zone_type++) { | ||
3634 | z = &NODE_DATA(nid)->node_zones[zone_type]; | ||
3635 | if (populated_zone(z)) { | ||
3636 | if (zone_type < ZONE_NORMAL) | ||
3637 | low_kmem_size += z->managed_pages; | ||
3638 | total_size += z->managed_pages; | ||
3639 | } else if (zone_type == ZONE_NORMAL) { | ||
3640 | /* | ||
3641 | * If any node has only lowmem, then node order | ||
3642 | * is preferred to allow kernel allocations | ||
3643 | * locally; otherwise, they can easily infringe | ||
3644 | * on other nodes when there is an abundance of | ||
3645 | * lowmem available to allocate from. | ||
3646 | */ | ||
3647 | return ZONELIST_ORDER_NODE; | ||
3648 | } | ||
3649 | } | ||
3650 | } | ||
3651 | if (!low_kmem_size || /* there are no DMA area. */ | ||
3652 | low_kmem_size > total_size/2) /* DMA/DMA32 is big. */ | ||
3653 | return ZONELIST_ORDER_NODE; | ||
3654 | /* | ||
3655 | * look into each node's config. | ||
3656 | * If there is a node whose DMA/DMA32 memory is very big area on | ||
3657 | * local memory, NODE_ORDER may be suitable. | ||
3658 | */ | ||
3659 | average_size = total_size / | ||
3660 | (nodes_weight(node_states[N_MEMORY]) + 1); | ||
3661 | for_each_online_node(nid) { | ||
3662 | low_kmem_size = 0; | ||
3663 | total_size = 0; | ||
3664 | for (zone_type = 0; zone_type < MAX_NR_ZONES; zone_type++) { | ||
3665 | z = &NODE_DATA(nid)->node_zones[zone_type]; | ||
3666 | if (populated_zone(z)) { | ||
3667 | if (zone_type < ZONE_NORMAL) | ||
3668 | low_kmem_size += z->present_pages; | ||
3669 | total_size += z->present_pages; | ||
3670 | } | ||
3671 | } | ||
3672 | if (low_kmem_size && | ||
3673 | total_size > average_size && /* ignore small node */ | ||
3674 | low_kmem_size > total_size * 70/100) | ||
3675 | return ZONELIST_ORDER_NODE; | ||
3676 | } | ||
3677 | return ZONELIST_ORDER_ZONE; | 3638 | return ZONELIST_ORDER_ZONE; |
3678 | } | 3639 | } |
3640 | #endif /* CONFIG_64BIT */ | ||
3679 | 3641 | ||
3680 | static void set_zonelist_order(void) | 3642 | static void set_zonelist_order(void) |
3681 | { | 3643 | { |