aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/vmscan.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 04dca89c4f34..fa91c20fe4b7 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2142,10 +2142,11 @@ static inline bool should_continue_reclaim(struct zone *zone,
2142 } 2142 }
2143} 2143}
2144 2144
2145static void 2145static int
2146__shrink_zone(struct zone *zone, struct scan_control *sc, bool soft_reclaim) 2146__shrink_zone(struct zone *zone, struct scan_control *sc, bool soft_reclaim)
2147{ 2147{
2148 unsigned long nr_reclaimed, nr_scanned; 2148 unsigned long nr_reclaimed, nr_scanned;
2149 int groups_scanned = 0;
2149 2150
2150 do { 2151 do {
2151 struct mem_cgroup *root = sc->target_mem_cgroup; 2152 struct mem_cgroup *root = sc->target_mem_cgroup;
@@ -2163,6 +2164,7 @@ __shrink_zone(struct zone *zone, struct scan_control *sc, bool soft_reclaim)
2163 while ((memcg = mem_cgroup_iter_cond(root, memcg, &reclaim, filter))) { 2164 while ((memcg = mem_cgroup_iter_cond(root, memcg, &reclaim, filter))) {
2164 struct lruvec *lruvec; 2165 struct lruvec *lruvec;
2165 2166
2167 groups_scanned++;
2166 lruvec = mem_cgroup_zone_lruvec(zone, memcg); 2168 lruvec = mem_cgroup_zone_lruvec(zone, memcg);
2167 2169
2168 shrink_lruvec(lruvec, sc); 2170 shrink_lruvec(lruvec, sc);
@@ -2190,6 +2192,8 @@ __shrink_zone(struct zone *zone, struct scan_control *sc, bool soft_reclaim)
2190 2192
2191 } while (should_continue_reclaim(zone, sc->nr_reclaimed - nr_reclaimed, 2193 } while (should_continue_reclaim(zone, sc->nr_reclaimed - nr_reclaimed,
2192 sc->nr_scanned - nr_scanned, sc)); 2194 sc->nr_scanned - nr_scanned, sc));
2195
2196 return groups_scanned;
2193} 2197}
2194 2198
2195 2199
@@ -2197,8 +2201,19 @@ static void shrink_zone(struct zone *zone, struct scan_control *sc)
2197{ 2201{
2198 bool do_soft_reclaim = mem_cgroup_should_soft_reclaim(sc); 2202 bool do_soft_reclaim = mem_cgroup_should_soft_reclaim(sc);
2199 unsigned long nr_scanned = sc->nr_scanned; 2203 unsigned long nr_scanned = sc->nr_scanned;
2204 int scanned_groups;
2200 2205
2201 __shrink_zone(zone, sc, do_soft_reclaim); 2206 scanned_groups = __shrink_zone(zone, sc, do_soft_reclaim);
2207 /*
2208 * memcg iterator might race with other reclaimer or start from
2209 * a incomplete tree walk so the tree walk in __shrink_zone
2210 * might have missed groups that are above the soft limit. Try
2211 * another loop to catch up with others. Do it just once to
2212 * prevent from reclaim latencies when other reclaimers always
2213 * preempt this one.
2214 */
2215 if (do_soft_reclaim && !scanned_groups)
2216 __shrink_zone(zone, sc, do_soft_reclaim);
2202 2217
2203 /* 2218 /*
2204 * No group is over the soft limit or those that are do not have 2219 * No group is over the soft limit or those that are do not have