From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794446230; b=vFjiHU6Y4GIjYMYowJWUoLTOsAUXbTJQCEPEp5lxeq7k5MPQa/vPNrr9YdI3TSBeBtAo 2riREFlUOPV5pf+9jdHX3q/QhMD5s/F3waklMKH5hVOciT70NLTvDmoI35o+7+m0yq8+G niaAK/fcFO08TZ5JoWpSQnqT92uDKdHtYTQqaY3ueYtrNaTKonv/Y42tP+O54kCI+sriB cj79Jk1wiaUPAxdtTuedydDOpC5CSbPEne9DWCtFpziCyM5/HeXkY4AwS/YEkxjRNCRDf F5JVFfYrDvZaZuE6cAj2F2I0/IYvFSfNEmfniufWy2VPbpFgS7o8VjMq3yCSeyJgzZw== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794446230; h=Received:DKIM-Signature:Date:To:From:Subject:Message-Id; bh=CFLVB6sqQWcJ1HVcmaEPPFwCvDbhuxdf7PpDmqC0GKw=; b=SIklj1ZxqhScMfuuYnA8xmD4AIk64yHlcE8P4hR76OL/U+k+oMrTAdxKu0h3GLu9WoAS sGteAlUyR3ruyUZwMpV3rTChi8yrg3lmunKSSdmCRO/VKHpfRBe+i/T9c1CSsFHreBz/z EhKL0zvcuz72kFRmn0FyO9gBRRsDcity4cfXUH6JQ4iPXD8ZDcG4t8M4n5R3Z2J/xUSBM r1v2LYZauLPPHTx9FLacQZAiyyVgBQcIwPUKafueV4QhnqeNw0uqJEqUOPvqXhekduOgK bGfZCYWqDcRpQ1CznudMZV6uFmm5rtIWFY3NmGZxvaEwc5kJrp5DQPPDIn0SIeFd/6Q== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linux-foundation.org header.i=@linux-foundation.org header.a=rsa-sha256 header.s=korg header.b=ARXCMZXT; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6B9C0606A321 for ; Thu, 12 Nov 2026 01:17:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.a=rsa-sha256 header.s=korg header.b=ARXCMZXT Received: by smtp.kernel.org (Postfix) with ESMTPSA id E046D1F00A05; Thu, 12 Nov 2026 01:17:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux-foundation.org; s=korg; t=1794446230; bh=CFLVB6sqQWcJ1HVcmaEPPFwCvDbhuxdf7PpDmqC0GKw=; h=Date:To:From:Subject; b=ARXCMZXTXZZEYhoQcWpefXKhdJxdVMJcbHzui3VbOWNvSeWasx8jxeSIQ10U7xNun TuQDi/z+xAndizMRSvXkbatfjY+BpUnBp/ulkh6HrE7RcIJWttN4CLNX4kFrqCeeO9 NSZ2tjd5ATr3L44V6aFZ48qGuRvzrHgja2WS48KE= Date: Wed, 11 Nov 2026 17:17:09 -0800 To: mm-commits@vger.kernel.org,zhuhui@kylinos.cn,zhangbo56@xiaomi.com, yuanchu@google.com,weixugc@google.com,wangzicheng@honor.com, surenb@google.com,sidchintamaneni@gmail.com,shakeel.butt@linux.dev, ryncsn@gmail.com,rppt@kernel.org,ridong.chen@linux.dev,qi.zheng@linux.dev, mhocko@suse.com,lyugaofei@xiaomi.com,liuxiang.277@bytedance.com, lianux.mm@gmail.com,liam@infradead.org,kunwu.chan@gmail.com, hui.zhu@linux.dev,hannes@cmpxchg.org,chentao@kylinos.cn,baoquan.he@linux.dev, baolin.wang@linux.alibaba.com,baohua@kernel.org,axelrasmussen@google.com, kasong@tencent.com,akpm@linux-foundation.org From: Andrew Morton Subject: + mm-mglru-reclaim-from-the-oldest-populated-gen.patch added to mm-new branch Message-Id: <20261112011709.E046D1F00A05@smtp.kernel.org> X-Mailing-List: mm-commits@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list The patch titled Subject: mm/mglru: reclaim from the oldest populated gen has been added to the -mm mm-new branch. Its filename is mm-mglru-reclaim-from-the-oldest-populated-gen.patch This patch will shortly appear at https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-mglru-reclaim-from-the-oldest-populated-gen.patch This patch will later appear in the mm-new branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Note, mm-new is a provisional staging ground for work-in-progress patches, and acceptance into mm-new is a notification for others take notice and to finish up reviews. Please do not hesitate to respond to review feedback and post updated versions to replace or incrementally fixup patches in mm-new. The mm-new branch of mm.git is not included in linux-next If a few days of testing in mm-new is successful, the patch will me moved into mm.git's mm-unstable branch, which is included in linux-next Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next via various branches at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm and is updated there most days ------------------------------------------------------ From: Kairui Song Subject: mm/mglru: reclaim from the oldest populated gen Date: Thu, 12 Nov 2026 07:25:50 +0800 Currently MGLRU tries to keep the gen numbers of the two types in sync, avoiding reducing the gen number of one type when the other type has more gens, as described in the comment in try_to_inc_min_seq(). This makes scan_folios() stuck reclaiming the type with fewer gens: it always scanned the oldest gen of the type, even when that gen was empty, so reclaim made no progress on that type unless forced aging created a new gen and eliminated the dead empty gen. There are other approaches, like lifting the gen number synchronization [1]. However, that would break the gen layout used by lru_gen_folio_seq(): newly added folios would no longer have a well-defined hotness according to their gen number, which reduces accuracy. It is also not pressure-aware, since with gentle reclaim we still want to respect the gen layout (hotness). Instead, reclaim from whichever populated oldest gen is left, but only when the default reclaim priority can't satisfy the reclaimer's requirement. This is typical for swappiness limitations: e.g., low swappiness asks the reclaimer to reclaim from file, but file gens are drained, so the reclaim cycle fails and priority is raised. At the default priority the scan quota is 1/4096 of the evictable size, and the old behavior is kept there to respect the hotness distribution. Once priority is raised, the quota is at least 1/2048, so the hotness bias introduced by reclaiming from a younger gen is bounded by that quota, which seems fair. Global reclaim for MGLRU may start with DEF_PRIORITY / 2 (1/64); the ratio is still reasonable at that point, and when global pressure is more critical, we should reclaim harder. Note that scan_folios() still refuses to reclaim a type left with only MIN_NR_GENS gens, so a completely drained type still requires aging. This change only avoids scanning empty gens when populated reclaimable gens remain. Link: https://lore.kernel.org/20261111232603.9934-4-baohua@kernel.org Link: https://lore.kernel.org/linux-mm/20260726122123.7614-4-baohua@kernel.org/ [1] Signed-off-by: Kairui Song Signed-off-by: Barry Song Signed-off-by: Andrew Morton Reviewed-by: Kunwu Chan Cc: Axel Rasmussen Cc: Baolin Wang Cc: Baoquan He Cc: Johannes Weiner Cc: Cc: Liam R. Howlett Cc: wang lian Cc: Cc: Cc: Michal Hocko Cc: Qi Zheng Cc: Ridong Chen Cc: Mike Rapoport Cc: Kairui Song Cc: Shakeel Butt Cc: Suren Baghdasaryan Cc: wangzicheng Cc: Wei Xu Cc: Yuanchu Xie Cc: Bo Zhang Cc: Hui Zhu Cc: Siddharth Chintamaneni Cc: Kunwu Chan --- mm/vmscan.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) --- a/mm/vmscan.c~mm-mglru-reclaim-from-the-oldest-populated-gen +++ a/mm/vmscan.c @@ -3312,11 +3312,9 @@ static int __folio_inc_gen(struct folio } /* protect pages accessed multiple times through file descriptors */ -static int folio_inc_gen(struct lruvec *lruvec, struct folio *folio) +static int folio_inc_gen(struct lruvec *lruvec, struct folio *folio, int old_gen) { - int type = folio_is_file_lru(folio); - struct lru_gen_folio *lrugen = &lruvec->lrugen; - int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]); + int new_gen; bool gen_increased; new_gen = __folio_inc_gen(folio, old_gen, &gen_increased); @@ -4681,7 +4679,7 @@ void lru_gen_reparent_memcg(struct mem_c ******************************************************************************/ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_control *sc, - int tier_idx) + int min_gen, int tier_idx) { int gen = folio_lru_gen(folio); int type = folio_is_file_lru(folio); @@ -4699,14 +4697,14 @@ static bool sort_folio(struct lruvec *lr return false; /* promoted */ - if (gen != lru_gen_from_seq(lrugen->min_seq[type])) { + if (gen != min_gen) { list_move(&folio->lru, &lrugen->folios[gen][type][zone]); return true; } /* protected */ if (tier > tier_idx || refs + workingset == BIT(LRU_REFS_WIDTH) + 1) { - gen = folio_inc_gen(lruvec, folio); + gen = folio_inc_gen(lruvec, folio, min_gen); list_move(&folio->lru, &lrugen->folios[gen][type][zone]); /* don't count the workingset being lazily promoted */ @@ -4721,7 +4719,7 @@ static bool sort_folio(struct lruvec *lr /* ineligible */ if (zone > sc->reclaim_idx) { - gen = folio_inc_gen(lruvec, folio); + gen = folio_inc_gen(lruvec, folio, min_gen); list_move_tail(&folio->lru, &lrugen->folios[gen][type][zone]); return true; } @@ -4764,17 +4762,27 @@ static int scan_folios(unsigned long nr_ int scanned = 0; int isolated = 0; int skipped = 0; + unsigned long min_seq; unsigned long remaining = nr_to_scan; struct lru_gen_folio *lrugen = &lruvec->lrugen; VM_WARN_ON_ONCE(nr_to_scan > MAX_LRU_BATCH); VM_WARN_ON_ONCE(!list_empty(list)); + /* + * Respect the gen hotness distribution at low priority to avoid + * aging and scan cost, but prefer to satisfy the reclaimers request + * when under pressure to respect swappiness more and reduce IO cost. + */ + if (sc->priority == DEF_PRIORITY) + min_seq = lrugen->min_seq[type]; + else + min_seq = lruvec_populated_min_seq(lruvec, type, lrugen->max_seq - MIN_NR_GENS + 1); + if (get_nr_gens(lruvec, type) == MIN_NR_GENS) return 0; - gen = lru_gen_from_seq(lrugen->min_seq[type]); - + gen = lru_gen_from_seq(min_seq); for (i = MAX_NR_ZONES; i > 0; i--) { LIST_HEAD(moved); int skipped_zone = 0; @@ -4792,7 +4800,7 @@ static int scan_folios(unsigned long nr_ scanned += delta; - if (sort_folio(lruvec, folio, sc, tier)) + if (sort_folio(lruvec, folio, sc, gen, tier)) sorted += delta; else if (isolate_folio(lruvec, folio, sc)) { list_add(&folio->lru, list); _ Patches currently in -mm which might be from kasong@tencent.com are mm-mglru-report-evictable-sizes-per-type.patch mm-mglru-extract-lruvec_populated_min_seq-helper.patch mm-mglru-reclaim-from-the-oldest-populated-gen.patch mm-mglru-lift-the-forced-protection-of-reclaimer.patch mm-mglru-skip-zones-above-reclaim_idx-instead-of-rotating-them.patch mm-mglru-return-for-unavailable-anon-reclaim-earlier.patch mm-mglru-balance-anon-and-file-scan-budget-by-refault-rate.patch mm-mglru-lift-youngest-gen-protection-for-higher-priority.patch