From nobody Tue Apr 7 23:40:52 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4B2E93C6A45 for ; Wed, 11 Mar 2026 12:09:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773230985; cv=none; b=eGCt/07cwPVzTKuEEjlSzkfTQWV2hjxrqgDUUVAXim7hskH/I1FwemBQcftK+DwalKlcCuBBezd/kAIqTDncQXLM5h1h6w7HKeLJZTW/xmxSO0jOIgCfaZReHkenJfVTPAyVsVgVPlUx4eRYN3vwx0inFLmi/kxY2sEbhvgLi6M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773230985; c=relaxed/simple; bh=rC4pO0IWDnF30bVsp69mvTMcZsws+nEtxbxlusOjQe0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dNSeQ40fMqLm7z2XGbtyG/hbDtOH6iMARlDWA3EhXF1M3hpRay2QTNTTktOcl/SLra/rsfPGf4+2F9VlEt+8EAiElEZIYKOzRHXYYSdM+iyqaLI2JVREf6nyT3ltWeEtLLnrB4sC2W17+fWtoIxelVIPLI01MGIKiaNS0JiXh5I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UYRl4yvJ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UYRl4yvJ" Received: by smtp.kernel.org (Postfix) with ESMTPS id 0F8F7C116C6; Wed, 11 Mar 2026 12:09:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773230985; bh=rC4pO0IWDnF30bVsp69mvTMcZsws+nEtxbxlusOjQe0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=UYRl4yvJ1o4wr+mqNseUyHMbQOZURSNHbP4V4dIZl3aZ0sIr866pecEB7LC+GkH66 P7fmi3kYTdCBkV9apJ+2jzqAEoZ0jKUbqQRNZ8gxAoNcegC0fbdlw7MefpE10Ya10s f37nIaa836ItyxNF6I/aWcnb0dysRdFLY677hYIKbShDb95Ma2x3wnMBA+jZMQfp+n Xlf6BFnXXhPEpCy+Ni1tdppTXFd2zAk2dlrzMvtMrCidOzOi/i6m/uFbGfKekcWcCQ xs6GPZXZMA/oFd0AqfYoPzLaNVDaZTdh4TLBAoRDDgUGqfZbeeKNocE2+8Jm0JrXil yBfB2Vxo2PK4A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id F38861062874; Wed, 11 Mar 2026 12:09:44 +0000 (UTC) From: Leno Hou via B4 Relay Date: Wed, 11 Mar 2026 20:09:43 +0800 Subject: [PATCH v2 2/2] mm/mglru: maintain workingset refault context across state transitions Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260311-b4-switch-mglru-v2-v2-2-080cb9321463@gmail.com> References: <20260311-b4-switch-mglru-v2-v2-0-080cb9321463@gmail.com> In-Reply-To: <20260311-b4-switch-mglru-v2-v2-0-080cb9321463@gmail.com> To: Andrew Morton , Axel Rasmussen , Yuanchu Xie , Wei Xu , Jialing Wang , Yafang Shao , Yu Zhao , Kairui Song , Bingfang Guo , Barry Song Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Leno Hou X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1773230982; l=5011; i=lenohou@gmail.com; s=20260311; h=from:subject:message-id; bh=mpnWMW6S89qGDIwaKivQjNoGDsv2soTWaW1Gf6K14EE=; b=xcndljvTygCcwBzsgj8nOw/iRC7PBqzNOjNrqjCnt1Bogi0UldgGc+rLPInShme/2seEjuxVE 5txGqDKNySACcCOr+H31oDye4fgESyq3o03RYnnnbcViC1fsrV+Y3ed X-Developer-Key: i=lenohou@gmail.com; a=ed25519; pk=8AVHXYurzu1kOGjk9rwvxovwSCynBkv2QAcOvSIe1rw= X-Endpoint-Received: by B4 Relay for lenohou@gmail.com/20260311 with auth_id=674 X-Original-From: Leno Hou Reply-To: lenohou@gmail.com From: Leno Hou When MGLRU state is toggled dynamically, existing shadow entries (eviction tokens) lose their context. Traditional LRU and MGLRU handle workingset refaults using different logic. Without context, shadow entries re-activated by the "wrong" reclaim logic trigger excessive page activations (pgactivate) and system thrashing, as the kernel cannot correctly distinguish if a refaulted page was originally managed by MGLRU or the traditional LRU. This patch introduces shadow entry context tracking: - Encode MGLRU origin: Introduce WORKINGSET_MGLRU_SHIFT into the shadow entry (eviction token) encoding. This adds an 'is_mglru' bit to shadow entries, allowing the kernel to correctly identify the originating reclaim logic for a page even after the global MGLRU state has been toggled. - Refault logic dispatch: Use this 'is_mglru' bit in workingset_refault() and workingset_test_recent() to dispatch refault events to the correct handler (lru_gen_refault vs. traditional workingset refault). This ensures that refaulted pages are handled by the appropriate reclaim logic regardless of the current MGLRU enabled state, preventing unnecessary thrashing and state-inconsistent refault activations during state transitions. To: Andrew Morton To: Axel Rasmussen To: Yuanchu Xie To: Wei Xu To: Barry Song <21cnbao@gmail.com> To: Jialing Wang To: Yafang Shao To: Yu Zhao To: Kairui Song To: Bingfang Guo Cc: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Leno Hou --- mm/workingset.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/mm/workingset.c b/mm/workingset.c index 13422d304715..baa766daac24 100644 --- a/mm/workingset.c +++ b/mm/workingset.c @@ -180,8 +180,10 @@ * refault distance will immediately activate the refaulting page. */ =20 +#define WORKINGSET_MGLRU_SHIFT 1 #define WORKINGSET_SHIFT 1 #define EVICTION_SHIFT ((BITS_PER_LONG - BITS_PER_XA_VALUE) + \ + WORKINGSET_MGLRU_SHIFT + \ WORKINGSET_SHIFT + NODES_SHIFT + \ MEM_CGROUP_ID_SHIFT) #define EVICTION_MASK (~0UL >> EVICTION_SHIFT) @@ -197,12 +199,13 @@ static unsigned int bucket_order __read_mostly; =20 static void *pack_shadow(int memcgid, pg_data_t *pgdat, unsigned long evic= tion, - bool workingset) + bool workingset, bool is_mglru) { eviction &=3D EVICTION_MASK; eviction =3D (eviction << MEM_CGROUP_ID_SHIFT) | memcgid; eviction =3D (eviction << NODES_SHIFT) | pgdat->node_id; eviction =3D (eviction << WORKINGSET_SHIFT) | workingset; + eviction =3D (eviction << WORKINGSET_MGLRU_SHIFT) | is_mglru; =20 return xa_mk_value(eviction); } @@ -214,6 +217,7 @@ static void unpack_shadow(void *shadow, int *memcgidp, = pg_data_t **pgdat, int memcgid, nid; bool workingset; =20 + entry >>=3D WORKINGSET_MGLRU_SHIFT; workingset =3D entry & ((1UL << WORKINGSET_SHIFT) - 1); entry >>=3D WORKINGSET_SHIFT; nid =3D entry & ((1UL << NODES_SHIFT) - 1); @@ -254,7 +258,7 @@ static void *lru_gen_eviction(struct folio *folio) hist =3D lru_hist_from_seq(min_seq); atomic_long_add(delta, &lrugen->evicted[hist][type][tier]); =20 - return pack_shadow(mem_cgroup_private_id(memcg), pgdat, token, workingset= ); + return pack_shadow(mem_cgroup_private_id(memcg), pgdat, token, workingset= , true); } =20 /* @@ -390,7 +394,7 @@ void *workingset_eviction(struct folio *folio, struct m= em_cgroup *target_memcg) VM_BUG_ON_FOLIO(folio_ref_count(folio), folio); VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio); =20 - if (lru_gen_enabled()) + if (folio_lru_gen(folio) !=3D -1) return lru_gen_eviction(folio); =20 lruvec =3D mem_cgroup_lruvec(target_memcg, pgdat); @@ -400,7 +404,7 @@ void *workingset_eviction(struct folio *folio, struct m= em_cgroup *target_memcg) eviction >>=3D bucket_order; workingset_age_nonresident(lruvec, folio_nr_pages(folio)); return pack_shadow(memcgid, pgdat, eviction, - folio_test_workingset(folio)); + folio_test_workingset(folio), false); } =20 /** @@ -426,8 +430,10 @@ bool workingset_test_recent(void *shadow, bool file, b= ool *workingset, int memcgid; struct pglist_data *pgdat; unsigned long eviction; + unsigned long entry =3D xa_to_value(shadow); + bool is_mglru =3D !!(entry & WORKINGSET_MGLRU_SHIFT); =20 - if (lru_gen_enabled()) { + if (is_mglru) { bool recent; =20 rcu_read_lock(); @@ -539,10 +545,11 @@ void workingset_refault(struct folio *folio, void *sh= adow) struct lruvec *lruvec; bool workingset; long nr; + unsigned long entry =3D xa_to_value(shadow); =20 VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio); =20 - if (lru_gen_enabled()) { + if (entry & ((1UL << WORKINGSET_MGLRU_SHIFT) - 1)) { lru_gen_refault(folio, shadow); return; } --=20 2.52.0