From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out-181.mta1.migadu.com (out-181.mta1.migadu.com [95.215.58.181]) (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 D7864220698 for ; Fri, 24 Jul 2026 02:21:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.181 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784859662; cv=none; b=QGTQFAuBKZS4s/tQ4RzjnJmsJK73ppIlQsJzLnFZpBGD5seHnbXvMl4S94VArF8ptKi1qMw1ZpX7+212rvuSyME5gBEquWY41m9MgPbqOEIOut9woT2pDgWHnl33ynOlG3JoaoJ4tOYxTk3VuhFwbJWjqEbO7DdGugQlzv0k1FM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784859662; c=relaxed/simple; bh=INJeF87RWnhe74I3N7SI0ypnlCV3G5xeh7vGB1hCuIA=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=PZWaZFZqH4t/pzoAb/VU3wqmsPppiT+myx5YWtmtf9XnQeAnEqwP08ff+TmVASTNrx1VIjtdN20HSDgksL1o1KDVwXmdr/KxPdKFQtM5J11zRAAWr/E0n44dh0tG+ptaWGe07h1kmAETCcychMBbg/dVGgXAbk1J/4X6eHL4wcU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=MF/5NYKf; arc=none smtp.client-ip=95.215.58.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="MF/5NYKf" Message-ID: <5b26565b-300a-498e-afb3-e5ee1d7fe84b@linux.dev> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1784859658; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=p3F27zBrceeZbGaaILb47jwwDwAQwrNTSWn2X4PwsM0=; b=MF/5NYKfUFVC4TwZgMWGbDo3Xx1CUS/Z+8ZSw3ZSegNIJ/W0PAFnzElyNINp3EfbSW8A2V g+9gIXC/pmcMI0l/Vk3vsqpOW70OPx9hC5c/spOwDjKsWLbtvdd2RUh2FVLJCM4ys3nqrc O2yhdJkpdQdXyrHGvNSAMH598aQOjio= Date: Fri, 24 Jul 2026 10:20:40 +0800 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Subject: Re: [PATCH v3 4/4] mm/mglru: fix anon-only reclaim evicting file pages when swappiness=max To: Barry Song Cc: Andrew Morton , Johannes Weiner , David Hildenbrand , Michal Hocko , Qi Zheng , Shakeel Butt , Lorenzo Stoakes , Kairui Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Zhongkun He , Muchun Song , Davidlohr Bueso , Roman Gushchin , linux-mm@kvack.org, linux-kernel@vger.kernel.org, Ridong Chen References: <20260723045718.2052070-1-ridong.chen@linux.dev> <20260723045718.2052070-5-ridong.chen@linux.dev> X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Ridong Chen In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT On 7/23/2026 4:57 PM, Barry Song wrote: > On Thu, Jul 23, 2026 at 12:58 PM Ridong wrote: >> >> From: Ridong Chen >> >> The previous patch fixed this issue for the traditional LRU. The same >> problem exists in MGLRU [1]: when swappiness=max (SWAPPINESS_ANON_ONLY) >> is set, reclaim is expected to evict anonymous pages exclusively, but >> file pages can still be reclaimed when anonymous pages cannot be >> reclaimed (e.g. no swap and no demotion target). >> >> With SWAPPINESS_ANON_ONLY, get_type_to_scan() always returns >> LRU_GEN_ANON and for_each_evictable_type() only iterates the anon type. >> But if get_nr_to_scan() does not bail out, evict_folios() still runs and >> isolate_folios() falls back to scanning file pages in the !scanned case: >> >> shrink_one >> try_to_shrink_lruvec >> get_swappiness // returns SWAPPINESS_ANON_ONLY for swappiness=max >> get_nr_to_scan >> evict_folios >> isolate_folios // falls back to file type when !scanned >> > > I am not convinced this is correct. Although we do have `type = !type`, > when `swappiness == 201`, `for_each_evictable_type()` stops iterating > after trying a single type, so there is no opportunity to fall back. > > #define for_each_evictable_type(type, swappiness) \ > for ((type) = min_type(swappiness); (type) <= > max_type(swappiness); (type)++) > You're right. In my initial version, the intention was to bail out early and avoid unnecessary work. I recall that during your review of Kairui's series, you sent a patch that used a fallback mechanism with type = !type. I was thinking that this could become an issue if we call isolate_folios() when swappiness is set to max. > So I'm really curious what's happening here. > > static int isolate_folios(unsigned long nr_to_scan, struct lruvec *lruvec, > struct scan_control *sc, int swappiness, > struct list_head *list, int *isolated, > int *isolate_type, int *isolate_scanned) > { > int i; > int total_scanned = 0; > int type = get_type_to_scan(lruvec, swappiness); > > for_each_evictable_type(i, swappiness) { > int scanned; > int tier = get_tier_idx(lruvec, type); > > scanned = scan_folios(nr_to_scan, lruvec, sc, > type, tier, list, isolated); > > ... > if (!scanned) > type = !type; > } > > return total_scanned; > } > > since both min and max types are anon: > #define min_type(swappiness) (!(swappiness)) > #define max_type(swappiness) ((swappiness) < SWAPPINESS_ANON_ONLY) > > I guess the real problem only occurs when `may_swap` is false? I added some trace logs to verify this behavior. If we don't make get_nr_to_scan() return 0 when swappiness=max, it won't fall back to scanning file pages, but it will still perform useless scanning that yields no reclaim. Log: # echo "64M swappiness=max" > memory.reclaim [ 78.914972] vmscan: in isolate_folios swappness 201 [ 78.916841] vmscan: call scan_folios type 0 [ 78.918311] vmscan: fall back 1 <- can't call scan_folios, loop ends. [ 78.919479] vmscan: out isolate_folios total_scanned 0 [...] # cat memory.stat | grep proactive pgdemote_proactive 0 pgsteal_proactive 0 pgscan_proactive 1808 I will update the commit message to clarify that get_nr_to_scan() returns 0 to avoid this useless work. -- Best regards Ridong