From 55d9ee81c53feb645e852686a43d5c7b68d4ff3f Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 27 Jul 2007 15:43:29 -0400 Subject: [PATCH] Memoryless nodes: introduce mask of nodes with memory It is necessary to know if nodes have memory since we have recently begun to add support for memoryless nodes. For that purpose we introduce a two new node states: N_HIGH_MEMORY and N_NORMAL_MEMORY. A node has its bit in N_HIGH_MEMORY set if it has any memory whatsoever. If a node has memory then it has at least one zone defined in its pgdat structure that is located in the pgdat itself. A node has its bit in N_NORMAL_MEMORY set if it has a lower zone than HIGH_MEM. This means it is possible to allocate memory that is not subject to kmap. N_HIGH_MEMORY and N_NORMAL_MEMORY can then be used in various places to insure that we do the right thing when we encounter a memoryless node. Signed-off-by: Lee Schermerhorn Signed-off-by: Nishanth Aravamudan Signed-off-by: Christoph Lameter Acked-by: Bob Picco Index: linux-2.6/include/linux/nodemask.h =================================================================== --- linux-2.6.orig/include/linux/nodemask.h 2007-07-31 21:09:33.000000000 -0700 +++ linux-2.6/include/linux/nodemask.h 2007-07-31 21:16:30.000000000 -0700 @@ -341,8 +341,10 @@ static inline void __nodes_remap(nodemas * Bitmasks that are kept for all the nodes. */ enum node_states { - N_POSSIBLE, /* The node could become online at some point */ - N_ONLINE, /* The node is online */ + N_POSSIBLE, /* The node could become online at some point */ + N_ONLINE, /* The node is online */ + N_NORMAL_MEMORY, /* The node has regular memory */ + N_HIGH_MEMORY, /* The node has regular or high memory */ NR_NODE_STATES }; Index: linux-2.6/mm/page_alloc.c =================================================================== --- linux-2.6.orig/mm/page_alloc.c 2007-07-31 21:09:17.000000000 -0700 +++ linux-2.6/mm/page_alloc.c 2007-07-31 21:18:29.000000000 -0700 @@ -2064,10 +2064,23 @@ static void build_zonelist_cache(pg_data static int __build_all_zonelists(void *dummy) { int nid; + enum zone_type zone; for_each_online_node(nid) { - build_zonelists(NODE_DATA(nid)); - build_zonelist_cache(NODE_DATA(nid)); + pg_data_t *pgdat = NODE_DATA(nid); + + build_zonelists(pgdat); + build_zonelist_cache(pgdat); + + /* Any memory on that node */ + if (pgdat->node_present_pages) + node_set_state(nid, N_HIGH_MEMORY); + + /* Any regular memory on that node ? */ + for (zone = 0; zone <= ZONE_NORMAL; zone++) + if (pgdat->node_zones[zone].present_pages) + node_set_state(nid, N_NORMAL_MEMORY); + } return 0; }