diff options
Diffstat (limited to 'mm/vmstat.c')
-rw-r--r-- | mm/vmstat.c | 20 |
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 |