|
@@ -3614,68 +3614,30 @@ static void build_zonelists_in_zone_order(pg_data_t *pgdat, int nr_nodes)
|
|
|
zonelist->_zonerefs[pos].zone_idx = 0;
|
|
|
}
|
|
|
|
|
|
+#if defined(CONFIG_64BIT)
|
|
|
+/*
|
|
|
+ * Devices that require DMA32/DMA are relatively rare and do not justify a
|
|
|
+ * penalty to every machine in case the specialised case applies. Default
|
|
|
+ * to Node-ordering on 64-bit NUMA machines
|
|
|
+ */
|
|
|
+static int default_zonelist_order(void)
|
|
|
+{
|
|
|
+ return ZONELIST_ORDER_NODE;
|
|
|
+}
|
|
|
+#else
|
|
|
+/*
|
|
|
+ * On 32-bit, the Normal zone needs to be preserved for allocations accessible
|
|
|
+ * by the kernel. If processes running on node 0 deplete the low memory zone
|
|
|
+ * then reclaim will occur more frequency increasing stalls and potentially
|
|
|
+ * be easier to OOM if a large percentage of the zone is under writeback or
|
|
|
+ * dirty. The problem is significantly worse if CONFIG_HIGHPTE is not set.
|
|
|
+ * Hence, default to zone ordering on 32-bit.
|
|
|
+ */
|
|
|
static int default_zonelist_order(void)
|
|
|
{
|
|
|
- int nid, zone_type;
|
|
|
- unsigned long low_kmem_size, total_size;
|
|
|
- struct zone *z;
|
|
|
- int average_size;
|
|
|
- /*
|
|
|
- * ZONE_DMA and ZONE_DMA32 can be very small area in the system.
|
|
|
- * If they are really small and used heavily, the system can fall
|
|
|
- * into OOM very easily.
|
|
|
- * This function detect ZONE_DMA/DMA32 size and configures zone order.
|
|
|
- */
|
|
|
- /* Is there ZONE_NORMAL ? (ex. ppc has only DMA zone..) */
|
|
|
- low_kmem_size = 0;
|
|
|
- total_size = 0;
|
|
|
- for_each_online_node(nid) {
|
|
|
- for (zone_type = 0; zone_type < MAX_NR_ZONES; zone_type++) {
|
|
|
- z = &NODE_DATA(nid)->node_zones[zone_type];
|
|
|
- if (populated_zone(z)) {
|
|
|
- if (zone_type < ZONE_NORMAL)
|
|
|
- low_kmem_size += z->managed_pages;
|
|
|
- total_size += z->managed_pages;
|
|
|
- } else if (zone_type == ZONE_NORMAL) {
|
|
|
- /*
|
|
|
- * If any node has only lowmem, then node order
|
|
|
- * is preferred to allow kernel allocations
|
|
|
- * locally; otherwise, they can easily infringe
|
|
|
- * on other nodes when there is an abundance of
|
|
|
- * lowmem available to allocate from.
|
|
|
- */
|
|
|
- return ZONELIST_ORDER_NODE;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if (!low_kmem_size || /* there are no DMA area. */
|
|
|
- low_kmem_size > total_size/2) /* DMA/DMA32 is big. */
|
|
|
- return ZONELIST_ORDER_NODE;
|
|
|
- /*
|
|
|
- * look into each node's config.
|
|
|
- * If there is a node whose DMA/DMA32 memory is very big area on
|
|
|
- * local memory, NODE_ORDER may be suitable.
|
|
|
- */
|
|
|
- average_size = total_size /
|
|
|
- (nodes_weight(node_states[N_MEMORY]) + 1);
|
|
|
- for_each_online_node(nid) {
|
|
|
- low_kmem_size = 0;
|
|
|
- total_size = 0;
|
|
|
- for (zone_type = 0; zone_type < MAX_NR_ZONES; zone_type++) {
|
|
|
- z = &NODE_DATA(nid)->node_zones[zone_type];
|
|
|
- if (populated_zone(z)) {
|
|
|
- if (zone_type < ZONE_NORMAL)
|
|
|
- low_kmem_size += z->present_pages;
|
|
|
- total_size += z->present_pages;
|
|
|
- }
|
|
|
- }
|
|
|
- if (low_kmem_size &&
|
|
|
- total_size > average_size && /* ignore small node */
|
|
|
- low_kmem_size > total_size * 70/100)
|
|
|
- return ZONELIST_ORDER_NODE;
|
|
|
- }
|
|
|
return ZONELIST_ORDER_ZONE;
|
|
|
}
|
|
|
+#endif /* CONFIG_64BIT */
|
|
|
|
|
|
static void set_zonelist_order(void)
|
|
|
{
|