mm: vmstat: use a single setter function and callback for adjusting percpu thresholds
[linux-2.6-block.git] / mm / vmscan.c
index 5da4295e7d672e8804151773e184d65fde1ddd67..86f8c3418795ee02ed376d3c60f82be052338d23 100644 (file)
@@ -2448,9 +2448,24 @@ static int kswapd(void *p)
                                 */
                                if (!sleeping_prematurely(pgdat, order, remaining)) {
                                        trace_mm_vmscan_kswapd_sleep(pgdat->node_id);
-                                       restore_pgdat_percpu_threshold(pgdat);
+
+                                       /*
+                                        * vmstat counters are not perfectly
+                                        * accurate and the estimated value
+                                        * for counters such as NR_FREE_PAGES
+                                        * can deviate from the true value by
+                                        * nr_online_cpus * threshold. To
+                                        * avoid the zone watermarks being
+                                        * breached while under pressure, we
+                                        * reduce the per-cpu vmstat threshold
+                                        * while kswapd is awake and restore
+                                        * them before going back to sleep.
+                                        */
+                                       set_pgdat_percpu_threshold(pgdat,
+                                               calculate_normal_threshold);
                                        schedule();
-                                       reduce_pgdat_percpu_threshold(pgdat);
+                                       set_pgdat_percpu_threshold(pgdat,
+                                               calculate_pressure_threshold);
                                } else {
                                        if (remaining)
                                                count_vm_event(KSWAPD_LOW_WMARK_HIT_QUICKLY);