2023-05-24 14:56:36 +00:00
|
|
|
From 11b14ee8cbbbebd8204609076a9327a1171cd253 Mon Sep 17 00:00:00 2001
|
2022-10-18 20:26:34 +00:00
|
|
|
From: Yu Zhao <yuzhao@google.com>
|
|
|
|
Date: Wed, 21 Dec 2022 21:19:05 -0700
|
2023-05-24 14:56:36 +00:00
|
|
|
Subject: [PATCH 07/19] BACKPORT: mm: multi-gen LRU: clarify scan_control flags
|
2022-10-18 20:26:34 +00:00
|
|
|
|
|
|
|
Among the flags in scan_control:
|
|
|
|
1. sc->may_swap, which indicates swap constraint due to memsw.max, is
|
|
|
|
supported as usual.
|
|
|
|
2. sc->proactive, which indicates reclaim by memory.reclaim, may not
|
|
|
|
opportunistically skip the aging path, since it is considered less
|
|
|
|
latency sensitive.
|
|
|
|
3. !(sc->gfp_mask & __GFP_IO), which indicates IO constraint, lowers
|
2023-05-22 00:36:35 +00:00
|
|
|
swappiness to prioritize file LRU, since clean file folios are more
|
2022-10-18 20:26:34 +00:00
|
|
|
likely to exist.
|
2023-05-24 14:56:36 +00:00
|
|
|
4. sc->may_writepage and sc->may_unmap, which indicates opportunistic
|
2023-05-22 00:36:35 +00:00
|
|
|
reclaim, are rejected, since unmapped clean folios are already
|
2022-10-18 20:26:34 +00:00
|
|
|
prioritized. Scanning for more of them is likely futile and can
|
|
|
|
cause high reclaim latency when there is a large number of memcgs.
|
|
|
|
|
|
|
|
The rest are handled by the existing code.
|
|
|
|
|
|
|
|
Link: https://lkml.kernel.org/r/20221222041905.2431096-8-yuzhao@google.com
|
|
|
|
Signed-off-by: Yu Zhao <yuzhao@google.com>
|
|
|
|
Cc: Johannes Weiner <hannes@cmpxchg.org>
|
|
|
|
Cc: Jonathan Corbet <corbet@lwn.net>
|
|
|
|
Cc: Michael Larabel <Michael@MichaelLarabel.com>
|
|
|
|
Cc: Michal Hocko <mhocko@kernel.org>
|
|
|
|
Cc: Mike Rapoport <rppt@kernel.org>
|
|
|
|
Cc: Roman Gushchin <roman.gushchin@linux.dev>
|
|
|
|
Cc: Suren Baghdasaryan <surenb@google.com>
|
|
|
|
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
2023-05-24 14:56:36 +00:00
|
|
|
Bug: 274865848
|
|
|
|
(cherry picked from commit e9d4e1ee788097484606c32122f146d802a9c5fb)
|
|
|
|
[TJ: Resolved conflict with older function signature for min_cgroup_below_min, and over
|
|
|
|
cdded861182142ac4488a4d64c571107aeb77f53 ("ANDROID: MGLRU: Don't skip anon reclaim if swap low")]
|
|
|
|
Change-Id: Ic2e779eaf4e91a3921831b4e2fa10c740dc59d50
|
|
|
|
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
2022-10-18 20:26:34 +00:00
|
|
|
---
|
|
|
|
mm/vmscan.c | 55 +++++++++++++++++++++++++++--------------------------
|
|
|
|
1 file changed, 28 insertions(+), 27 deletions(-)
|
|
|
|
|
|
|
|
--- a/mm/vmscan.c
|
|
|
|
+++ b/mm/vmscan.c
|
2023-05-30 01:41:35 +00:00
|
|
|
@@ -3185,6 +3185,9 @@ static int get_swappiness(struct lruvec
|
2022-10-18 20:26:34 +00:00
|
|
|
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
|
|
|
struct pglist_data *pgdat = lruvec_pgdat(lruvec);
|
|
|
|
|
|
|
|
+ if (!sc->may_swap)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
if (!can_demote(pgdat->node_id, sc) &&
|
2023-05-22 16:06:14 +00:00
|
|
|
mem_cgroup_get_nr_swap_pages(memcg) < MIN_LRU_BATCH)
|
2022-10-18 20:26:34 +00:00
|
|
|
return 0;
|
2023-05-30 01:41:35 +00:00
|
|
|
@@ -4223,7 +4226,7 @@ static void walk_mm(struct lruvec *lruve
|
2022-10-18 20:26:34 +00:00
|
|
|
} while (err == -EAGAIN);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat)
|
|
|
|
+static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat, bool force_alloc)
|
|
|
|
{
|
|
|
|
struct lru_gen_mm_walk *walk = current->reclaim_state->mm_walk;
|
|
|
|
|
2023-05-30 01:41:35 +00:00
|
|
|
@@ -4231,7 +4234,7 @@ static struct lru_gen_mm_walk *set_mm_wa
|
2022-10-18 20:26:34 +00:00
|
|
|
VM_WARN_ON_ONCE(walk);
|
|
|
|
|
|
|
|
walk = &pgdat->mm_walk;
|
|
|
|
- } else if (!pgdat && !walk) {
|
|
|
|
+ } else if (!walk && force_alloc) {
|
|
|
|
VM_WARN_ON_ONCE(current_is_kswapd());
|
|
|
|
|
|
|
|
walk = kzalloc(sizeof(*walk), __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN);
|
2023-09-19 18:00:07 +00:00
|
|
|
@@ -4419,7 +4422,7 @@ static bool try_to_inc_max_seq(struct lr
|
2022-10-18 20:26:34 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
- walk = set_mm_walk(NULL);
|
|
|
|
+ walk = set_mm_walk(NULL, true);
|
|
|
|
if (!walk) {
|
|
|
|
success = iterate_mm_list_nowalk(lruvec, max_seq);
|
|
|
|
goto done;
|
2023-09-19 18:00:07 +00:00
|
|
|
@@ -4488,8 +4491,6 @@ static bool lruvec_is_reclaimable(struct
|
2022-10-18 20:26:34 +00:00
|
|
|
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
|
|
|
DEFINE_MIN_SEQ(lruvec);
|
|
|
|
|
|
|
|
- VM_WARN_ON_ONCE(sc->memcg_low_reclaim);
|
|
|
|
-
|
2023-05-22 00:36:35 +00:00
|
|
|
/* see the comment on lru_gen_folio */
|
2022-10-18 20:26:34 +00:00
|
|
|
gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]);
|
|
|
|
birth = READ_ONCE(lruvec->lrugen.timestamps[gen]);
|
2023-09-19 18:00:07 +00:00
|
|
|
@@ -4753,12 +4754,8 @@ static bool isolate_folio(struct lruvec
|
2022-10-18 20:26:34 +00:00
|
|
|
{
|
|
|
|
bool success;
|
|
|
|
|
|
|
|
- /* unmapping inhibited */
|
2023-05-22 00:36:35 +00:00
|
|
|
- if (!sc->may_unmap && folio_mapped(folio))
|
2022-10-18 20:26:34 +00:00
|
|
|
- return false;
|
|
|
|
-
|
|
|
|
/* swapping inhibited */
|
|
|
|
- if (!(sc->may_writepage && (sc->gfp_mask & __GFP_IO)) &&
|
|
|
|
+ if (!(sc->gfp_mask & __GFP_IO) &&
|
2023-05-22 00:36:35 +00:00
|
|
|
(folio_test_dirty(folio) ||
|
|
|
|
(folio_test_anon(folio) && !folio_test_swapcache(folio))))
|
2022-10-18 20:26:34 +00:00
|
|
|
return false;
|
2023-09-19 18:00:07 +00:00
|
|
|
@@ -4857,9 +4854,8 @@ static int scan_folios(struct lruvec *lr
|
2022-10-18 20:26:34 +00:00
|
|
|
__count_vm_events(PGSCAN_ANON + type, isolated);
|
|
|
|
|
|
|
|
/*
|
|
|
|
- * There might not be eligible pages due to reclaim_idx, may_unmap and
|
|
|
|
- * may_writepage. Check the remaining to prevent livelock if it's not
|
|
|
|
- * making progress.
|
2023-05-24 14:56:36 +00:00
|
|
|
+ * There might not be eligible folios due to reclaim_idx. Check the
|
2022-10-18 20:26:34 +00:00
|
|
|
+ * remaining to prevent livelock if it's not making progress.
|
|
|
|
*/
|
|
|
|
return isolated || !remaining ? scanned : 0;
|
|
|
|
}
|
2023-09-19 18:00:07 +00:00
|
|
|
@@ -5119,8 +5115,7 @@ static long get_nr_to_scan(struct lruvec
|
2022-10-18 20:26:34 +00:00
|
|
|
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
|
|
|
DEFINE_MAX_SEQ(lruvec);
|
|
|
|
|
|
|
|
- if (mem_cgroup_below_min(memcg) ||
|
|
|
|
- (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim))
|
|
|
|
+ if (mem_cgroup_below_min(memcg))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!should_run_aging(lruvec, max_seq, sc, can_swap, &nr_to_scan))
|
2023-09-19 18:00:07 +00:00
|
|
|
@@ -5148,17 +5143,14 @@ static bool try_to_shrink_lruvec(struct
|
2022-10-18 20:26:34 +00:00
|
|
|
long nr_to_scan;
|
|
|
|
unsigned long scanned = 0;
|
|
|
|
unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
|
|
|
|
+ int swappiness = get_swappiness(lruvec, sc);
|
|
|
|
+
|
2023-05-22 00:36:35 +00:00
|
|
|
+ /* clean file folios are more likely to exist */
|
2022-10-18 20:26:34 +00:00
|
|
|
+ if (swappiness && !(sc->gfp_mask & __GFP_IO))
|
|
|
|
+ swappiness = 1;
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
int delta;
|
|
|
|
- int swappiness;
|
|
|
|
-
|
|
|
|
- if (sc->may_swap)
|
|
|
|
- swappiness = get_swappiness(lruvec, sc);
|
|
|
|
- else if (!cgroup_reclaim(sc) && get_swappiness(lruvec, sc))
|
|
|
|
- swappiness = 1;
|
|
|
|
- else
|
|
|
|
- swappiness = 0;
|
|
|
|
|
|
|
|
nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
|
|
|
|
if (nr_to_scan <= 0)
|
2023-09-19 18:00:07 +00:00
|
|
|
@@ -5289,12 +5281,13 @@ static void lru_gen_shrink_lruvec(struct
|
2022-10-18 20:26:34 +00:00
|
|
|
struct blk_plug plug;
|
|
|
|
|
|
|
|
VM_WARN_ON_ONCE(global_reclaim(sc));
|
|
|
|
+ VM_WARN_ON_ONCE(!sc->may_writepage || !sc->may_unmap);
|
|
|
|
|
|
|
|
lru_add_drain();
|
|
|
|
|
|
|
|
blk_start_plug(&plug);
|
|
|
|
|
|
|
|
- set_mm_walk(lruvec_pgdat(lruvec));
|
2023-05-22 00:36:35 +00:00
|
|
|
+ set_mm_walk(NULL, sc->proactive);
|
2022-10-18 20:26:34 +00:00
|
|
|
|
|
|
|
if (try_to_shrink_lruvec(lruvec, sc))
|
|
|
|
lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG);
|
2023-09-19 18:00:07 +00:00
|
|
|
@@ -5350,11 +5343,19 @@ static void lru_gen_shrink_node(struct p
|
2022-10-18 20:26:34 +00:00
|
|
|
|
|
|
|
VM_WARN_ON_ONCE(!global_reclaim(sc));
|
|
|
|
|
|
|
|
+ /*
|
2023-05-22 00:36:35 +00:00
|
|
|
+ * Unmapped clean folios are already prioritized. Scanning for more of
|
2022-10-18 20:26:34 +00:00
|
|
|
+ * them is likely futile and can cause high reclaim latency when there
|
|
|
|
+ * is a large number of memcgs.
|
|
|
|
+ */
|
|
|
|
+ if (!sc->may_writepage || !sc->may_unmap)
|
|
|
|
+ goto done;
|
|
|
|
+
|
|
|
|
lru_add_drain();
|
|
|
|
|
|
|
|
blk_start_plug(&plug);
|
|
|
|
|
|
|
|
- set_mm_walk(pgdat);
|
2023-05-24 14:56:36 +00:00
|
|
|
+ set_mm_walk(pgdat, sc->proactive);
|
2022-10-18 20:26:34 +00:00
|
|
|
|
|
|
|
set_initial_priority(pgdat, sc);
|
|
|
|
|
2023-09-19 18:00:07 +00:00
|
|
|
@@ -5372,7 +5373,7 @@ static void lru_gen_shrink_node(struct p
|
2022-10-18 20:26:34 +00:00
|
|
|
clear_mm_walk();
|
|
|
|
|
|
|
|
blk_finish_plug(&plug);
|
|
|
|
-
|
|
|
|
+done:
|
|
|
|
/* kswapd should never fail */
|
|
|
|
pgdat->kswapd_failures = 0;
|
|
|
|
}
|
2023-09-19 18:00:07 +00:00
|
|
|
@@ -5944,7 +5945,7 @@ static ssize_t lru_gen_seq_write(struct
|
2022-10-18 20:26:34 +00:00
|
|
|
set_task_reclaim_state(current, &sc.reclaim_state);
|
|
|
|
flags = memalloc_noreclaim_save();
|
|
|
|
blk_start_plug(&plug);
|
|
|
|
- if (!set_mm_walk(NULL)) {
|
|
|
|
+ if (!set_mm_walk(NULL, true)) {
|
|
|
|
err = -ENOMEM;
|
|
|
|
goto done;
|
|
|
|
}
|