aboutsummaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
authorMartin J. Bligh <mbligh@mbligh.org>2005-07-30 01:59:18 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-30 13:14:46 -0400
commite310fd43256b3cf4d37f6447b8f7413ca744657a (patch)
tree29537927762fd44459fa288b5241d4e79dbadedb /mm/page_alloc.c
parent5fa918b451f625870cd4275ca908b2392ee86a51 (diff)
[PATCH] Fix NUMA node sizing in nr_free_zone_pages
We are iterating over all nodes in nr_free_zone_pages(). Because the fallback zonelists contain all nodes in the system, and we walk all the zonelists, we're counting memory multiple times (once for each node). This caused us to make a size estimate of 32GB for an 8GB AMD64 box, which makes all the dirty ratio calculations, etc incorrect. There's still a further bug to fix from e820 holes causing overestimation as well, but this fix is separate, and good as is, and fixes one class of problems. Problem found by Badari, and tested by Ram Pai - thanks! Signed-off-by: Martin J. Bligh <mbligh@mbligh.org> Signed-off-by: Matt Dobson <colpatch@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c21
1 files changed, 10 insertions, 11 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 42bccfb8464d..8d088371196a 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1061,20 +1061,19 @@ unsigned int nr_free_pages_pgdat(pg_data_t *pgdat)
1061 1061
1062static unsigned int nr_free_zone_pages(int offset) 1062static unsigned int nr_free_zone_pages(int offset)
1063{ 1063{
1064 pg_data_t *pgdat; 1064 /* Just pick one node, since fallback list is circular */
1065 pg_data_t *pgdat = NODE_DATA(numa_node_id());
1065 unsigned int sum = 0; 1066 unsigned int sum = 0;
1066 1067
1067 for_each_pgdat(pgdat) { 1068 struct zonelist *zonelist = pgdat->node_zonelists + offset;
1068 struct zonelist *zonelist = pgdat->node_zonelists + offset; 1069 struct zone **zonep = zonelist->zones;
1069 struct zone **zonep = zonelist->zones; 1070 struct zone *zone;
1070 struct zone *zone;
1071 1071
1072 for (zone = *zonep++; zone; zone = *zonep++) { 1072 for (zone = *zonep++; zone; zone = *zonep++) {
1073 unsigned long size = zone->present_pages; 1073 unsigned long size = zone->present_pages;
1074 unsigned long high = zone->pages_high; 1074 unsigned long high = zone->pages_high;
1075 if (size > high) 1075 if (size > high)
1076 sum += size - high; 1076 sum += size - high;
1077 }
1078 } 1077 }
1079 1078
1080 return sum; 1079 return sum;