2023-05-24 14:56:36 +00:00
|
|
|
From 620b0ee94455e48d124414cd06d8a53f69fb6453 Mon Sep 17 00:00:00 2001
|
2022-10-18 20:26:34 +00:00
|
|
|
From: Yu Zhao <yuzhao@google.com>
|
|
|
|
Date: Mon, 13 Feb 2023 00:53:22 -0700
|
2023-05-24 14:56:36 +00:00
|
|
|
Subject: [PATCH 09/19] UPSTREAM: mm: multi-gen LRU: avoid futile retries
|
2022-10-18 20:26:34 +00:00
|
|
|
|
|
|
|
Recall that the per-node memcg LRU has two generations and they alternate
|
|
|
|
when the last memcg (of a given node) is moved from one to the other.
|
|
|
|
Each generation is also sharded into multiple bins to improve scalability.
|
|
|
|
A reclaimer starts with a random bin (in the old generation) and, if it
|
|
|
|
fails, it will retry, i.e., to try the rest of the bins.
|
|
|
|
|
|
|
|
If a reclaimer fails with the last memcg, it should move this memcg to the
|
|
|
|
young generation first, which causes the generations to alternate, and
|
|
|
|
then retry. Otherwise, the retries will be futile because all other bins
|
|
|
|
are empty.
|
|
|
|
|
|
|
|
Link: https://lkml.kernel.org/r/20230213075322.1416966-1-yuzhao@google.com
|
|
|
|
Fixes: e4dde56cd208 ("mm: multi-gen LRU: per-node lru_gen_folio lists")
|
|
|
|
Signed-off-by: Yu Zhao <yuzhao@google.com>
|
|
|
|
Reported-by: T.J. Mercier <tjmercier@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 9f550d78b40da21b4da515db4c37d8d7b12aa1a6)
|
|
|
|
Change-Id: Ie92535676b005ec9e7987632b742fdde8d54436f
|
|
|
|
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
2022-10-18 20:26:34 +00:00
|
|
|
---
|
|
|
|
mm/vmscan.c | 25 +++++++++++++++----------
|
|
|
|
1 file changed, 15 insertions(+), 10 deletions(-)
|
|
|
|
|
|
|
|
--- a/mm/vmscan.c
|
|
|
|
+++ b/mm/vmscan.c
|
2023-05-30 01:41:35 +00:00
|
|
|
@@ -5206,18 +5206,20 @@ static int shrink_one(struct lruvec *lru
|
2022-10-18 20:26:34 +00:00
|
|
|
|
|
|
|
static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
|
|
|
|
{
|
|
|
|
+ int op;
|
|
|
|
int gen;
|
|
|
|
int bin;
|
|
|
|
int first_bin;
|
|
|
|
struct lruvec *lruvec;
|
2023-05-22 00:36:35 +00:00
|
|
|
struct lru_gen_folio *lrugen;
|
2022-10-18 20:26:34 +00:00
|
|
|
+ struct mem_cgroup *memcg;
|
|
|
|
const struct hlist_nulls_node *pos;
|
|
|
|
- int op = 0;
|
|
|
|
- struct mem_cgroup *memcg = NULL;
|
|
|
|
unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
|
|
|
|
|
2023-05-24 14:56:36 +00:00
|
|
|
bin = first_bin = get_random_u32_below(MEMCG_NR_BINS);
|
2022-10-18 20:26:34 +00:00
|
|
|
restart:
|
|
|
|
+ op = 0;
|
|
|
|
+ memcg = NULL;
|
|
|
|
gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq));
|
|
|
|
|
|
|
|
rcu_read_lock();
|
2023-05-30 01:41:35 +00:00
|
|
|
@@ -5241,14 +5243,22 @@ restart:
|
2022-10-18 20:26:34 +00:00
|
|
|
|
|
|
|
op = shrink_one(lruvec, sc);
|
|
|
|
|
|
|
|
- if (sc->nr_reclaimed >= nr_to_reclaim)
|
|
|
|
- goto success;
|
|
|
|
-
|
|
|
|
rcu_read_lock();
|
|
|
|
+
|
|
|
|
+ if (sc->nr_reclaimed >= nr_to_reclaim)
|
|
|
|
+ break;
|
|
|
|
}
|
|
|
|
|
|
|
|
rcu_read_unlock();
|
|
|
|
|
|
|
|
+ if (op)
|
|
|
|
+ lru_gen_rotate_memcg(lruvec, op);
|
|
|
|
+
|
|
|
|
+ mem_cgroup_put(memcg);
|
|
|
|
+
|
|
|
|
+ if (sc->nr_reclaimed >= nr_to_reclaim)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
/* restart if raced with lru_gen_rotate_memcg() */
|
|
|
|
if (gen != get_nulls_value(pos))
|
|
|
|
goto restart;
|
2023-05-30 01:41:35 +00:00
|
|
|
@@ -5257,11 +5267,6 @@ restart:
|
2022-10-18 20:26:34 +00:00
|
|
|
bin = get_memcg_bin(bin + 1);
|
|
|
|
if (bin != first_bin)
|
|
|
|
goto restart;
|
|
|
|
-success:
|
|
|
|
- if (op)
|
|
|
|
- lru_gen_rotate_memcg(lruvec, op);
|
|
|
|
-
|
|
|
|
- mem_cgroup_put(memcg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
|