mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/3] mm: clean up folio LRU and swap declarations
@ 2026-05-31  9:50 Jianyue Wu
  2026-05-31  9:50 ` [PATCH v2 1/3] mm/swap: colocate page-cluster sysctl with swap readahead Jianyue Wu
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Jianyue Wu @ 2026-05-31  9:50 UTC (permalink / raw)
  To: Andrew Morton, Chris Li, Kairui Song, Kemeng Shi, Nhat Pham,
	Baoquan He, Barry Song, Youngjun Park, Qi Zheng, Shakeel Butt,
	Axel Rasmussen, Yuanchu Xie, Wei Xu, Johannes Weiner,
	David Hildenbrand, Michal Hocko, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Hugh Dickins, Baolin Wang
  Cc: linux-mm, linux-kernel, Jianyue Wu

This is a v2 of the previous single-patch cleanup:

  https://lore.kernel.org/r/20260407110002.204755-1-wujianyue000@gmail.com

The previous version moved the folio LRU helpers out of mm/swap.c in
one step. Based on review feedback from Johannes, Baoquan and Barry,
split the cleanup into smaller steps:

  - move the page-cluster sysctl next to swap readahead in mm/swap_state.c
  - rename mm/swap.c to mm/folio_lru.c after the swap-specific bits move out
  - move MM-internal reclaim declarations out of include/linux/swap.h

The first patch handles the swap-specific page-cluster state before the
file rename, so the rename commit only carries folio LRU code. The last
patch keeps the LRU helpers used outside mm/ in include/linux/swap.h and
moves the internal reclaim/workingset declarations to mm/internal.h.

This series is based on Christoph Hellwig's swap_ops series, which
moves swap I/O dispatch behind swap_ops and leaves mm/swap.c with less
swap-specific state. That makes the folio LRU cleanup more natural to
split out on top.

  https://lore.kernel.org/r/20260528124559.2566481-1-hch@lst.de

Signed-off-by: Jianyue Wu <wujianyue000@gmail.com>
---
Jianyue Wu (3):
      mm/swap: colocate page-cluster sysctl with swap readahead
      mm: move folio LRU code out of swap
      mm: move reclaim-internal declarations out of swap.h

 include/linux/swap.h       | 75 ++++------------------------------------------
 mm/Makefile                |  2 +-
 mm/{swap.c => folio_lru.c} | 38 +----------------------
 mm/internal.h              | 66 ++++++++++++++++++++++++++++++++++++++++
 mm/memfd.c                 |  1 +
 mm/swap.h                  |  2 --
 mm/swap_state.c            | 37 +++++++++++++++++++++++
 mm/vmscan.c                |  2 +-
 8 files changed, 113 insertions(+), 110 deletions(-)
---
base-commit: d7be408821acadd7d713d1da16a6742886799114
change-id: 20260531-ch-swap-series-plus-folio-lru-cleanup-d9781c8332dc

Best regards,
-- 
Jianyue Wu <wujianyue000@gmail.com>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/3] mm/swap: colocate page-cluster sysctl with swap readahead
  2026-05-31  9:50 [PATCH v2 0/3] mm: clean up folio LRU and swap declarations Jianyue Wu
@ 2026-05-31  9:50 ` Jianyue Wu
  2026-05-31 22:06   ` Barry Song
  2026-05-31  9:50 ` [PATCH v2 2/3] mm: move folio LRU code out of swap Jianyue Wu
  2026-05-31  9:50 ` [PATCH v2 3/3] mm: move reclaim-internal declarations out of swap.h Jianyue Wu
  2 siblings, 1 reply; 9+ messages in thread
From: Jianyue Wu @ 2026-05-31  9:50 UTC (permalink / raw)
  To: Andrew Morton, Chris Li, Kairui Song, Kemeng Shi, Nhat Pham,
	Baoquan He, Barry Song, Youngjun Park, Qi Zheng, Shakeel Butt,
	Axel Rasmussen, Yuanchu Xie, Wei Xu, Johannes Weiner,
	David Hildenbrand, Michal Hocko, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Hugh Dickins, Baolin Wang
  Cc: linux-mm, linux-kernel, Jianyue Wu

page_cluster and the vm.page-cluster sysctl are only used by swap-in
readahead in swap_state.c. Move them out of swap.c together with
swap_readahead_setup(), and make page_cluster static to that file.

Rename swap_setup() while moving it as well. The helper is internal to
MM and now only sets up swap readahead defaults and its sysctl hook, so
the more specific name matches its reduced scope.

Signed-off-by: Jianyue Wu <wujianyue000@gmail.com>
---
 include/linux/swap.h |  2 +-
 mm/swap.c            | 36 ------------------------------------
 mm/swap.h            |  2 --
 mm/swap_state.c      | 37 +++++++++++++++++++++++++++++++++++++
 mm/vmscan.c          |  2 +-
 5 files changed, 39 insertions(+), 40 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index 636d94108166..c36f72877e8b 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -345,7 +345,7 @@ extern void lru_add_drain_cpu_zone(struct zone *zone);
 extern void lru_add_drain_all(void);
 void folio_deactivate(struct folio *folio);
 void folio_mark_lazyfree(struct folio *folio);
-extern void swap_setup(void);
+extern void swap_readahead_setup(void);
 
 /* linux/mm/vmscan.c */
 extern unsigned long zone_reclaimable_pages(struct zone *zone);
diff --git a/mm/swap.c b/mm/swap.c
index 588f50d8f1a8..e4b3dadaa6dc 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -43,10 +43,6 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/pagemap.h>
 
-/* How many pages do we try to swap or page in/out together? As a power of 2 */
-int page_cluster;
-static const int page_cluster_max = 31;
-
 struct cpu_fbatches {
 	/*
 	 * The following folio batches are grouped together because they are protected
@@ -1171,35 +1167,3 @@ void lru_reparent_memcg(struct mem_cgroup *memcg, struct mem_cgroup *parent, int
 		lruvec_reparent_lru(child_lruvec, parent_lruvec, lru, nid);
 }
 #endif
-
-static const struct ctl_table swap_sysctl_table[] = {
-	{
-		.procname	= "page-cluster",
-		.data		= &page_cluster,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= SYSCTL_ZERO,
-		.extra2		= (void *)&page_cluster_max,
-	}
-};
-
-/*
- * Perform any setup for the swap system
- */
-void __init swap_setup(void)
-{
-	unsigned long megs = PAGES_TO_MB(totalram_pages());
-
-	/* Use a smaller cluster for small-memory machines */
-	if (megs < 16)
-		page_cluster = 2;
-	else
-		page_cluster = 3;
-	/*
-	 * Right now other parts of the system means that we
-	 * _really_ don't want to cluster much more
-	 */
-
-	register_sysctl_init("vm", swap_sysctl_table);
-}
diff --git a/mm/swap.h b/mm/swap.h
index 8742b82cd0db..1a9b42440320 100644
--- a/mm/swap.h
+++ b/mm/swap.h
@@ -9,8 +9,6 @@ struct mempolicy;
 struct swap_iocb;
 struct swap_memcg_table;
 
-extern int page_cluster;
-
 #if defined(MAX_POSSIBLE_PHYSMEM_BITS)
 #define SWAP_CACHE_PFN_BITS (MAX_POSSIBLE_PHYSMEM_BITS - PAGE_SHIFT)
 #elif defined(MAX_PHYSMEM_BITS)
diff --git a/mm/swap_state.c b/mm/swap_state.c
index b9613026950e..e8f1fb37a6cf 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -22,10 +22,15 @@
 #include <linux/vmalloc.h>
 #include <linux/huge_mm.h>
 #include <linux/shmem_fs.h>
+#include <linux/sysctl.h>
 #include "internal.h"
 #include "swap_table.h"
 #include "swap.h"
 
+/* How many pages do we try to swap or page in/out together? As a power of 2 */
+static int page_cluster;
+static const int page_cluster_max = 31;
+
 /*
  * swapper_space is a fiction, retained to simplify the path through
  * vmscan's shrink_folio_list.
@@ -986,6 +991,38 @@ struct folio *swapin_readahead(swp_entry_t entry, gfp_t gfp_mask,
 	return folio;
 }
 
+static const struct ctl_table swap_sysctl_table[] = {
+	{
+		.procname	= "page-cluster",
+		.data		= &page_cluster,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= SYSCTL_ZERO,
+		.extra2		= (void *)&page_cluster_max,
+	}
+};
+
+/**
+ * swap_readahead_setup - defaults and sysctl for swap cache readahead clustering
+ */
+void __init swap_readahead_setup(void)
+{
+	unsigned long megs = PAGES_TO_MB(totalram_pages());
+
+	/* Use a smaller cluster for small-memory machines */
+	if (megs < 16)
+		page_cluster = 2;
+	else
+		page_cluster = 3;
+	/*
+	 * Right now other parts of the system means that we
+	 * _really_ don't want to cluster much more
+	 */
+
+	register_sysctl_init("vm", swap_sysctl_table);
+}
+
 #ifdef CONFIG_SYSFS
 static ssize_t vma_ra_enabled_show(struct kobject *kobj,
 				     struct kobj_attribute *attr, char *buf)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 2d44ebfebdea..e34f1565f42f 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -7651,7 +7651,7 @@ static int __init kswapd_init(void)
 {
 	int nid;
 
-	swap_setup();
+	swap_readahead_setup();
 	for_each_node_state(nid, N_MEMORY)
  		kswapd_run(nid);
 	register_sysctl_init("vm", vmscan_sysctl_table);

-- 
2.43.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 2/3] mm: move folio LRU code out of swap
  2026-05-31  9:50 [PATCH v2 0/3] mm: clean up folio LRU and swap declarations Jianyue Wu
  2026-05-31  9:50 ` [PATCH v2 1/3] mm/swap: colocate page-cluster sysctl with swap readahead Jianyue Wu
