mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-20 06:08:08 +00:00
89 lines
2.5 KiB
Diff
89 lines
2.5 KiB
Diff
|
From cc67f962cc53f6e1dfa92eb85b7b26fe83a3c66f Mon Sep 17 00:00:00 2001
|
||
|
From: Yu Zhao <yuzhao@google.com>
|
||
|
Date: Mon, 13 Feb 2023 00:53:22 -0700
|
||
|
Subject: [PATCH 29/29] mm: multi-gen LRU: avoid futile retries
|
||
|
|
||
|
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>
|
||
|
---
|
||
|
mm/vmscan.c | 25 +++++++++++++++----------
|
||
|
1 file changed, 15 insertions(+), 10 deletions(-)
|
||
|
|
||
|
--- a/mm/vmscan.c
|
||
|
+++ b/mm/vmscan.c
|
||
|
@@ -4934,18 +4934,20 @@ static int shrink_one(struct lruvec *lru
|
||
|
|
||
|
static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
|
||
|
{
|
||
|
+ int op;
|
||
|
int gen;
|
||
|
int bin;
|
||
|
int first_bin;
|
||
|
struct lruvec *lruvec;
|
||
|
struct lru_gen_page *lrugen;
|
||
|
+ 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);
|
||
|
|
||
|
bin = first_bin = prandom_u32_max(MEMCG_NR_BINS);
|
||
|
restart:
|
||
|
+ op = 0;
|
||
|
+ memcg = NULL;
|
||
|
gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq));
|
||
|
|
||
|
rcu_read_lock();
|
||
|
@@ -4969,14 +4971,22 @@ restart:
|
||
|
|
||
|
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;
|
||
|
@@ -4985,11 +4995,6 @@ restart:
|
||
|
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)
|