From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7C91DD35E5D for ; Wed, 6 Nov 2024 02:10:09 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 114936B009D; Tue, 5 Nov 2024 21:10:09 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 09E476B009E; Tue, 5 Nov 2024 21:10:09 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id E59C66B009F; Tue, 5 Nov 2024 21:10:08 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id C48B46B009D for ; Tue, 5 Nov 2024 21:10:08 -0500 (EST) Received: from smtpin13.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id 6FFBFA164D for ; Wed, 6 Nov 2024 02:10:08 +0000 (UTC) X-FDA: 82754038374.13.A7D68C8 Received: from nyc.source.kernel.org (nyc.source.kernel.org [147.75.193.91]) by imf01.hostedemail.com (Postfix) with ESMTP id 683F040013 for ; Wed, 6 Nov 2024 02:09:40 +0000 (UTC) Authentication-Results: imf01.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=gPaAJK79; spf=pass (imf01.hostedemail.com: domain of sashal@kernel.org designates 147.75.193.91 as permitted sender) smtp.mailfrom=sashal@kernel.org; dmarc=pass (policy=quarantine) header.from=kernel.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1730858822; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:references:dkim-signature; bh=WxIypgWWCs0Y+dcF9QKe9V47Xx9gsdRH+Z5KraxIvDs=; b=UdSOsoZnHmt/gB2bYn9mPRi1+0J0AKoNsRzx/SB2dUTR6cpnzENXECeqsXbOxeRVKf9YbS 7sMpgsC5ULZoxgBw+xbeBj3V+eWrugcH6/gtiztrwDNU8FhLLxo7USCn4BbKiANL3nG1OZ XwWxG+k/6JcWLbQQvUsjuYGX4SJlz/8= ARC-Authentication-Results: i=1; imf01.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=gPaAJK79; spf=pass (imf01.hostedemail.com: domain of sashal@kernel.org designates 147.75.193.91 as permitted sender) smtp.mailfrom=sashal@kernel.org; dmarc=pass (policy=quarantine) header.from=kernel.org ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1730858822; a=rsa-sha256; cv=none; b=2Xmuq7ryp68rbQFyZgFwyqL6cp2iwYT3lsscwWSVWW6xDOvhNg1oK8j2/xaUpamDNcb6Wr AQjOS+R5ZtOKrSclSzhR8OcIz/GbUyV3HWgjfnRq1RxToGEeMWUu7EPyC00uSCNYJb/H/Y +uqFf4IJMUSnVLOII0uS+1xncUi/bX4= Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by nyc.source.kernel.org (Postfix) with ESMTP id 322E5A41BD8; Wed, 6 Nov 2024 02:08:11 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 76CB9C4CEE3; Wed, 6 Nov 2024 02:10:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1730859005; bh=DEnQJQNDMiiOXMpyHq+sUGk43RCAzJypHtU77gDkvqM=; h=From:To:Cc:Subject:Date:From; b=gPaAJK79uwm2/Hium77ERZ0p9nU6YUVdQdaeQ5h8itPAoSiPepqmEmAsNnvPJCMcC EpPl1GrSFdow63vFb772cbplNGbqyRAoyQoYQ+n3XQDjJ3QAj/FFKPjnqJhnjkKRSC Rd+8Ro0g6/Xr6XQ2GRdCKvrpbp1zTtpJwXN7DHOmQQWjKBTPJzMd29Gp/B7tPLOCKP yX2dd8u0+aJzbCN5CRKQ/5wt2iD4BbNRxkHTujAiyqHAYDBjXY4qH/CsAnByc6xsbK Xo+SUYEFSwr2+vNLMSrfaS9QeigLvnzfmQklRa6Wjr+kQts8N5u4vSDpUdWETYxSNW 3Qw9NIa+Ui+AQ== From: Sasha Levin To: stable@vger.kernel.org, yuzhao@google.com Cc: James Houghton , David Stevens , Axel Rasmussen , David Matlack , David Rientjes , Oliver Upton , Paolo Bonzini , Sean Christopherson , Wei Xu , kernel test robot , Andrew Morton , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: FAILED: Patch "mm: multi-gen LRU: use {ptep,pmdp}_clear_young_notify()" failed to apply to v6.6-stable tree Date: Tue, 5 Nov 2024 21:10:00 -0500 Message-ID: <20241106021001.176509-1-sashal@kernel.org> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-Patchwork-Hint: ignore X-stable: review Content-Transfer-Encoding: 8bit X-Rspamd-Server: rspam07 X-Rspamd-Queue-Id: 683F040013 X-Stat-Signature: q6qu1r5dc9pmkkf8ytzoxfqiodh37nqx X-Rspam-User: X-HE-Tag: 1730858980-534962 X-HE-Meta: U2FsdGVkX1+gJGGUQtjieHWYqIWIbD86+iYqB5rWYrxk/X+Kn2vRWP3zlKEZGbBZhmDp2cl/3yo4HO00Y6IqEiE0KPeBcJJOv7meiuyN3CCAbOeJ+o/WXNBdd8I57j9+lQ/91d6olmaNQDXWhwmdE60TGvh8joAHdZkmjZ8XDhiJ4+mOyJp3+ELEPpwdO6awQqGdMTH81nKiYf66oeMFEAnHXZJdgpnBKPE7WoRsHcQYl9N9Y8tSjA8dpwN05/9jK7s4mqouENcxB58vOg4MGcTePju/ICe3gKtyFU2qpQczhreOYkIF+F81SCMRUWnhahNozOzGAsYIPrTuIB0uin0jG0NX2MYMgfWuWHYxjTNJEJ6s9rQL+F0KF9x9xEsIClGivUieI2fWMbd84ZbTcfIUZxMo1oe0/8C7LLGmNnSrlpqjoE72W4iUOgyQ1szXi1X/pdsuf9lBnTYZx2p4aY6LRTp/JvdhE2Xkc4p1CaT+uAoaBHmv/1C4FL1NJsqPUEbXpeQNW1AHy8e2MnfZ6N+B6oV2cvvSf+g40k4owxgArTwHumBY8qPVSFVm1C/yUIePiYMtmlilvuTvyoQ+SkNA12oQJKhMemR4vDEnJfPfvIfQIHhYFGCWvLcJ13YvIrPK3yUZJdR3wxkNUj/NERRDqSUby7vSrj0+sg0tapD3KY/HhAahm7Kgpk4/nkszusXt44I+eyUBFjM9KazFmHfEp02G+6rVcbl8T8GuuGfIHRcwqZYz1biagiongr8FORSvPwHHL1Tv3YM002RIDdN+M4REg6kkohzfo4cvMXQrMt1dbH9qX48zp4v6wiN2iGG4Hs1ayp02t44qgRN0eTSzb/rReexZlaD8oXK2GlGDjkGv1cWWlOUsuEhPWKnfbtneShVSX+VAEb2uYXqkhjNB70C8qgwbb/tEnGXPoN+321eoDmMrKIWBnr+k8oOwZSDP2AFd/y/AYtsIlWE 4D316Y34 ULZWWS+Z+y5EJg/Q+XgGG+R1IPpvSs3zf/3DQbZJx45Lho/Zoj6/x3yzJu4AZaJtVGttXa1cA0m2cR/FScYcCYtrOYIl6EBdHWwwlqUrm5WKXFo3/ZCinM89f4KbFlATr5QzCnXIeiWokusHkW6ngGfgQiN7MB57I0CHt1Vi1NIyvjCtzl2+uiMqR/dWn5B6P2/Im8yp3sXRe3dqVP5wkc/WnOfrZQ6wBCJrCJBDVeE5wj5ZnTSDvlJJTBZ7Wi1Mn1gQxp0uDd1GI8R3t3K/p6eWgwKCcM+2lL3gNlecPlK1In8SGeoN31x6jioTjYLKKFT3OFCVj7fsDd/pArNHCzFoN1hfuUk+c+DSjFcwSeby2B6ITJplilgADsHnqTG1ODW+/3lltCO4zNtVEYuecqReuQ14vVrQ3X6uo X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: The patch below does not apply to the v6.6-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to . Thanks, Sasha ------------------ original commit in Linus's tree ------------------ >From 1d4832becdc2cdb2cffe2a6050c9d9fd8ff1c58c Mon Sep 17 00:00:00 2001 From: Yu Zhao Date: Sat, 19 Oct 2024 01:29:39 +0000 Subject: [PATCH] mm: multi-gen LRU: use {ptep,pmdp}_clear_young_notify() When the MM_WALK capability is enabled, memory that is mostly accessed by a VM appears younger than it really is, therefore this memory will be less likely to be evicted. Therefore, the presence of a running VM can significantly increase swap-outs for non-VM memory, regressing the performance for the rest of the system. Fix this regression by always calling {ptep,pmdp}_clear_young_notify() whenever we clear the young bits on PMDs/PTEs. [jthoughton@google.com: fix link-time error] Link: https://lkml.kernel.org/r/20241019012940.3656292-3-jthoughton@google.com Fixes: bd74fdaea146 ("mm: multi-gen LRU: support page table walks") Signed-off-by: Yu Zhao Signed-off-by: James Houghton Reported-by: David Stevens Cc: Axel Rasmussen Cc: David Matlack Cc: David Rientjes Cc: Oliver Upton Cc: Paolo Bonzini Cc: Sean Christopherson Cc: Wei Xu Cc: Cc: kernel test robot Signed-off-by: Andrew Morton --- include/linux/mmzone.h | 5 ++- mm/rmap.c | 9 ++--- mm/vmscan.c | 88 +++++++++++++++++++++++------------------- 3 files changed, 55 insertions(+), 47 deletions(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 9342e5692dab6..5b1c984daf454 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -555,7 +555,7 @@ struct lru_gen_memcg { void lru_gen_init_pgdat(struct pglist_data *pgdat); void lru_gen_init_lruvec(struct lruvec *lruvec); -void lru_gen_look_around(struct page_vma_mapped_walk *pvmw); +bool lru_gen_look_around(struct page_vma_mapped_walk *pvmw); void lru_gen_init_memcg(struct mem_cgroup *memcg); void lru_gen_exit_memcg(struct mem_cgroup *memcg); @@ -574,8 +574,9 @@ static inline void lru_gen_init_lruvec(struct lruvec *lruvec) { } -static inline void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) +static inline bool lru_gen_look_around(struct page_vma_mapped_walk *pvmw) { + return false; } static inline void lru_gen_init_memcg(struct mem_cgroup *memcg) diff --git a/mm/rmap.c b/mm/rmap.c index a8797d1b3d496..73d5998677d40 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -885,13 +885,10 @@ static bool folio_referenced_one(struct folio *folio, return false; } - if (pvmw.pte) { - if (lru_gen_enabled() && - pte_young(ptep_get(pvmw.pte))) { - lru_gen_look_around(&pvmw); + if (lru_gen_enabled() && pvmw.pte) { + if (lru_gen_look_around(&pvmw)) referenced++; - } - + } else if (pvmw.pte) { if (ptep_clear_flush_young_notify(vma, address, pvmw.pte)) referenced++; diff --git a/mm/vmscan.c b/mm/vmscan.c index 4f1d33e4b3601..ddaaff67642e1 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -3294,7 +3295,8 @@ static bool get_next_vma(unsigned long mask, unsigned long size, struct mm_walk return false; } -static unsigned long get_pte_pfn(pte_t pte, struct vm_area_struct *vma, unsigned long addr) +static unsigned long get_pte_pfn(pte_t pte, struct vm_area_struct *vma, unsigned long addr, + struct pglist_data *pgdat) { unsigned long pfn = pte_pfn(pte); @@ -3306,13 +3308,20 @@ static unsigned long get_pte_pfn(pte_t pte, struct vm_area_struct *vma, unsigned if (WARN_ON_ONCE(pte_devmap(pte) || pte_special(pte))) return -1; + if (!pte_young(pte) && !mm_has_notifiers(vma->vm_mm)) + return -1; + if (WARN_ON_ONCE(!pfn_valid(pfn))) return -1; + if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat)) + return -1; + return pfn; } -static unsigned long get_pmd_pfn(pmd_t pmd, struct vm_area_struct *vma, unsigned long addr) +static unsigned long get_pmd_pfn(pmd_t pmd, struct vm_area_struct *vma, unsigned long addr, + struct pglist_data *pgdat) { unsigned long pfn = pmd_pfn(pmd); @@ -3324,9 +3333,15 @@ static unsigned long get_pmd_pfn(pmd_t pmd, struct vm_area_struct *vma, unsigned if (WARN_ON_ONCE(pmd_devmap(pmd))) return -1; + if (!pmd_young(pmd) && !mm_has_notifiers(vma->vm_mm)) + return -1; + if (WARN_ON_ONCE(!pfn_valid(pfn))) return -1; + if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat)) + return -1; + return pfn; } @@ -3335,10 +3350,6 @@ static struct folio *get_pfn_folio(unsigned long pfn, struct mem_cgroup *memcg, { struct folio *folio; - /* try to avoid unnecessary memory loads */ - if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat)) - return NULL; - folio = pfn_folio(pfn); if (folio_nid(folio) != pgdat->node_id) return NULL; @@ -3394,20 +3405,16 @@ static bool walk_pte_range(pmd_t *pmd, unsigned long start, unsigned long end, total++; walk->mm_stats[MM_LEAF_TOTAL]++; - pfn = get_pte_pfn(ptent, args->vma, addr); + pfn = get_pte_pfn(ptent, args->vma, addr, pgdat); if (pfn == -1) continue; - if (!pte_young(ptent)) { - continue; - } - folio = get_pfn_folio(pfn, memcg, pgdat, walk->can_swap); if (!folio) continue; - if (!ptep_test_and_clear_young(args->vma, addr, pte + i)) - VM_WARN_ON_ONCE(true); + if (!ptep_clear_young_notify(args->vma, addr, pte + i)) + continue; young++; walk->mm_stats[MM_LEAF_YOUNG]++; @@ -3473,21 +3480,25 @@ static void walk_pmd_range_locked(pud_t *pud, unsigned long addr, struct vm_area /* don't round down the first address */ addr = i ? (*first & PMD_MASK) + i * PMD_SIZE : *first; - pfn = get_pmd_pfn(pmd[i], vma, addr); - if (pfn == -1) + if (!pmd_present(pmd[i])) goto next; if (!pmd_trans_huge(pmd[i])) { - if (!walk->force_scan && should_clear_pmd_young()) + if (!walk->force_scan && should_clear_pmd_young() && + !mm_has_notifiers(args->mm)) pmdp_test_and_clear_young(vma, addr, pmd + i); goto next; } + pfn = get_pmd_pfn(pmd[i], vma, addr, pgdat); + if (pfn == -1) + goto next; + folio = get_pfn_folio(pfn, memcg, pgdat, walk->can_swap); if (!folio) goto next; - if (!pmdp_test_and_clear_young(vma, addr, pmd + i)) + if (!pmdp_clear_young_notify(vma, addr, pmd + i)) goto next; walk->mm_stats[MM_LEAF_YOUNG]++; @@ -3545,24 +3556,18 @@ static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end, } if (pmd_trans_huge(val)) { - unsigned long pfn = pmd_pfn(val); struct pglist_data *pgdat = lruvec_pgdat(walk->lruvec); + unsigned long pfn = get_pmd_pfn(val, vma, addr, pgdat); walk->mm_stats[MM_LEAF_TOTAL]++; - if (!pmd_young(val)) { - continue; - } - - /* try to avoid unnecessary memory loads */ - if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat)) - continue; - - walk_pmd_range_locked(pud, addr, vma, args, bitmap, &first); + if (pfn != -1) + walk_pmd_range_locked(pud, addr, vma, args, bitmap, &first); continue; } - if (!walk->force_scan && should_clear_pmd_young()) { + if (!walk->force_scan && should_clear_pmd_young() && + !mm_has_notifiers(args->mm)) { if (!pmd_young(val)) continue; @@ -4036,13 +4041,13 @@ static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc) * the PTE table to the Bloom filter. This forms a feedback loop between the * eviction and the aging. */ -void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) +bool lru_gen_look_around(struct page_vma_mapped_walk *pvmw) { int i; unsigned long start; unsigned long end; struct lru_gen_mm_walk *walk; - int young = 0; + int young = 1; pte_t *pte = pvmw->pte; unsigned long addr = pvmw->address; struct vm_area_struct *vma = pvmw->vma; @@ -4058,12 +4063,15 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) lockdep_assert_held(pvmw->ptl); VM_WARN_ON_ONCE_FOLIO(folio_test_lru(folio), folio); + if (!ptep_clear_young_notify(vma, addr, pte)) + return false; + if (spin_is_contended(pvmw->ptl)) - return; + return true; /* exclude special VMAs containing anon pages from COW */ if (vma->vm_flags & VM_SPECIAL) - return; + return true; /* avoid taking the LRU lock under the PTL when possible */ walk = current->reclaim_state ? current->reclaim_state->mm_walk : NULL; @@ -4071,6 +4079,9 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) start = max(addr & PMD_MASK, vma->vm_start); end = min(addr | ~PMD_MASK, vma->vm_end - 1) + 1; + if (end - start == PAGE_SIZE) + return true; + if (end - start > MIN_LRU_BATCH * PAGE_SIZE) { if (addr - start < MIN_LRU_BATCH * PAGE_SIZE / 2) end = start + MIN_LRU_BATCH * PAGE_SIZE; @@ -4084,7 +4095,7 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) /* folio_update_gen() requires stable folio_memcg() */ if (!mem_cgroup_trylock_pages(memcg)) - return; + return true; arch_enter_lazy_mmu_mode(); @@ -4094,19 +4105,16 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) unsigned long pfn; pte_t ptent = ptep_get(pte + i); - pfn = get_pte_pfn(ptent, vma, addr); + pfn = get_pte_pfn(ptent, vma, addr, pgdat); if (pfn == -1) continue; - if (!pte_young(ptent)) - continue; - folio = get_pfn_folio(pfn, memcg, pgdat, can_swap); if (!folio) continue; - if (!ptep_test_and_clear_young(vma, addr, pte + i)) - VM_WARN_ON_ONCE(true); + if (!ptep_clear_young_notify(vma, addr, pte + i)) + continue; young++; @@ -4136,6 +4144,8 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) /* feedback from rmap walkers to page table walkers */ if (mm_state && suitable_to_scan(i, young)) update_bloom_filter(mm_state, max_seq, pvmw->pmd); + + return true; } /****************************************************************************** -- 2.43.0