aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Lameter <clameter@sgi.com>2007-10-16 04:25:29 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:42:58 -0400
commit7ea1530ab3fdfa85441061909cc8040e84776fd4 (patch)
treef3af0f8ed40a6df90bdbb9396d6163d59798a821
parent13808910713a98cc1159291e62cdfec92cc94d05 (diff)
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 regardless of the type of mmemory. 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 ZONE_HIGHMEM. 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. [akpm@linux-foundation.org: build fix] [Lee.Schermerhorn@hp.com: update N_HIGH_MEMORY node state for memory hotadd] [y-goto@jp.fujitsu.com: Fix memory hotplug + sparsemem build] Signed-off-by: Lee Schermerhorn <Lee.Schermerhorn@hp.com> Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com> Signed-off-by: Christoph Lameter <clameter@sgi.com> Acked-by: Bob Picco <bob.picco@hp.com> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Mel Gorman <mel@skynet.ie> Signed-off-by: Yasunori Goto <y-goto@jp.fujitsu.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/linux/nodemask.h10
-rw-r--r--mm/memory_hotplug.c7
-rw-r--r--mm/page_alloc.c25
3 files changed, 35 insertions, 7 deletions
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
index 583e6b843d2a..ccee962f3559 100644
--- a/include/linux/nodemask.h
+++ b/include/linux/nodemask.h
@@ -341,8 +341,14 @@ static inline void __nodes_remap(nodemask_t *dstp, const nodemask_t *srcp,
341 * Bitmasks that are kept for all the nodes. 341 * Bitmasks that are kept for all the nodes.
342 */ 342 */
343enum node_states { 343enum node_states {
344 N_POSSIBLE, /* The node could become online at some point */ 344 N_POSSIBLE, /* The node could become online at some point */
345 N_ONLINE, /* The node is online */ 345 N_ONLINE, /* The node is online */
346 N_NORMAL_MEMORY, /* The node has regular memory */
347#ifdef CONFIG_HIGHMEM
348 N_HIGH_MEMORY, /* The node has regular or high memory */
349#else
350 N_HIGH_MEMORY = N_NORMAL_MEMORY,
351#endif
346 NR_NODE_STATES 352 NR_NODE_STATES
347}; 353};
348 354
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index df9d554bea30..9c12ae5e3695 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -217,6 +217,10 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
217 zone->zone_pgdat->node_present_pages += onlined_pages; 217 zone->zone_pgdat->node_present_pages += onlined_pages;
218 218
219 setup_per_zone_pages_min(); 219 setup_per_zone_pages_min();
220 if (onlined_pages) {
221 kswapd_run(zone_to_nid(zone));
222 node_set_state(zone_to_nid(zone), N_HIGH_MEMORY);
223 }
220 224
221 if (need_zonelists_rebuild) 225 if (need_zonelists_rebuild)
222 build_all_zonelists(); 226 build_all_zonelists();
@@ -271,9 +275,6 @@ int add_memory(int nid, u64 start, u64 size)
271 if (!pgdat) 275 if (!pgdat)
272 return -ENOMEM; 276 return -ENOMEM;
273 new_pgdat = 1; 277 new_pgdat = 1;
274 ret = kswapd_run(nid);
275 if (ret)
276 goto error;
277 } 278 }
278 279
279 /* call arch's memory hotadd */ 280 /* call arch's memory hotadd */
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 0cc5b3e198e5..07dfd89992fa 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2080,14 +2080,35 @@ static void build_zonelist_cache(pg_data_t *pgdat)
2080 2080
2081#endif /* CONFIG_NUMA */ 2081#endif /* CONFIG_NUMA */
2082 2082
2083/* Any regular memory on that node ? */
2084static void check_for_regular_memory(pg_data_t *pgdat)
2085{
2086#ifdef CONFIG_HIGHMEM
2087 enum zone_type zone_type;
2088
2089 for (zone_type = 0; zone_type <= ZONE_NORMAL; zone_type++) {
2090 struct zone *zone = &pgdat->node_zones[zone_type];
2091 if (zone->present_pages)
2092 node_set_state(zone_to_nid(zone), N_NORMAL_MEMORY);
2093 }
2094#endif
2095}
2096
2083/* return values int ....just for stop_machine_run() */ 2097/* return values int ....just for stop_machine_run() */
2084static int __build_all_zonelists(void *dummy) 2098static int __build_all_zonelists(void *dummy)
2085{ 2099{
2086 int nid; 2100 int nid;
2087 2101
2088 for_each_online_node(nid) { 2102 for_each_online_node(nid) {
2089 build_zonelists(NODE_DATA(nid)); 2103 pg_data_t *pgdat = NODE_DATA(nid);
2090 build_zonelist_cache(NODE_DATA(nid)); 2104
2105 build_zonelists(pgdat);
2106 build_zonelist_cache(pgdat);
2107
2108 /* Any memory on that node */
2109 if (pgdat->node_present_pages)
2110 node_set_state(nid, N_HIGH_MEMORY);
2111 check_for_regular_memory(pgdat);
2091 } 2112 }
2092 return 0; 2113 return 0;
2093} 2114}