aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-05-22 08:05:02 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-05-22 08:05:02 -0700
commit6633401dda1a4994174344c80685cd89c7d1e83c (patch)
tree1030eb9163145049102508b1efa047ba1de72ff5 /mm
parente52c02f76ae684f86f18f0fc7d7577e22a4d9318 (diff)
downloadhistory-6633401dda1a4994174344c80685cd89c7d1e83c.tar.gz
[PATCH] numa api: Add statistics
From: Andi Kleen <ak@suse.de> Add NUMA hit/miss statistics to page allocation and display them in sysfs. This is not 100% required for NUMA API, but without this it is very The overhead is quite low because all counters are per CPU and only happens when CONFIG_NUMA is defined.
Diffstat (limited to 'mm')
-rw-r--r--mm/page_alloc.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index e65925aac16eb9..86c00e43b51939 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -460,6 +460,32 @@ void drain_local_pages(void)
}
#endif /* CONFIG_PM */
+static void zone_statistics(struct zonelist *zonelist, struct zone *z)
+{
+#ifdef CONFIG_NUMA
+ unsigned long flags;
+ int cpu;
+ pg_data_t *pg = z->zone_pgdat;
+ pg_data_t *orig = zonelist->zones[0]->zone_pgdat;
+ struct per_cpu_pageset *p;
+
+ local_irq_save(flags);
+ cpu = smp_processor_id();
+ p = &z->pageset[cpu];
+ if (pg == orig) {
+ z->pageset[cpu].numa_hit++;
+ } else {
+ p->numa_miss++;
+ zonelist->zones[0]->pageset[cpu].numa_foreign++;
+ }
+ if (pg == NODE_DATA(numa_node_id()))
+ p->local_node++;
+ else
+ p->other_node++;
+ local_irq_restore(flags);
+#endif
+}
+
/*
* Free a 0-order page
*/
@@ -593,8 +619,10 @@ __alloc_pages(unsigned int gfp_mask, unsigned int order,
if (z->free_pages >= min ||
(!wait && z->free_pages >= z->pages_high)) {
page = buffered_rmqueue(z, order, gfp_mask);
- if (page)
+ if (page) {
+ zone_statistics(zonelist, z);
goto got_pg;
+ }
}
}
@@ -616,8 +644,10 @@ __alloc_pages(unsigned int gfp_mask, unsigned int order,
if (z->free_pages >= min ||
(!wait && z->free_pages >= z->pages_high)) {
page = buffered_rmqueue(z, order, gfp_mask);
- if (page)
+ if (page) {
+ zone_statistics(zonelist, z);
goto got_pg;
+ }
}
}
@@ -630,8 +660,10 @@ rebalance:
struct zone *z = zones[i];
page = buffered_rmqueue(z, order, gfp_mask);
- if (page)
+ if (page) {
+ zone_statistics(zonelist, z);
goto got_pg;
+ }
}
goto nopage;
}
@@ -658,8 +690,10 @@ rebalance:
if (z->free_pages >= min ||
(!wait && z->free_pages >= z->pages_high)) {
page = buffered_rmqueue(z, order, gfp_mask);
- if (page)
+ if (page) {
+ zone_statistics(zonelist, z);
goto got_pg;
+ }
}
}