aboutsummaryrefslogtreecommitdiffstats
path: root/mm/vmscan.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r--mm/vmscan.c44
1 files changed, 42 insertions, 2 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 61d3a9a0d96f..e176bd3936da 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1904,6 +1904,24 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont,
1904} 1904}
1905#endif 1905#endif
1906 1906
1907/* is kswapd sleeping prematurely? */
1908static int sleeping_prematurely(int order, long remaining)
1909{
1910 struct zone *zone;
1911
1912 /* If a direct reclaimer woke kswapd within HZ/10, it's premature */
1913 if (remaining)
1914 return 1;
1915
1916 /* If after HZ/10, a zone is below the high mark, it's premature */
1917 for_each_populated_zone(zone)
1918 if (!zone_watermark_ok(zone, order, high_wmark_pages(zone),
1919 0, 0))
1920 return 1;
1921
1922 return 0;
1923}
1924
1907/* 1925/*
1908 * For kswapd, balance_pgdat() will work across all this node's zones until 1926 * For kswapd, balance_pgdat() will work across all this node's zones until
1909 * they are all at high_wmark_pages(zone). 1927 * they are all at high_wmark_pages(zone).
@@ -2185,8 +2203,30 @@ static int kswapd(void *p)
2185 */ 2203 */
2186 order = new_order; 2204 order = new_order;
2187 } else { 2205 } else {
2188 if (!freezing(current) && !kthread_should_stop()) 2206 if (!freezing(current) && !kthread_should_stop()) {
2189 schedule(); 2207 long remaining = 0;
2208
2209 /* Try to sleep for a short interval */
2210 if (!sleeping_prematurely(order, remaining)) {
2211 remaining = schedule_timeout(HZ/10);
2212 finish_wait(&pgdat->kswapd_wait, &wait);
2213 prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
2214 }
2215
2216 /*
2217 * After a short sleep, check if it was a
2218 * premature sleep. If not, then go fully
2219 * to sleep until explicitly woken up
2220 */
2221 if (!sleeping_prematurely(order, remaining))
2222 schedule();
2223 else {
2224 if (remaining)
2225 count_vm_event(KSWAPD_PREMATURE_FAST);
2226 else
2227 count_vm_event(KSWAPD_PREMATURE_SLOW);
2228 }
2229 }
2190 2230
2191 order = pgdat->kswapd_max_order; 2231 order = pgdat->kswapd_max_order;
2192 } 2232 }