mm/page-writeback.c: fix __set_page_dirty_no_writeback() return value
[platform/adaptation/renesas_rcar/renesas_kernel.git] / mm / vmscan.c
index 9ca587c..86f8c34 100644 (file)
@@ -2143,7 +2143,7 @@ static int sleeping_prematurely(pg_data_t *pgdat, int order, long remaining)
                if (zone->all_unreclaimable)
                        continue;
 
-               if (!zone_watermark_ok(zone, order, high_wmark_pages(zone),
+               if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone),
                                                                0, 0))
                        return 1;
        }
@@ -2230,7 +2230,7 @@ loop_again:
                                shrink_active_list(SWAP_CLUSTER_MAX, zone,
                                                        &sc, priority, 0);
 
-                       if (!zone_watermark_ok(zone, order,
+                       if (!zone_watermark_ok_safe(zone, order,
                                        high_wmark_pages(zone), 0, 0)) {
                                end_zone = i;
                                break;
@@ -2276,7 +2276,7 @@ loop_again:
                         * We put equal pressure on every zone, unless one
                         * zone has way too many pages free already.
                         */
-                       if (!zone_watermark_ok(zone, order,
+                       if (!zone_watermark_ok_safe(zone, order,
                                        8*high_wmark_pages(zone), end_zone, 0))
                                shrink_zone(priority, zone, &sc);
                        reclaim_state->reclaimed_slab = 0;
@@ -2297,7 +2297,7 @@ loop_again:
                            total_scanned > sc.nr_reclaimed + sc.nr_reclaimed / 2)
                                sc.may_writepage = 1;
 
-                       if (!zone_watermark_ok(zone, order,
+                       if (!zone_watermark_ok_safe(zone, order,
                                        high_wmark_pages(zone), end_zone, 0)) {
                                all_zones_ok = 0;
                                /*
@@ -2305,7 +2305,7 @@ loop_again:
                                 * means that we have a GFP_ATOMIC allocation
                                 * failure risk. Hurry up!
                                 */
-                               if (!zone_watermark_ok(zone, order,
+                               if (!zone_watermark_ok_safe(zone, order,
                                            min_wmark_pages(zone), end_zone, 0))
                                        has_under_min_watermark_zone = 1;
                        } else {
@@ -2448,7 +2448,24 @@ static int kswapd(void *p)
                                 */
                                if (!sleeping_prematurely(pgdat, order, remaining)) {
                                        trace_mm_vmscan_kswapd_sleep(pgdat->node_id);
+
+                                       /*
+                                        * 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();
+                                       set_pgdat_percpu_threshold(pgdat,
+                                               calculate_pressure_threshold);
                                } else {
                                        if (remaining)
                                                count_vm_event(KSWAPD_LOW_WMARK_HIT_QUICKLY);
@@ -2487,16 +2504,17 @@ void wakeup_kswapd(struct zone *zone, int order)
        if (!populated_zone(zone))
                return;
 
-       pgdat = zone->zone_pgdat;
-       if (zone_watermark_ok(zone, order, low_wmark_pages(zone), 0, 0))
+       if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
                return;
+       pgdat = zone->zone_pgdat;
        if (pgdat->kswapd_max_order < order)
                pgdat->kswapd_max_order = order;
-       trace_mm_vmscan_wakeup_kswapd(pgdat->node_id, zone_idx(zone), order);
-       if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
-               return;
        if (!waitqueue_active(&pgdat->kswapd_wait))
                return;
+       if (zone_watermark_ok_safe(zone, order, low_wmark_pages(zone), 0, 0))
+               return;
+
+       trace_mm_vmscan_wakeup_kswapd(pgdat->node_id, zone_idx(zone), order);
        wake_up_interruptible(&pgdat->kswapd_wait);
 }