mm/memblock.c: call kmemleak directly from memblock_(alloc|free)
[firefly-linux-kernel-4.4.55.git] / mm / vmscan.c
index 494cd632178cb430cf60db7268801266fd5ee550..f44476a415444c53de367d70668bb91fc459969a 100644 (file)
@@ -83,6 +83,9 @@ struct scan_control {
        /* Scan (total_size >> priority) pages at once */
        int priority;
 
+       /* anon vs. file LRUs scanning "ratio" */
+       int swappiness;
+
        /*
         * The memory cgroup that hit its limit and as a result is the
         * primary target of this reclaim invocation.
@@ -1845,13 +1848,6 @@ static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan,
        return shrink_inactive_list(nr_to_scan, lruvec, sc, lru);
 }
 
-static int vmscan_swappiness(struct scan_control *sc)
-{
-       if (global_reclaim(sc))
-               return vm_swappiness;
-       return mem_cgroup_swappiness(sc->target_mem_cgroup);
-}
-
 enum scan_balance {
        SCAN_EQUAL,
        SCAN_FRACT,
@@ -1912,7 +1908,7 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc,
         * using the memory controller's swap limit feature would be
         * too expensive.
         */
-       if (!global_reclaim(sc) && !vmscan_swappiness(sc)) {
+       if (!global_reclaim(sc) && !sc->swappiness) {
                scan_balance = SCAN_FILE;
                goto out;
        }
@@ -1922,7 +1918,7 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc,
         * system is close to OOM, scan both anon and file equally
         * (unless the swappiness setting disagrees with swapping).
         */
-       if (!sc->priority && vmscan_swappiness(sc)) {
+       if (!sc->priority && sc->swappiness) {
                scan_balance = SCAN_EQUAL;
                goto out;
        }
@@ -1965,7 +1961,7 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc,
         * With swappiness at 100, anonymous and file have the same priority.
         * This scanning priority is essentially the inverse of IO cost.
         */
-       anon_prio = vmscan_swappiness(sc);
+       anon_prio = sc->swappiness;
        file_prio = 200 - anon_prio;
 
        /*
@@ -2064,13 +2060,27 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
        unsigned long nr_reclaimed = 0;
        unsigned long nr_to_reclaim = sc->nr_to_reclaim;
        struct blk_plug plug;
-       bool scan_adjusted = false;
+       bool scan_adjusted;
 
        get_scan_count(lruvec, sc, nr);
 
        /* Record the original scan target for proportional adjustments later */
        memcpy(targets, nr, sizeof(nr));
 
+       /*
+        * Global reclaiming within direct reclaim at DEF_PRIORITY is a normal
+        * event that can occur when there is little memory pressure e.g.
+        * multiple streaming readers/writers. Hence, we do not abort scanning
+        * when the requested number of pages are reclaimed when scanning at
+        * DEF_PRIORITY on the assumption that the fact we are direct
+        * reclaiming implies that kswapd is not keeping up and it is best to
+        * do a batch of work at once. For memcg reclaim one check is made to
+        * abort proportional reclaim if either the file or anon lru has already
+        * dropped to zero at the first pass.
+        */
+       scan_adjusted = (global_reclaim(sc) && !current_is_kswapd() &&
+                        sc->priority == DEF_PRIORITY);
+
        blk_start_plug(&plug);
        while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] ||
                                        nr[LRU_INACTIVE_FILE]) {
@@ -2090,18 +2100,9 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
                if (nr_reclaimed < nr_to_reclaim || scan_adjusted)
                        continue;
 
-               /*
-                * For global direct reclaim, reclaim only the number of pages
-                * requested. Less care is taken to scan proportionally as it
-                * is more important to minimise direct reclaim stall latency
-                * than it is to properly age the LRU lists.
-                */
-               if (global_reclaim(sc) && !current_is_kswapd())
-                       break;
-
                /*
                 * For kswapd and memcg, reclaim at least the number of pages
-                * requested. Ensure that the anon and file LRUs shrink
+                * requested. Ensure that the anon and file LRUs are scanned
                 * proportionally what was requested by get_scan_count(). We
                 * stop reclaiming one LRU and reduce the amount scanning
                 * proportional to the original scan target.
@@ -2109,6 +2110,15 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
                nr_file = nr[LRU_INACTIVE_FILE] + nr[LRU_ACTIVE_FILE];
                nr_anon = nr[LRU_INACTIVE_ANON] + nr[LRU_ACTIVE_ANON];
 
+               /*
+                * It's just vindictive to attack the larger once the smaller
+                * has gone to zero.  And given the way we stop scanning the
+                * smaller below, this makes sure that we only make one nudge
+                * towards proportionality once we've got nr_to_reclaim.
+                */
+               if (!nr_file || !nr_anon)
+                       break;
+
                if (nr_file > nr_anon) {
                        unsigned long scan_target = targets[LRU_INACTIVE_ANON] +
                                                targets[LRU_ACTIVE_ANON] + 1;
@@ -2251,6 +2261,7 @@ static void shrink_zone(struct zone *zone, struct scan_control *sc)
 
                        lruvec = mem_cgroup_zone_lruvec(zone, memcg);
 
+                       sc->swappiness = mem_cgroup_swappiness(memcg);
                        shrink_lruvec(lruvec, sc);
 
                        /*
@@ -2295,9 +2306,8 @@ static inline bool compaction_ready(struct zone *zone, struct scan_control *sc)
         * there is a buffer of free pages available to give compaction
         * a reasonable chance of completing and allocating the page
         */
-       balance_gap = min(low_wmark_pages(zone),
-               (zone->managed_pages + KSWAPD_ZONE_BALANCE_GAP_RATIO-1) /
-                       KSWAPD_ZONE_BALANCE_GAP_RATIO);
+       balance_gap = min(low_wmark_pages(zone), DIV_ROUND_UP(
+                       zone->managed_pages, KSWAPD_ZONE_BALANCE_GAP_RATIO));
        watermark = high_wmark_pages(zone) + balance_gap + (2UL << sc->order);
        watermark_ok = zone_watermark_ok_safe(zone, 0, watermark, 0, 0);
 
@@ -2718,6 +2728,7 @@ unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *memcg,
                .may_swap = !noswap,
                .order = 0,
                .priority = 0,
+               .swappiness = mem_cgroup_swappiness(memcg),
                .target_mem_cgroup = memcg,
        };
        struct lruvec *lruvec = mem_cgroup_zone_lruvec(zone, memcg);
@@ -2949,9 +2960,8 @@ static bool kswapd_shrink_zone(struct zone *zone,
         * high wmark plus a "gap" where the gap is either the low
         * watermark or 1% of the zone, whichever is smaller.
         */
-       balance_gap = min(low_wmark_pages(zone),
-               (zone->managed_pages + KSWAPD_ZONE_BALANCE_GAP_RATIO-1) /
-               KSWAPD_ZONE_BALANCE_GAP_RATIO);
+       balance_gap = min(low_wmark_pages(zone), DIV_ROUND_UP(
+                       zone->managed_pages, KSWAPD_ZONE_BALANCE_GAP_RATIO));
 
        /*
         * If there is no low memory pressure or the zone is balanced then no
@@ -3360,7 +3370,10 @@ static int kswapd(void *p)
                }
        }
 
+       tsk->flags &= ~(PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD);
        current->reclaim_state = NULL;
+       lockdep_clear_current_reclaim_state();
+
        return 0;
 }