@ 2026-05-31  9:50 ` Jianyue Wu
  2026-06-01 14:48   ` David Hildenbrand (Arm)
  2026-05-31  9:50 ` [PATCH v2 3/3] mm: move reclaim-internal declarations out of swap.h Jianyue Wu
  2 siblings, 1 reply; 9+ messages in thread
From: Jianyue Wu @ 2026-05-31  9:50 UTC (permalink / raw)
  To: Andrew Morton, Chris Li, Kairui Song, Kemeng Shi, Nhat Pham,
	Baoquan He, Barry Song, Youngjun Park, Qi Zheng, Shakeel Butt,
	Axel Rasmussen, Yuanchu Xie, Wei Xu, Johannes Weiner,
	David Hildenbrand, Michal Hocko, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Hugh Dickins, Baolin Wang
  Cc: linux-mm, linux-kernel, Jianyue Wu

Rename mm/swap.c to mm/folio_lru.c so the filename better matches
the code's main responsibility.

This keeps the implementation split from swap-specific code without
changing the published LRU helper interfaces.

Signed-off-by: Jianyue Wu <wujianyue000@gmail.com>
---
 mm/Makefile                | 2 +-
 mm/{swap.c => folio_lru.c} | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/Makefile b/mm/Makefile
index eff9f9e7e061..5f712f9bbe73 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -50,7 +50,7 @@ endif
 
 obj-y			:= filemap.o mempool.o oom_kill.o fadvise.o \
 			   maccess.o page-writeback.o folio-compat.o \
-			   readahead.o swap.o truncate.o vmscan.o shrinker.o \
+			   readahead.o folio_lru.o truncate.o vmscan.o shrinker.o \
 			   shmem.o util.o mmzone.o vmstat.o backing-dev.o \
 			   mm_init.o percpu.o slab_common.o \
 			   compaction.o show_mem.o \
diff --git a/mm/swap.c b/mm/folio_lru.c
similarity index 99%
rename from mm/swap.c
rename to mm/folio_lru.c
index e4b3dadaa6dc..7dab6a544d94 100644
--- a/mm/swap.c
+++ b/mm/folio_lru.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- *  linux/mm/swap.c
+ *  linux/mm/folio_lru.c
  *
  *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  */

-- 
2.43.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 3/3] mm: move reclaim-internal declarations out of swap.h
  2026-05-31  9:50 [PATCH v2 0/3] mm: clean up folio LRU and swap declarations Jianyue Wu
  2026-05-31  9:50 ` [PATCH v2 1/3] mm/swap: colocate page-cluster sysctl with swap readahead Jianyue Wu
  2026-05-31  9:50 ` [PATCH v2 2/3] mm: move folio LRU code out of swap Jianyue Wu
@ 2026-05-31  9:50 ` Jianyue Wu
  2026-06-01 14:57   ` David Hildenbrand (Arm)
  2 siblings, 1 reply; 9+ messages in thread
From: Jianyue Wu @ 2026-05-31  9:50 UTC (permalink / raw)
  To: Andrew Morton, Chris Li, Kairui Song, Kemeng Shi, Nhat Pham,
	Baoquan He, Barry Song, Youngjun Park, Qi Zheng, Shakeel Butt,
	Axel Rasmussen, Yuanchu Xie, Wei Xu, Johannes Weiner,
	David Hildenbrand, Michal Hocko, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Hugh Dickins, Baolin Wang
  Cc: linux-mm, linux-kernel, Jianyue Wu

Keep include/linux/swap.h focused on swap-facing interfaces by moving
MM-internal reclaim and workingset declarations into mm/internal.h.

Leave the small set of LRU helper declarations that are used outside mm/
in swap.h so this cleanup does not need a new public header under
include/linux/.

Signed-off-by: Jianyue Wu <wujianyue000@gmail.com>
---
 include/linux/swap.h | 75 +++++-----------------------------------------------
 mm/internal.h        | 66 +++++++++++++++++++++++++++++++++++++++++++++
 mm/memfd.c           |  1 +
 3 files changed, 73 insertions(+), 69 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index c36f72877e8b..1ef6ae7b2db7 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -292,39 +292,17 @@ static inline swp_entry_t page_swap_entry(struct page *page)
 	return entry;
 }
 
-/* linux/mm/workingset.c */
-bool workingset_test_recent(void *shadow, bool file, bool *workingset,
-				bool flush);
-void workingset_age_nonresident(struct lruvec *lruvec, unsigned long nr_pages);
-void *workingset_eviction(struct folio *folio, struct mem_cgroup *target_memcg);
-void workingset_refault(struct folio *folio, void *shadow);
-void workingset_activation(struct folio *folio);
-
 /* linux/mm/page_alloc.c */
 extern unsigned long totalreserve_pages;
 
 /* Definition of global_zone_page_state not available yet */
 #define nr_free_pages() global_zone_page_state(NR_FREE_PAGES)
 
-
-/* linux/mm/swap.c */
-void lru_note_cost_unlock_irq(struct lruvec *lruvec, bool file,
-		unsigned int nr_io, unsigned int nr_rotated);
-void lru_note_cost_refault(struct folio *);
-void folio_add_lru(struct folio *);
-void folio_add_lru_vma(struct folio *, struct vm_area_struct *);
-void mark_page_accessed(struct page *);
-void folio_mark_accessed(struct folio *);
-
-static inline bool folio_may_be_lru_cached(struct folio *folio)
-{
-	/*
-	 * Holding PMD-sized folios in per-CPU LRU cache unbalances accounting.
-	 * Holding small numbers of low-order mTHP folios in per-CPU LRU cache
-	 * will be sensible, but nobody has implemented and tested that yet.
-	 */
-	return !folio_test_large(folio);
-}
+/* Generic folio LRU helpers used outside mm/. */
+void folio_add_lru(struct folio *folio);
+void mark_page_accessed(struct page *page);
+void folio_mark_accessed(struct folio *folio);
+void lru_add_drain_all(void);
 
 extern atomic_t lru_disable_count;
 
@@ -333,43 +311,7 @@ static inline bool lru_cache_disabled(void)
 	return atomic_read(&lru_disable_count);
 }
 
-static inline void lru_cache_enable(void)
-{
-	atomic_dec(&lru_disable_count);
-}
-
-extern void lru_cache_disable(void);
-extern void lru_add_drain(void);
-extern void lru_add_drain_cpu(int cpu);
-extern void lru_add_drain_cpu_zone(struct zone *zone);
-extern void lru_add_drain_all(void);
-void folio_deactivate(struct folio *folio);
-void folio_mark_lazyfree(struct folio *folio);
-extern void swap_readahead_setup(void);
-
 /* linux/mm/vmscan.c */
-extern unsigned long zone_reclaimable_pages(struct zone *zone);
-extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
-					gfp_t gfp_mask, nodemask_t *mask);
-unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru, int zone_idx);
-
-#define MEMCG_RECLAIM_MAY_SWAP (1 << 1)
-#define MEMCG_RECLAIM_PROACTIVE (1 << 2)
-#define MIN_SWAPPINESS 0
-#define MAX_SWAPPINESS 200
-
-/* Just reclaim from anon folios in proactive memory reclaim */
-#define SWAPPINESS_ANON_ONLY (MAX_SWAPPINESS + 1)
-
-extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg,
-						  unsigned long nr_pages,
-						  gfp_t gfp_mask,
-						  unsigned int reclaim_options,
-						  int *swappiness);
-extern unsigned long mem_cgroup_shrink_node(struct mem_cgroup *mem,
-						gfp_t gfp_mask, bool noswap,
-						pg_data_t *pgdat,
-						unsigned long *nr_scanned);
 extern unsigned long shrink_all_memory(unsigned long nr_pages);
 extern int vm_swappiness;
 long remove_mapping(struct address_space *mapping, struct folio *folio);
@@ -390,11 +332,6 @@ static inline void reclaim_unregister_node(struct node *node)
 }
 #endif /* CONFIG_SYSFS && CONFIG_NUMA */
 
-#ifdef CONFIG_NUMA
-extern int sysctl_min_unmapped_ratio;
-extern int sysctl_min_slab_ratio;
-#endif
-
 void check_move_unevictable_folios(struct folio_batch *fbatch);
 
 extern void __meminit kswapd_run(int nid);
@@ -554,7 +491,7 @@ static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
 
 void lru_reparent_memcg(struct mem_cgroup *memcg, struct mem_cgroup *parent, int nid);
 #else
-static inline int mem_cgroup_swappiness(struct mem_cgroup *mem)
+static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
 {
 	return READ_ONCE(vm_swappiness);
 }
diff --git a/mm/internal.h b/mm/internal.h
index 5602393054f3..5475ba38a621 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -24,6 +24,72 @@
 
 struct folio_batch;
 
+bool workingset_test_recent(void *shadow, bool file, bool *workingset,
+			    bool flush);
+void workingset_age_nonresident(struct lruvec *lruvec, unsigned long nr_pages);
+void *workingset_eviction(struct folio *folio,
+			  struct mem_cgroup *target_memcg);
+void workingset_refault(struct folio *folio, void *shadow);
+void workingset_activation(struct folio *folio);
+
+void lru_note_cost_unlock_irq(struct lruvec *lruvec, bool file,
+		unsigned int nr_io, unsigned int nr_rotated)
+		__releases(lruvec->lru_lock);
+void lru_note_cost_refault(struct folio *folio);
+void folio_add_lru_vma(struct folio *folio, struct vm_area_struct *vma);
+
+static inline bool folio_may_be_lru_cached(struct folio *folio)
+{
+	/*
+	 * Holding PMD-sized folios in per-CPU LRU cache unbalances accounting.
+	 * Holding small numbers of low-order mTHP folios in per-CPU LRU cache
+	 * will be sensible, but nobody has implemented and tested that yet.
+	 */
+	return !folio_test_large(folio);
+}
+
+static inline void lru_cache_enable(void)
+{
+	atomic_dec(&lru_disable_count);
+}
+
+void lru_cache_disable(void);
+void lru_add_drain(void);
+void lru_add_drain_cpu(int cpu);
+void lru_add_drain_cpu_zone(struct zone *zone);
+void folio_deactivate(struct folio *folio);
+void folio_mark_lazyfree(struct folio *folio);
+void swap_readahead_setup(void);
+
+unsigned long zone_reclaimable_pages(struct zone *zone);
+unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
+				gfp_t gfp_mask, nodemask_t *mask);
+unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru,
+			      int zone_idx);
+
+#define MEMCG_RECLAIM_MAY_SWAP (1 << 1)
+#define MEMCG_RECLAIM_PROACTIVE (1 << 2)
+#define MIN_SWAPPINESS 0
+#define MAX_SWAPPINESS 200
+
+/* Just reclaim from anon folios in proactive memory reclaim */
+#define SWAPPINESS_ANON_ONLY (MAX_SWAPPINESS + 1)
+
+unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg,
+					   unsigned long nr_pages,
+					   gfp_t gfp_mask,
+					   unsigned int reclaim_options,
+					   int *swappiness);
+unsigned long mem_cgroup_shrink_node(struct mem_cgroup *memcg,
+				     gfp_t gfp_mask, bool noswap,
+				     pg_data_t *pgdat,
+				     unsigned long *nr_scanned);
+
+#ifdef CONFIG_NUMA
+extern int sysctl_min_unmapped_ratio;
+extern int sysctl_min_slab_ratio;
+#endif
+
 /*
  * Maintains state across a page table move. The operation assumes both source
  * and destination VMAs already exist and are specified by the user.
diff --git a/mm/memfd.c b/mm/memfd.c
index abe13b291ddc..6c72fe6caef7 100644
--- a/mm/memfd.c
+++ b/mm/memfd.c
@@ -19,6 +19,7 @@
 #include <linux/memfd.h>
 #include <linux/pid_namespace.h>
 #include <uapi/linux/memfd.h>
+#include "internal.h"
 #include "swap.h"
 
 /*

-- 
2.43.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/3] mm/swap: colocate page-cluster sysctl with swap readahead
  2026-05-31  9:50 ` [PATCH v2 1/3] mm/swap: colocate page-cluster sysctl with swap readahead Jianyue Wu
