diff options
author | Yasunori Goto <y-goto@jp.fujitsu.com> | 2006-07-04 05:57:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-04 13:24:57 -0400 |
commit | dd8041f16b117f63f40fb844d6cdebe8b03514d2 (patch) | |
tree | 40521ea93b2034484ceb1f16af7d47bfa1b35b6c /arch/ia64/mm/discontig.c | |
parent | 31304c909e6945b005af62cd55a582e9c010a0b4 (diff) |
[PATCH] Fix copying of pgdat array on each node for ia64 memory hotplug
I found a bug in memory hot-add code for ia64.
IA64's code has copies of pgdat's array on each node to reduce memory
access over crossing node. This array is used by NODE_DATA() macro. When
new node is hot-added, this pgdat's array should be updated and copied on
new node too.
However, I used for_each_online_node() in scatter_node_data() to copy
it. This meant its array is not copied on new node.
Because initialization of structures for new node was halfway,
so online_node_map couldn't be set at this time.
To copy arrays on new node, I changed it to check value of pgdat_list[]
which is source array of copies. I tested this patch with my Memory Hotadd
emulation on Tiger4. This patch is for 2.6.17-git20.
Signed-off-by: Yasunori Goto <y-goto@jp.fujitsu.com>
Cc: "Luck, Tony" <tony.luck@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ia64/mm/discontig.c')
-rw-r--r-- | arch/ia64/mm/discontig.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index 525b082eb661..99bd9e30db96 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c | |||
@@ -313,9 +313,19 @@ static void __meminit scatter_node_data(void) | |||
313 | pg_data_t **dst; | 313 | pg_data_t **dst; |
314 | int node; | 314 | int node; |
315 | 315 | ||
316 | for_each_online_node(node) { | 316 | /* |
317 | dst = LOCAL_DATA_ADDR(pgdat_list[node])->pg_data_ptrs; | 317 | * for_each_online_node() can't be used at here. |
318 | memcpy(dst, pgdat_list, sizeof(pgdat_list)); | 318 | * node_online_map is not set for hot-added nodes at this time, |
319 | * because we are halfway through initialization of the new node's | ||
320 | * structures. If for_each_online_node() is used, a new node's | ||
321 | * pg_data_ptrs will be not initialized. Insted of using it, | ||
322 | * pgdat_list[] is checked. | ||
323 | */ | ||
324 | for_each_node(node) { | ||
325 | if (pgdat_list[node]) { | ||
326 | dst = LOCAL_DATA_ADDR(pgdat_list[node])->pg_data_ptrs; | ||
327 | memcpy(dst, pgdat_list, sizeof(pgdat_list)); | ||
328 | } | ||
319 | } | 329 | } |
320 | } | 330 | } |
321 | 331 | ||