]> git.hungrycats.org Git - linux/commitdiff
[PATCH] numa api: Add statistics
authorAndrew Morton <akpm@osdl.org>
Sat, 22 May 2004 15:05:02 +0000 (08:05 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Sat, 22 May 2004 15:05:02 +0000 (08:05 -0700)
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.

include/linux/mmzone.h
mm/page_alloc.c

index 51b8f3f67741f0330bfc4146d49557d630aa8627..f1e1a727acb29de9fcac5c50cdf161e546b2ede5 100644 (file)
@@ -52,6 +52,14 @@ struct per_cpu_pages {
 
 struct per_cpu_pageset {
        struct per_cpu_pages pcp[2];    /* 0: hot.  1: cold */
+#ifdef CONFIG_NUMA
+       unsigned long numa_hit;         /* allocated in intended node */
+       unsigned long numa_miss;        /* allocated in non intended node */
+       unsigned long numa_foreign;     /* was intended here, hit elsewhere */
+       unsigned long interleave_hit;   /* interleaver prefered this zone */
+       unsigned long local_node;       /* allocation from local node */
+       unsigned long other_node;       /* allocation from other node */
+#endif
 } ____cacheline_aligned_in_smp;
 
 #define ZONE_DMA               0
index e65925aac16eb9d4245c3c00d0660807e4841b0a..86c00e43b51939cd0045360793e2c3183e0d3090 100644 (file)
@@ -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;
+                       }
                }
        }