@ 2026-05-31 22:06   ` Barry Song
  2026-06-01  0:59     ` Jianyue Wu
  0 siblings, 1 reply; 9+ messages in thread
From: Barry Song @ 2026-05-31 22:06 UTC (permalink / raw)
  To: Jianyue Wu
  Cc: Andrew Morton, Chris Li, Kairui Song, Kemeng Shi, Nhat Pham,
	Baoquan He, Youngjun Park, Qi Zheng, Shakeel Butt,
	Axel Rasmussen, Yuanchu Xie, Wei Xu, Johannes Weiner,
	David Hildenbrand, Michal Hocko, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Hugh Dickins, Baolin Wang,
	linux-mm, linux-kernel

On Sun, May 31, 2026 at 5:50 PM Jianyue Wu <wujianyue000@gmail.com> wrote:
>
> page_cluster and the vm.page-cluster sysctl are only used by swap-in
> readahead in swap_state.c. Move them out of swap.c together with
> swap_readahead_setup(), and make page_cluster static to that file.
>
> Rename swap_setup() while moving it as well. The helper is internal to
> MM and now only sets up swap readahead defaults and its sysctl hook, so
> the more specific name matches its reduced scope.
>
> Signed-off-by: Jianyue Wu <wujianyue000@gmail.com>
> ---
>  include/linux/swap.h |  2 +-
>  mm/swap.c            | 36 ------------------------------------
>  mm/swap.h            |  2 --
>  mm/swap_state.c      | 37 +++++++++++++++++++++++++++++++++++++
>  mm/vmscan.c          |  2 +-
>  5 files changed, 39 insertions(+), 40 deletions(-)
>
> diff --git a/include/linux/swap.h b/include/linux/swap.h
> index 636d94108166..c36f72877e8b 100644
> --- a/include/linux/swap.h
> +++ b/include/linux/swap.h
> @@ -345,7 +345,7 @@ extern void lru_add_drain_cpu_zone(struct zone *zone);
>  extern void lru_add_drain_all(void);
>  void folio_deactivate(struct folio *folio);
>  void folio_mark_lazyfree(struct folio *folio);
> -extern void swap_setup(void);
> +extern void swap_readahead_setup(void);

