| From 7f9cfb31030737a7fc9a1cbca3fd01bec184c849 Mon Sep 17 00:00:00 2001 |
| From: Bo Liu <bo-liu@hotmail.com> |
| Date: Tue, 18 Aug 2009 14:11:19 -0700 |
| Subject: mm: build_zonelists(): move clear node_load[] to __build_all_zonelists() |
| |
| From: Bo Liu <bo-liu@hotmail.com> |
| |
| commit 7f9cfb31030737a7fc9a1cbca3fd01bec184c849 upstream. |
| |
| If node_load[] is cleared everytime build_zonelists() is |
| called,node_load[] will have no help to find the next node that should |
| appear in the given node's fallback list. |
| |
| Because of the bug, zonelist's node_order is not calculated as expected. |
| This bug affects on big machine, which has asynmetric node distance. |
| |
| [synmetric NUMA's node distance] |
| 0 1 2 |
| 0 10 12 12 |
| 1 12 10 12 |
| 2 12 12 10 |
| |
| [asynmetric NUMA's node distance] |
| 0 1 2 |
| 0 10 12 20 |
| 1 12 10 14 |
| 2 20 14 10 |
| |
| This (my bug) is very old but no one has reported this for a long time. |
| Maybe because the number of asynmetric NUMA is very small and they use |
| cpuset for customizing node memory allocation fallback. |
| |
| [akpm@linux-foundation.org: fix CONFIG_NUMA=n build] |
| Signed-off-by: Bo Liu <bo-liu@hotmail.com> |
| Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> |
| Cc: Mel Gorman <mel@csn.ul.ie> |
| Cc: Christoph Lameter <cl@linux-foundation.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| mm/page_alloc.c | 4 +++- |
| 1 file changed, 3 insertions(+), 1 deletion(-) |
| |
| --- a/mm/page_alloc.c |
| +++ b/mm/page_alloc.c |
| @@ -2342,7 +2342,6 @@ static void build_zonelists(pg_data_t *p |
| prev_node = local_node; |
| nodes_clear(used_mask); |
| |
| - memset(node_load, 0, sizeof(node_load)); |
| memset(node_order, 0, sizeof(node_order)); |
| j = 0; |
| |
| @@ -2451,6 +2450,9 @@ static int __build_all_zonelists(void *d |
| { |
| int nid; |
| |
| +#ifdef CONFIG_NUMA |
| + memset(node_load, 0, sizeof(node_load)); |
| +#endif |
| for_each_online_node(nid) { |
| pg_data_t *pgdat = NODE_DATA(nid); |
| |