mm: page-writeback: fix page state calculation in throttle_vm_writeout

It was found that a number of tasks were blocked in the reclaim path
(throttle_vm_writeout) for seconds, because of vmstat_diff not being
synced in time. Fix that by adding a new function
global_page_state_snapshot.

Signed-off-by: Vinayak Menon <vinmenon@codeaurora.org>
Change-Id: Iec167635ad724a55c27bdbd49eb8686e7857216c
This commit is contained in:
Vinayak Menon 2015-03-26 11:58:45 +05:30
parent 1802f7bfc3
commit 7da4414ce5
2 changed files with 25 additions and 0 deletions

View file

@ -142,6 +142,25 @@ static inline unsigned long zone_page_state_snapshot(struct zone *zone,
return x;
}
static inline unsigned long global_page_state_snapshot(enum zone_stat_item item)
{
long x = atomic_long_read(&vm_stat[item]);
#ifdef CONFIG_SMP
struct zone *zone;
int cpu;
for_each_online_cpu(cpu) {
for_each_populated_zone(zone)
x += per_cpu_ptr(zone->pageset,
cpu)->vm_stat_diff[item];
}
if (x < 0)
x = 0;
#endif
return x;
}
#ifdef CONFIG_NUMA
/*
* Determine the per node value of a stat item. This function

View file

@ -1670,6 +1670,12 @@ void throttle_vm_writeout(gfp_t gfp_mask)
if (global_page_state(NR_UNSTABLE_NFS) +
global_page_state(NR_WRITEBACK) <= dirty_thresh)
break;
/* Try safe version */
else if (unlikely(global_page_state_snapshot(NR_UNSTABLE_NFS) +
global_page_state_snapshot(NR_WRITEBACK) <=
dirty_thresh))
break;
congestion_wait(BLK_RW_ASYNC, HZ/10);
/*