Can we move this to mm/swap.h?

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/3] mm/swap: colocate page-cluster sysctl with swap readahead
  2026-05-31 22:06   ` Barry Song
@ 2026-06-01  0:59     ` Jianyue Wu
  0 siblings, 0 replies; 9+ messages in thread
From: Jianyue Wu @ 2026-06-01  0:59 UTC (permalink / raw)
  To: Barry Song
  Cc: Andrew Morton, Chris Li, Kairui Song, Kemeng Shi, Nhat Pham,
	Baoquan He, Youngjun Park, Qi Zheng, Shakeel Butt,
	Axel Rasmussen, Yuanchu Xie, Wei Xu, Johannes Weiner,
	David Hildenbrand, Michal Hocko, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Hugh Dickins, Baolin Wang,
	linux-mm, linux-kernel

On 6/1/2026 6:06 AM, Barry Song wrote:
> On Sun, May 31, 2026 at 5:50 PM Jianyue Wu <wujianyue000@gmail.com> wrote:
>>
>> page_cluster and the vm.page-cluster sysctl are only used by swap-in
>> readahead in swap_state.c. Move them out of swap.c together with
>> swap_readahead_setup(), and make page_cluster static to that file.
>>
>> Rename swap_setup() while moving it as well. The helper is internal to
>> MM and now only sets up swap readahead defaults and its sysctl hook, so
>> the more specific name matches its reduced scope.
>>
>> Signed-off-by: Jianyue Wu <wujianyue000@gmail.com>
>> ---
>>   include/linux/swap.h |  2 +-
>>   mm/swap.c            | 36 ------------------------------------
>>   mm/swap.h            |  2 --
>>   mm/swap_state.c      | 37 +++++++++++++++++++++++++++++++++++++
>>   mm/vmscan.c          |  2 +-
>>   5 files changed, 39 insertions(+), 40 deletions(-)
>>
>> diff --git a/include/linux/swap.h b/include/linux/swap.h
>> index 636d94108166..c36f72877e8b 100644
>> --- a/include/linux/swap.h
>> +++ b/include/linux/swap.h
>> @@ -345,7 +345,7 @@ extern void lru_add_drain_cpu_zone(struct zone *zone);
>>   extern void lru_add_drain_all(void);
>>   void folio_deactivate(struct folio *folio);
>>   void folio_mark_lazyfree(struct folio *folio);
>> -extern void swap_setup(void);
>> +extern void swap_readahead_setup(void);
>
> Can we move this to mm/swap.h?

