diff options
Diffstat (limited to 'mm')
| -rw-r--r-- | mm/page_alloc.c | 7 | ||||
| -rw-r--r-- | mm/vmstat.c | 12 | 
2 files changed, 19 insertions, 0 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 9b8e6243a52..5485f0ef4ec 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5916,6 +5916,7 @@ static int __meminit __zone_pcp_update(void *data)  		local_irq_save(flags);  		if (pcp->count > 0)  			free_pcppages_bulk(zone, pcp->count, pcp); +		drain_zonestat(zone, pset);  		setup_pageset(pset, batch);  		local_irq_restore(flags);  	} @@ -5932,10 +5933,16 @@ void __meminit zone_pcp_update(struct zone *zone)  void zone_pcp_reset(struct zone *zone)  {  	unsigned long flags; +	int cpu; +	struct per_cpu_pageset *pset;  	/* avoid races with drain_pages()  */  	local_irq_save(flags);  	if (zone->pageset != &boot_pageset) { +		for_each_online_cpu(cpu) { +			pset = per_cpu_ptr(zone->pageset, cpu); +			drain_zonestat(zone, pset); +		}  		free_percpu(zone->pageset);  		zone->pageset = &boot_pageset;  	} diff --git a/mm/vmstat.c b/mm/vmstat.c index 05e3a991374..2f11309955c 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -495,6 +495,18 @@ void refresh_cpu_vm_stats(int cpu)  			atomic_long_add(global_diff[i], &vm_stat[i]);  } +void drain_zonestat(struct zone *zone, struct per_cpu_pageset *pset) +{ +	int i; + +	for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) +		if (pset->vm_stat_diff[i]) { +			int v = pset->vm_stat_diff[i]; +			pset->vm_stat_diff[i] = 0; +			atomic_long_add(v, &zone->vm_stat[i]); +			atomic_long_add(v, &vm_stat[i]); +		} +}  #endif  #ifdef CONFIG_NUMA  |