aboutsummaryrefslogtreecommitdiffstats
diff options
-rw-r--r--mm/vmscan.c72
1 files changed, 36 insertions, 36 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c
index abe2ace8e3265..66ddf211e3ca9 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -4917,49 +4917,37 @@ retry:
}
static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq,
- int swappiness, unsigned long *nr_to_scan)
+ struct scan_control *sc, int swappiness)
{
DEFINE_MIN_SEQ(lruvec);
- *nr_to_scan = 0;
/* have to run aging, since eviction is not possible anymore */
if (evictable_min_seq(min_seq, swappiness) + MIN_NR_GENS > max_seq)
return true;
- *nr_to_scan = lruvec_evictable_size(lruvec, swappiness);
+ /* try to avoid aging, do gentle reclaim at the default priority */
+ if (sc->priority == DEF_PRIORITY)
+ return false;
+
/* better to run aging even though eviction is still possible */
return evictable_min_seq(min_seq, swappiness) + MIN_NR_GENS == max_seq;
}
-/*
- * For future optimizations:
- * 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg
- * reclaim.
- */
-static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, int swappiness)
+static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc,
+ struct mem_cgroup *memcg, int swappiness)
{
- bool need_aging;
- unsigned long nr_to_scan;
- struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- DEFINE_MAX_SEQ(lruvec);
+ unsigned long nr_to_scan, evictable;
- if (mem_cgroup_below_min(sc->target_mem_cgroup, memcg))
- return -1;
-
- need_aging = should_run_aging(lruvec, max_seq, swappiness, &nr_to_scan);
+ evictable = lruvec_evictable_size(lruvec, swappiness);
/* try to scrape all its memory if this memcg was deleted */
- if (nr_to_scan && !mem_cgroup_online(memcg))
- return nr_to_scan;
-
- nr_to_scan = apply_proportional_protection(memcg, sc, nr_to_scan);
+ if (!mem_cgroup_online(memcg))
+ return evictable;
- /* try to get away with not aging at the default priority */
- if (!need_aging || sc->priority == DEF_PRIORITY)
- return nr_to_scan >> sc->priority;
+ nr_to_scan = apply_proportional_protection(memcg, sc, evictable);
+ nr_to_scan >>= sc->priority;
- /* stop scanning this lruvec as it's low on cold folios */
- return try_to_inc_max_seq(lruvec, max_seq, swappiness, false) ? -1 : 0;
+ return nr_to_scan;
}
static bool should_abort_scan(struct lruvec *lruvec, struct scan_control *sc)
@@ -4989,31 +4977,44 @@ static bool should_abort_scan(struct lruvec *lruvec, struct scan_control *sc)
return true;
}
+/*
+ * For future optimizations:
+ * 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg
+ * reclaim.
+ */
static bool try_to_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
{
+ bool need_rotate = false;
long nr_batch, nr_to_scan;
- unsigned long scanned = 0;
int swappiness = get_swappiness(lruvec, sc);
+ struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- while (true) {
+ nr_to_scan = get_nr_to_scan(lruvec, sc, memcg, swappiness);
+ while (nr_to_scan > 0) {
int delta;
+ DEFINE_MAX_SEQ(lruvec);
- nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
- if (nr_to_scan <= 0)
+ if (mem_cgroup_below_min(sc->target_mem_cgroup, memcg)) {
+ need_rotate = true;
break;
+ }
+
+ if (should_run_aging(lruvec, max_seq, sc, swappiness)) {
+ if (try_to_inc_max_seq(lruvec, max_seq, swappiness, false))
+ need_rotate = true;
+ /* stop scanning as it's low on cold folios */
+ break;
+ }
nr_batch = min(nr_to_scan, MAX_LRU_BATCH);
delta = evict_folios(nr_batch, lruvec, sc, swappiness);
if (!delta)
break;
- scanned += delta;
- if (scanned >= nr_to_scan)
- break;
-
if (should_abort_scan(lruvec, sc))
break;
+ nr_to_scan -= delta;
cond_resched();
}
@@ -5039,8 +5040,7 @@ static bool try_to_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
reclaim_throttle(pgdat, VMSCAN_THROTTLE_WRITEBACK);
}
- /* whether this lruvec should be rotated */
- return nr_to_scan < 0;
+ return need_rotate;
}
static int shrink_one(struct lruvec *lruvec, struct scan_control *sc)