Yes, that makes sense.  swap_readahead_setup() is only used inside
mm/, and mm/vmscan.c already includes mm/swap.h, so it does not need to
stay in include/linux/swap.h.

I will move the prototype to mm/swap.h in v3.  While doing that, I will
also add a CONFIG_SWAP=n stub, because swap_state.o is only built when
CONFIG_SWAP is enabled, while kswapd_init() is built unconditionally.

Thanks,
Best regards,
Jianyue

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/3] mm: move folio LRU code out of swap
  2026-05-31  9:50 ` [PATCH v2 2/3] mm: move folio LRU code out of swap Jianyue Wu
@ 2026-06-01 14:48   ` David Hildenbrand (Arm)
  0 siblings, 0 replies; 9+ messages in thread
From: David Hildenbrand (Arm) @ 2026-06-01 14:48 UTC (permalink / raw)
  To: Jianyue Wu, Andrew Morton, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Qi Zheng,
	Shakeel Butt, Axel Rasmussen, Yuanchu Xie, Wei Xu,
	Johannes Weiner, Michal Hocko, Lorenzo Stoakes, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Hugh Dickins, Baolin Wang
  Cc: linux-mm, linux-kernel

On 5/31/26 11:50, Jianyue Wu wrote:
> Rename mm/swap.c to mm/folio_lru.c so the filename better matches
> the code's main responsibility.

