aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Lameter <clameter@sgi.com>2008-02-05 01:29:16 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-05 12:44:18 -0500
commita7f75e25860ac0a7b70cf6e14c37618d2d2bb890 (patch)
tree12f651d69e72159c6f904e007973874e912853bb
parent08e7d9b557299ba6ce57165ce8df310780bd681c (diff)
vmstat: small revisions to refresh_cpu_vm_stats()
1. Add comments explaining how the function can be called. 2. Collect global diffs in a local array and only spill them once into the global counters when the zone scan is finished. This means that we only touch each global counter once instead of each time we fold cpu counters into zone counters. Signed-off-by: Christoph Lameter <clameter@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/vmstat.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/mm/vmstat.c b/mm/vmstat.c
index e8d846f57774..9ffc573ceb6e 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -284,6 +284,10 @@ EXPORT_SYMBOL(dec_zone_page_state);
284/* 284/*
285 * Update the zone counters for one cpu. 285 * Update the zone counters for one cpu.
286 * 286 *
287 * The cpu specified must be either the current cpu or a processor that
288 * is not online. If it is the current cpu then the execution thread must
289 * be pinned to the current cpu.
290 *
287 * Note that refresh_cpu_vm_stats strives to only access 291 * Note that refresh_cpu_vm_stats strives to only access
288 * node local memory. The per cpu pagesets on remote zones are placed 292 * node local memory. The per cpu pagesets on remote zones are placed
289 * in the memory local to the processor using that pageset. So the 293 * in the memory local to the processor using that pageset. So the
@@ -299,7 +303,7 @@ void refresh_cpu_vm_stats(int cpu)
299{ 303{
300 struct zone *zone; 304 struct zone *zone;
301 int i; 305 int i;
302 unsigned long flags; 306 int global_diff[NR_VM_ZONE_STAT_ITEMS] = { 0, };
303 307
304 for_each_zone(zone) { 308 for_each_zone(zone) {
305 struct per_cpu_pageset *p; 309 struct per_cpu_pageset *p;
@@ -311,15 +315,19 @@ void refresh_cpu_vm_stats(int cpu)
311 315
312 for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) 316 for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
313 if (p->vm_stat_diff[i]) { 317 if (p->vm_stat_diff[i]) {
318 unsigned long flags;
319 int v;
320
314 local_irq_save(flags); 321 local_irq_save(flags);
315 zone_page_state_add(p->vm_stat_diff[i], 322 v = p->vm_stat_diff[i];
316 zone, i);
317 p->vm_stat_diff[i] = 0; 323 p->vm_stat_diff[i] = 0;
324 local_irq_restore(flags);
325 atomic_long_add(v, &zone->vm_stat[i]);
326 global_diff[i] += v;
318#ifdef CONFIG_NUMA 327#ifdef CONFIG_NUMA
319 /* 3 seconds idle till flush */ 328 /* 3 seconds idle till flush */
320 p->expire = 3; 329 p->expire = 3;
321#endif 330#endif
322 local_irq_restore(flags);
323 } 331 }
324#ifdef CONFIG_NUMA 332#ifdef CONFIG_NUMA
325 /* 333 /*
@@ -351,6 +359,10 @@ void refresh_cpu_vm_stats(int cpu)
351 drain_zone_pages(zone, p->pcp + 1); 359 drain_zone_pages(zone, p->pcp + 1);
352#endif 360#endif
353 } 361 }
362
363 for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
364 if (global_diff[i])
365 atomic_long_add(global_diff[i], &vm_stat[i]);
354} 366}
355 367
356#endif 368#endif