From nobody Sat Jul 25 05:22:16 2026 Received: from out-176.mta1.migadu.com (out-176.mta1.migadu.com [95.215.58.176]) (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 929673F1AB1 for ; Fri, 17 Jul 2026 11:33:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784288033; cv=none; b=STx//6TAuO1XjDSDPNzuByZNIvXV2s5vQHusCpJp5P58PctiuU38Aq0gYh44FNq1isvUwKzAHnJwcykJYUuwCN98tHwVF+Hs+rMAhKLCnsfZhfds57xSTkZkUzpqB/3bXS60/k3McylDsd3qco94rympT6br/7/LmgMUquEmBiQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784288033; c=relaxed/simple; bh=kYFCKB1Mp5xS+cgzbUx5FFGtK5kVzo0WYvqVQYJHtQ4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=p16a0dYJ7OI0tR8iP5c2mw16HIvauF+SWzQhWLkT+Nsq+YuYN5nB8tJSPMdV6Qe/8i6JLbDdaLUZh4GEuoG13qq1Jf9ejeF1XDiBH1uTjuBl7AbBD8GjXU9CU1IRRaOhPMS3S9NtWy8wLyeAiUHKkl02gfJlnWV193tL+rC6XKA= 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=Ixlqaof0; arc=none smtp.client-ip=95.215.58.176 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="Ixlqaof0" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1784288027; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DprPjyu/Xh7pvxQDg4G9+s5tuo/a+Q1TxmnJCqoFTQI=; b=Ixlqaof0mrjiVjyILhuAeq3Q/An2WVbFntlKx+qtS3BktN/efz9rs964udLFnTUJP+L0Ey GSl1v8lTdobCaV77p0Do+hUrPwm1bkoqeePDfZEnz98nDIUXEBxM5K9xx5sV7oklIVyqoS mkStED/E79xqKtf1bOVc9tW6p5olwTM= From: Ridong To: Andrew Morton , Johannes Weiner Cc: Kairui Song , Qi Zheng , Shakeel Butt , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , David Hildenbrand , Michal Hocko , Lorenzo Stoakes , Zhongkun He , Muchun Song , Davidlohr Bueso , Roman Gushchin , linux-mm@kvack.org, linux-kernel@vger.kernel.org, Ridong Chen , Ridong Chen Subject: [PATCH 1/3] mm/vmscan: fix anon-only reclaim evicting file pages when swappiness=max Date: Fri, 17 Jul 2026 19:32:58 +0800 Message-Id: <20260717113300.214717-2-ridong.chen@linux.dev> In-Reply-To: <20260717113300.214717-1-ridong.chen@linux.dev> References: <20260717113300.214717-1-ridong.chen@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: Ridong Chen As Qi mentioned [1], when swappiness=3Dmax (SWAPPINESS_ANON_ONLY) is set, the reclaim logic is expected to reclaim anonymous pages exclusively. However, due to the current ordering of checks in get_scan_count(), file pages may still be evicted if can_reclaim_anon_pages() returns false, which contradicts the semantics of SWAPPINESS_ANON_ONLY. Reproducer in a cgroup holding 64M of file cache, with no swap configured: Before (file cache is wrongly evicted): # cat memory.stat anon 196608 file 67178496 pgscan_proactive 0 # echo "64M swappiness=3Dmax" > memory.reclaim # cat memory.stat anon 208896 file 4096 <- page cache evicted pgsteal_proactive 16400 pgscan_proactive 16400 After (file cache is left intact): # cat memory.stat anon 200704 file 67178496 pgscan_proactive 0 # echo "64M swappiness=3Dmax" > memory.reclaim -bash: echo: write error: Resource temporarily unavailable # cat memory.stat anon 208896 file 67178496 <- page cache untouched pgsteal_proactive 0 pgscan_proactive 0 Fix this by bailing out early when SWAPPINESS_ANON_ONLY is set and no anonymous pages are reclaimable, before falling back to file reclaim. [1] https://lore.kernel.org/cgroups/7ddf3eee-5fe2-45f7-8614-c8936a039e04@li= nux.dev/ Fixes: 68a1436bde00 ("mm: add swappiness=3Dmax arg to memory.reclaim for on= ly anon reclaim") Suggested-by: Qi Zheng Signed-off-by: Ridong Chen Acked-by: Johannes Weiner Acked-by: Shakeel Butt Reviewed-by: Muchun Song --- mm/vmscan.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 4357a44ee876..098adc599720 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2492,6 +2492,17 @@ static void get_scan_count(struct lruvec *lruvec, st= ruct scan_control *sc, enum scan_balance scan_balance; enum lru_list lru; =20 + /* Proactive reclaim initiated by userspace for anonymous memory only */ + if (swappiness =3D=3D SWAPPINESS_ANON_ONLY) { + WARN_ON_ONCE(!sc->proactive); + if (!can_reclaim_anon_pages(memcg, pgdat->node_id, sc)) { + memset(nr, 0, sizeof(*nr) * NR_LRU_LISTS); + return; + } + scan_balance =3D SCAN_ANON; + goto out; + } + /* If we have no swap space, do not bother scanning anon folios. */ if (!sc->may_swap || !can_reclaim_anon_pages(memcg, pgdat->node_id, sc)) { scan_balance =3D SCAN_FILE; @@ -2510,13 +2521,6 @@ static void get_scan_count(struct lruvec *lruvec, st= ruct scan_control *sc, goto out; } =20 - /* Proactive reclaim initiated by userspace for anonymous memory only */ - if (swappiness =3D=3D SWAPPINESS_ANON_ONLY) { - WARN_ON_ONCE(!sc->proactive); - scan_balance =3D SCAN_ANON; - goto out; - } - /* * Do not apply any pressure balancing cleverness when the * system is close to OOM, scan both anon and file equally --=20 2.34.1 From nobody Sat Jul 25 05:22:16 2026 Received: from out-180.mta1.migadu.com (out-180.mta1.migadu.com [95.215.58.180]) (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 7FDD73F4DC5 for ; Fri, 17 Jul 2026 11:34:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784288044; cv=none; b=oDVywvRX76n27IY/MDw3gyBMKZCCsz4VI9vNgaBXHxnTf1a2isK/Qgf8/vzxP3Wq27ifx3aRFoqkiEcKLD0mf35NZXQVG3804XzoTVF2wtLICvbGlbvS3J1iZWx8ctK2urEC8zXM/LOyHrQajVffnCay0TPssYorhRvyqQDeMng= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784288044; c=relaxed/simple; bh=6XbiC6AbwVTN8q21pbLa6f6Ks5nXpMEjJJ0qPoVzs1o=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ff53qMqMC3udug2gwWjabOpig/sPg6fYm1hedFjhgXg8RoPYqdGVvLE4tFPbr3ENhThFzjNYeKfg9IC1LJ+EESSPEy0uDAsOMHVkk5eNXh1cYUIA/i/mbaIOAloYJBj0GyxXtIR5aOXh48B32nzqNrkppCZUJpbRyrv9o263G4w= 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=AZ+Yr0Xv; arc=none smtp.client-ip=95.215.58.180 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="AZ+Yr0Xv" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1784288038; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Sc0VGRUzcqdv3KA7EiSHGFvMq8ccWrkhZ0yDnBW1FTs=; b=AZ+Yr0XvBQ4M5QU7eoDtvL5dH5Q8zO9GotliAwIYiggIQqu7EA//ED38790jEB1jVDW3XI tdN+nU+xZx85OZGsrBfpuMdjWHYp41hkfasWqbU+3EKYwn3AS4Yr+3E1hKsLpPlq9EYylB 6Hvv+VDn3OXrBBlYwTjcoUi4iztPxnU= From: Ridong To: Andrew Morton , Johannes Weiner Cc: Kairui Song , Qi Zheng , Shakeel Butt , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , David Hildenbrand , Michal Hocko , Lorenzo Stoakes , Zhongkun He , Muchun Song , Davidlohr Bueso , Roman Gushchin , linux-mm@kvack.org, linux-kernel@vger.kernel.org, Ridong Chen , Ridong Chen Subject: [PATCH 2/3] mm: vmscan: propagate real error code from per-node proactive reclaim Date: Fri, 17 Jul 2026 19:32:59 +0800 Message-Id: <20260717113300.214717-3-ridong.chen@linux.dev> In-Reply-To: <20260717113300.214717-1-ridong.chen@linux.dev> References: <20260717113300.214717-1-ridong.chen@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: Ridong Chen It has been observed that per-node proactive reclaim always returns -EAGAIN when any error occurs. As discussed in the mailing list [1], the interface should distinguish between cases where no reclaimable memory is left and where another entity is concurrently using the same interface. Propagate the real error code, consistent with how memcg proactive reclaim handles errors. [1] https://lore.kernel.org/all/20250717235604.2atyx2aobwowpge3@offworld/T/= #m3514718be82a31b05726a49da9b61fbfc69a589e Fixes: b980077899ea ("mm: introduce per-node proactive reclaim interface") Signed-off-by: Ridong Chen Acked-by: Johannes Weiner Acked-by: Shakeel Butt Reviewed-by: Muchun Song --- mm/vmscan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 098adc599720..45fbbefe0906 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -8008,7 +8008,7 @@ static ssize_t reclaim_store(struct device *dev, int ret, nid =3D dev->id; =20 ret =3D user_proactive_reclaim((char *)buf, NULL, NODE_DATA(nid)); - return ret ? -EAGAIN : count; + return ret ? ret : count; } =20 static DEVICE_ATTR_WO(reclaim); --=20 2.34.1 From nobody Sat Jul 25 05:22:16 2026 Received: from out-189.mta1.migadu.com (out-189.mta1.migadu.com [95.215.58.189]) (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 ADEF13DD523 for ; Fri, 17 Jul 2026 11:34:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.189 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784288056; cv=none; b=jzSuPXdkGgn8QnUq8zC5lHwV26vHMasyQJOBCGPHTtXNr4hvy9AyOFU1D7SPhfP4pwSwCEBCRcTt6PpNs61QuGgR6Yk6SSK/XqPMYX5+jH8C3jZycG+YM99WI5n8O2x4Y3Wmxf446G7PsgsINf3h/aQVtLePBEuPEP+iNS3pFew= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784288056; c=relaxed/simple; bh=HoBE2suShDrHy4Vlf4k+SnnuvP4e7LI69vyEizN7S4I=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=IuOuoIXuk7SpWCDKPbYWny972uMDTOqn9lBaGCn9kz6zykyaGismwpTCuxfLwqmVrsh6EsqGyBCHRlPg/q02KfLX1aMMVjtUbgJgrbFnRZD+R1+H/MoWTTsyPlgh/TXF38gktirhmHPA0qiWWplFNhydL26okQsMRfLasPfIfJU= 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=GmJL+ZXS; arc=none smtp.client-ip=95.215.58.189 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="GmJL+ZXS" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1784288049; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=z5tdw2I2w2kmXQSitUb9eexNs9mGFkjONwUJzVAe//Y=; b=GmJL+ZXS7uM7O5XfGgszJ2EdwmiEvbYDoyZTyB/8YOSEtJN8CDDpzjoECGE5dfFqmsZrbU ol/2KRj/EKAM/piIzF55To7qKfONo+KD8/oUpMu7EYo+FtDeypjt+Fwo9B9zthuhEu4YOQ KOZsOjQ7EYy0c2RjrFtjaIzq2Icb840= From: Ridong To: Andrew Morton , Johannes Weiner Cc: Kairui Song , Qi Zheng , Shakeel Butt , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , David Hildenbrand , Michal Hocko , Lorenzo Stoakes , Zhongkun He , Muchun Song , Davidlohr Bueso , Roman Gushchin , linux-mm@kvack.org, linux-kernel@vger.kernel.org, Ridong Chen , Ridong Chen Subject: [PATCH 3/3] mm: vmscan: drop unused gfp_mask parameter from __node_reclaim() Date: Fri, 17 Jul 2026 19:33:00 +0800 Message-Id: <20260717113300.214717-4-ridong.chen@linux.dev> In-Reply-To: <20260717113300.214717-1-ridong.chen@linux.dev> References: <20260717113300.214717-1-ridong.chen@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: Ridong Chen Commit 57972c78e678 ("mm/vmscan: make __node_reclaim() more generic") moved the scan_control construction out to the callers and passed the struct in by pointer. After that change every use of the gfp mask inside __node_reclaim() goes through sc->gfp_mask, leaving the gfp_mask parameter unused. Just remove the dead parameter and update the callers accordingly. No functional change. Signed-off-by: Ridong Chen Acked-by: Johannes Weiner Acked-by: Shakeel Butt Reviewed-by: Muchun Song --- mm/vmscan.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 45fbbefe0906..551c47a6cf6f 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -7729,7 +7729,7 @@ static unsigned long node_pagecache_reclaimable(struc= t pglist_data *pgdat) /* * Try to free up some pages from this node through reclaim. */ -static unsigned long __node_reclaim(struct pglist_data *pgdat, gfp_t gfp_m= ask, +static unsigned long __node_reclaim(struct pglist_data *pgdat, unsigned long nr_pages, struct scan_control *sc) { @@ -7821,7 +7821,7 @@ int node_reclaim(struct pglist_data *pgdat, gfp_t gfp= _mask, unsigned int order) if (test_and_set_bit_lock(PGDAT_RECLAIM_LOCKED, &pgdat->flags)) return NODE_RECLAIM_NOSCAN; =20 - ret =3D __node_reclaim(pgdat, gfp_mask, nr_pages, &sc) >=3D nr_pages; + ret =3D __node_reclaim(pgdat, nr_pages, &sc) >=3D nr_pages; clear_bit_unlock(PGDAT_RECLAIM_LOCKED, &pgdat->flags); =20 if (ret) @@ -7834,7 +7834,7 @@ int node_reclaim(struct pglist_data *pgdat, gfp_t gfp= _mask, unsigned int order) =20 #else =20 -static unsigned long __node_reclaim(struct pglist_data *pgdat, gfp_t gfp_m= ask, +static unsigned long __node_reclaim(struct pglist_data *pgdat, unsigned long nr_pages, struct scan_control *sc) { @@ -7940,8 +7940,7 @@ int user_proactive_reclaim(char *buf, &pgdat->flags)) return -EBUSY; =20 - reclaimed =3D __node_reclaim(pgdat, gfp_mask, - batch_size, &sc); + reclaimed =3D __node_reclaim(pgdat, batch_size, &sc); clear_bit_unlock(PGDAT_RECLAIM_LOCKED, &pgdat->flags); } =20 --=20 2.34.1