I agree that this is cleaner than "swap.c" ...

> 
> This keeps the implementation split from swap-specific code without
> changing the published LRU helper interfaces.
> 
> Signed-off-by: Jianyue Wu <wujianyue000@gmail.com>
> ---
>  mm/Makefile                | 2 +-
>  mm/{swap.c => folio_lru.c} | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/mm/Makefile b/mm/Makefile
> index eff9f9e7e061..5f712f9bbe73 100644
> --- a/mm/Makefile
> +++ b/mm/Makefile
> @@ -50,7 +50,7 @@ endif
>  
>  obj-y			:= filemap.o mempool.o oom_kill.o fadvise.o \
>  			   maccess.o page-writeback.o folio-compat.o \
> -			   readahead.o swap.o truncate.o vmscan.o shrinker.o \
> +			   readahead.o folio_lru.o truncate.o vmscan.o shrinker.o \
>  			   shmem.o util.o mmzone.o vmstat.o backing-dev.o \
>  			   mm_init.o percpu.o slab_common.o \
>  			   compaction.o show_mem.o \
> diff --git a/mm/swap.c b/mm/folio_lru.c
> similarity index 99%
> rename from mm/swap.c
> rename to mm/folio_lru.c
> index e4b3dadaa6dc..7dab6a544d94 100644
> --- a/mm/swap.c
> +++ b/mm/folio_lru.c
> @@ -1,6 +1,6 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  /*
> - *  linux/mm/swap.c
> + *  linux/mm/folio_lru.c
>   *
>   *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
>   */
> 

This likely needs a MAINTAINER update?

-- 
Cheers,

David

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 3/3] mm: move reclaim-internal declarations out of swap.h
  2026-05-31  9:50 ` [PATCH v2 3/3] mm: move reclaim-internal declarations out of swap.h Jianyue Wu
@ 2026-06-01 14:57   ` David Hildenbrand (Arm)
  2026-06-01 23:46     ` Jianyue Wu
  0 siblings, 1 reply; 9+ messages in thread
From: David Hildenbrand (Arm) @ 2026-06-01 14:57 UTC (permalink / raw)
  To: Jianyue Wu, Andrew Morton, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Qi Zheng,
	Shakeel Butt, Axel Rasmussen, Yuanchu Xie, Wei Xu,
	Johannes Weiner, Michal Hocko, Lorenzo Stoakes, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Hugh Dickins, Baolin Wang
  Cc: linux-mm, linux-kernel

On 5/31/26 11:50, Jianyue Wu wrote:
> Keep include/linux/swap.h focused on swap-facing interfaces by moving
> MM-internal reclaim and workingset declarations into mm/internal.h.
> 
> Leave the small set of LRU helper declarations that are used outside mm/
> in swap.h so this cleanup does not need a new public header under
> include/linux/.
> 
> Signed-off-by: Jianyue Wu <wujianyue000@gmail.com>
> ---
>  include/linux/swap.h | 75 +++++-----------------------------------------------
>  mm/internal.h        | 66 +++++++++++++++++++++++++++++++++++++++++++++
>  mm/memfd.c           |  1 +
>  3 files changed, 73 insertions(+), 69 deletions(-)
> 
> diff --git a/include/linux/swap.h b/include/linux/swap.h
> index c36f72877e8b..1ef6ae7b2db7 100644
> --- a/include/linux/swap.h
> +++ b/include/linux/swap.h
> @@ -292,39 +292,17 @@ static inline swp_entry_t page_swap_entry(struct page *page)
>  	return entry;
>  }
>  
> -/* linux/mm/workingset.c */
> -bool workingset_test_recent(void *shadow, bool file, bool *workingset,
> -				bool flush);
> -void workingset_age_nonresident(struct lruvec *lruvec, unsigned long nr_pages);
> -void *workingset_eviction(struct folio *folio, struct mem_cgroup *target_memcg);
> -void workingset_refault(struct folio *folio, void *shadow);
> -void workingset_activation(struct folio *folio);
> -
>  /* linux/mm/page_alloc.c */
>  extern unsigned long totalreserve_pages;
>  
>  /* Definition of global_zone_page_state not available yet */
>  #define nr_free_pages() global_zone_page_state(NR_FREE_PAGES)
>  
> -
> -/* linux/mm/swap.c */
> -void lru_note_cost_unlock_irq(struct lruvec *lruvec, bool file,
> -		unsigned int nr_io, unsigned int nr_rotated);
> -void lru_note_cost_refault(struct folio *);
> -void folio_add_lru(struct folio *);
> -void folio_add_lru_vma(struct folio *, struct vm_area_struct *);
> -void mark_page_accessed(struct page *);
> -void folio_mark_accessed(struct folio *);
> -
> -static inline bool folio_may_be_lru_cached(struct folio *folio)
> -{
> -	/*
> -	 * Holding PMD-sized folios in per-CPU LRU cache unbalances accounting.
> -	 * Holding small numbers of low-order mTHP folios in per-CPU LRU cache
> -	 * will be sensible, but nobody has implemented and tested that yet.
> -	 */
> -	return !folio_test_large(folio);
> -}
> +/* Generic folio LRU helpers used outside mm/. */
> +void folio_add_lru(struct folio *folio);
> +void mark_page_accessed(struct page *page);
> +void folio_mark_accessed(struct folio *folio);
> +void lru_add_drain_all(void);
>  
>  extern atomic_t lru_disable_count;
>  
> @@ -333,43 +311,7 @@ static inline bool lru_cache_disabled(void)
>  	return atomic_read(&lru_disable_count);
>  }
>  
> -static inline void lru_cache_enable(void)
> -{
> -	atomic_dec(&lru_disable_count);
> -}
> -
> -extern void lru_cache_disable(void);
> -extern void lru_add_drain(void);
> -extern void lru_add_drain_cpu(int cpu);
> -extern void lru_add_drain_cpu_zone(struct zone *zone);
> -extern void lru_add_drain_all(void);
> -void folio_deactivate(struct folio *folio);
> -void folio_mark_lazyfree(struct folio *folio);
> -extern void swap_readahead_setup(void);
> -
>  /* linux/mm/vmscan.c */
> -extern unsigned long zone_reclaimable_pages(struct zone *zone);
> -extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
> -					gfp_t gfp_mask, nodemask_t *mask);
> -unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru, int zone_idx);
> -
> -#define MEMCG_RECLAIM_MAY_SWAP (1 << 1)
> -#define MEMCG_RECLAIM_PROACTIVE (1 << 2)
> -#define MIN_SWAPPINESS 0
> -#define MAX_SWAPPINESS 200
> -
> -/* Just reclaim from anon folios in proactive memory reclaim */
> -#define SWAPPINESS_ANON_ONLY (MAX_SWAPPINESS + 1)
> -
> -extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg,
> -						  unsigned long nr_pages,
> -						  gfp_t gfp_mask,
> -						  unsigned int reclaim_options,
> -						  int *swappiness);
> -extern unsigned long mem_cgroup_shrink_node(struct mem_cgroup *mem,
> -						gfp_t gfp_mask, bool noswap,
> -						pg_data_t *pgdat,
> -						unsigned long *nr_scanned);
>  extern unsigned long shrink_all_memory(unsigned long nr_pages);
>  extern int vm_swappiness;
>  long remove_mapping(struct address_space *mapping, struct folio *folio);
> @@ -390,11 +332,6 @@ static inline void reclaim_unregister_node(struct node *node)
>  }
>  #endif /* CONFIG_SYSFS && CONFIG_NUMA */
>  
> -#ifdef CONFIG_NUMA
> -extern int sysctl_min_unmapped_ratio;
> -extern int sysctl_min_slab_ratio;
> -#endif
> -
>  void check_move_unevictable_folios(struct folio_batch *fbatch);
>  
>  extern void __meminit kswapd_run(int nid);
> @@ -554,7 +491,7 @@ static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
>  
>  void lru_reparent_memcg(struct mem_cgroup *memcg, struct mem_cgroup *parent, int nid);
>  #else
> -static inline int mem_cgroup_swappiness(struct mem_cgroup *mem)
> +static inline int mem_cgroup_swappiness(struct mem_cgroup *memcg)
>  {
>  	return READ_ONCE(vm_swappiness);
>  }
> diff --git a/mm/internal.h b/mm/internal.h
> index 5602393054f3..5475ba38a621 100644
> --- a/mm/internal.h
> +++ b/mm/internal.h
> @@ -24,6 +24,72 @@
>  
>  struct folio_batch;
>  
> +bool workingset_test_recent(void *shadow, bool file, bool *workingset,
> +			    bool flush);
> +void workingset_age_nonresident(struct lruvec *lruvec, unsigned long nr_pages);
> +void *workingset_eviction(struct folio *folio,
> +			  struct mem_cgroup *target_memcg);
> +void workingset_refault(struct folio *folio, void *shadow);
> +void workingset_activation(struct folio *folio);
> +
> +void lru_note_cost_unlock_irq(struct lruvec *lruvec, bool file,
> +		unsigned int nr_io, unsigned int nr_rotated)
> +		__releases(lruvec->lru_lock);
> +void lru_note_cost_refault(struct folio *folio);
> +void folio_add_lru_vma(struct folio *folio, struct vm_area_struct *vma);
> +
> +static inline bool folio_may_be_lru_cached(struct folio *folio)
> +{
> +	/*
> +	 * Holding PMD-sized folios in per-CPU LRU cache unbalances accounting.
> +	 * Holding small numbers of low-order mTHP folios in per-CPU LRU cache
> +	 * will be sensible, but nobody has implemented and tested that yet.
> +	 */
> +	return !folio_test_large(folio);
> +}
> +
> +static inline void lru_cache_enable(void)
> +{
> +	atomic_dec(&lru_disable_count);
> +}
> +
> +void lru_cache_disable(void);
> +void lru_add_drain(void);
> +void lru_add_drain_cpu(int cpu);
> +void lru_add_drain_cpu_zone(struct zone *zone);
> +void folio_deactivate(struct folio *folio);
> +void folio_mark_lazyfree(struct folio *folio);
> +void swap_readahead_setup(void);
> +
> +unsigned long zone_reclaimable_pages(struct zone *zone);
> +unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
> +				gfp_t gfp_mask, nodemask_t *mask);

Skimming over this, what a confusing function name (having free_pages() etc in
mind). In particular, that it's interesting in a single high-order page judging
from the interface?

I wonder if making it clearer that this is a direct reclaim interface would
improve the situation.

"direct_reclaim_...()"

Similar for try_to_free_mem_cgroup_pages -- which actually consumes nr_pages.

Just a random thought ...

Moving a lot of stuff out of swap.h sounds like a good idea. I do wonder if
mm/internal.h should be split up as well (to minimize future conflicts).

-- 
Cheers,

David

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 3/3] mm: move reclaim-internal declarations out of swap.h
  2026-06-01 14:57   ` David Hildenbrand (Arm)
@ 2026-06-01 23:46     ` Jianyue Wu
  0 siblings, 0 replies; 9+ messages in thread
From: Jianyue Wu @ 2026-06-01 23:46 UTC (permalink / raw)
  To: David Hildenbrand (Arm)
  Cc: Andrew Morton, Chris Li, Kairui Song, Kemeng Shi, Nhat Pham,
	Baoquan He, Barry Song, Youngjun Park, Qi Zheng, Shakeel Butt,
	Axel Rasmussen, Yuanchu Xie, Wei Xu, Johannes Weiner,
	Michal Hocko, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
	Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Hugh Dickins,
	Baolin Wang, linux-mm, linux-kernel

On Mon, Jun 1, 2026 at 10:57 PM David Hildenbrand (Arm)
<david@kernel.org> wrote:
>
> Skimming over this, what a confusing function name (having free_pages() etc in
> mind). In particular, that it's interesting in a single high-order page judging
> from the interface?
>
> I wonder if making it clearer that this is a direct reclaim interface would
> improve the situation.
>
> "direct_reclaim_...()"
>
> Similar for try_to_free_mem_cgroup_pages -- which actually consumes nr_pages.
>
> Just a random thought ...
>
> Moving a lot of stuff out of swap.h sounds like a good idea. I do wonder if
> mm/internal.h should be split up as well (to minimize future conflicts).
>
> --
> Cheers,
>
> David

Hi David,

Thanks for the review.

Good catch on MAINTAINERS — I missed that in v2. I've updated it locally:
- MGLRU: F: mm/swap.c -> F: mm/folio_lru.c
- SWAP: drop the stale F: mm/swap.c entry (swap code is already
  covered by swap_state.c, page_io.c, swapfile.c, etc.)
- Docs: update the remaining mm/swap.c references in
  Documentation/admin-guide/sysctl/vm.rst and
  Documentation/core-api/mm-api.rst
I'll include those in v3.

On try_to_free_pages() / try_to_free_mem_cgroup_pages() naming:
agree the names are misleading next to free_pages() -- they trigger
reclaim, not free owned pages. The order argument reflects the
allocation request that triggered direct reclaim, not "free one
high-order page".

I had a quick look: try_to_free_pages() is only called from
__perform_reclaim() in page_alloc.c (plus a comment in fuse/file.c),
so renaming that entry point would be a small follow-up -- something
like direct_reclaim_pages() for the page-alloc path. I'll keep the
existing names in v3 to avoid expanding scope; try_to_free_mem_cgroup_pages()
has more call sites and I'd treat them separately.

Thanks,
Jianyue

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-06-01 23:46 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-05-31  9:50 [PATCH v2 0/3] mm: clean up folio LRU and swap declarations Jianyue Wu
2026-05-31  9:50 ` [PATCH v2 1/3] mm/swap: colocate page-cluster sysctl with swap readahead Jianyue Wu
2026-05-31 22:06   ` Barry Song
2026-06-01  0:59     ` Jianyue Wu
2026-05-31  9:50 ` [PATCH v2 2/3] mm: move folio LRU code out of swap Jianyue Wu
2026-06-01 14:48   ` David Hildenbrand (Arm)
2026-05-31  9:50 ` [PATCH v2 3/3] mm: move reclaim-internal declarations out of swap.h Jianyue Wu
2026-06-01 14:57   ` David Hildenbrand (Arm)
2026-06-01 23:46     ` Jianyue Wu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome