Commit 7ea1530a authored by Christoph Lameter's avatar Christoph Lameter Committed by Linus Torvalds

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: default avatarLee Schermerhorn <Lee.Schermerhorn@hp.com>
Signed-off-by: default avatarNishanth Aravamudan <nacc@us.ibm.com>
Signed-off-by: default avatarChristoph Lameter <clameter@sgi.com>
Acked-by: default avatarBob Picco <bob.picco@hp.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Mel Gorman <mel@skynet.ie>
Signed-off-by: default avatarYasunori Goto <y-goto@jp.fujitsu.com>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 13808910
...@@ -341,8 +341,14 @@ static inline void __nodes_remap(nodemask_t *dstp, const nodemask_t *srcp, ...@@ -341,8 +341,14 @@ static inline void __nodes_remap(nodemask_t *dstp, const nodemask_t *srcp,
* Bitmasks that are kept for all the nodes. * Bitmasks that are kept for all the nodes.
*/ */
enum node_states { enum node_states {
N_POSSIBLE, /* The node could become online at some point */ N_POSSIBLE, /* The node could become online at some point */
N_ONLINE, /* The node is online */ N_ONLINE, /* The node is online */
N_NORMAL_MEMORY, /* The node has regular memory */
#ifdef CONFIG_HIGHMEM
N_HIGH_MEMORY, /* The node has regular or high memory */
#else
N_HIGH_MEMORY = N_NORMAL_MEMORY,
#endif
NR_NODE_STATES NR_NODE_STATES
}; };
......
...@@ -217,6 +217,10 @@ int online_pages(unsigned long pfn, unsigned long nr_pages) ...@@ -217,6 +217,10 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
zone->zone_pgdat->node_present_pages += onlined_pages; zone->zone_pgdat->node_present_pages += onlined_pages;
setup_per_zone_pages_min(); setup_per_zone_pages_min();
if (onlined_pages) {
kswapd_run(zone_to_nid(zone));
node_set_state(zone_to_nid(zone), N_HIGH_MEMORY);
}
if (need_zonelists_rebuild) if (need_zonelists_rebuild)
build_all_zonelists(); build_all_zonelists();
...@@ -271,9 +275,6 @@ int add_memory(int nid, u64 start, u64 size) ...@@ -271,9 +275,6 @@ int add_memory(int nid, u64 start, u64 size)
if (!pgdat) if (!pgdat)
return -ENOMEM; return -ENOMEM;
new_pgdat = 1; new_pgdat = 1;
ret = kswapd_run(nid);
if (ret)
goto error;
} }
/* call arch's memory hotadd */ /* call arch's memory hotadd */
......
...@@ -2080,14 +2080,35 @@ static void build_zonelist_cache(pg_data_t *pgdat) ...@@ -2080,14 +2080,35 @@ static void build_zonelist_cache(pg_data_t *pgdat)
#endif /* CONFIG_NUMA */ #endif /* CONFIG_NUMA */
/* Any regular memory on that node ? */
static void check_for_regular_memory(pg_data_t *pgdat)
{
#ifdef CONFIG_HIGHMEM
enum zone_type zone_type;
for (zone_type = 0; zone_type <= ZONE_NORMAL; zone_type++) {
struct zone *zone = &pgdat->node_zones[zone_type];
if (zone->present_pages)
node_set_state(zone_to_nid(zone), N_NORMAL_MEMORY);
}
#endif
}
/* return values int ....just for stop_machine_run() */ /* return values int ....just for stop_machine_run() */
static int __build_all_zonelists(void *dummy) static int __build_all_zonelists(void *dummy)
{ {
int nid; int nid;
for_each_online_node(nid) { for_each_online_node(nid) {
build_zonelists(NODE_DATA(nid)); pg_data_t *pgdat = NODE_DATA(nid);
build_zonelist_cache(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);
check_for_regular_memory(pgdat);
} }
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment