linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] mm/swap: use swap_ops to register swap device's methods
@ 2026-03-28  7:58 Barry Song
  2026-03-28  7:58 ` [PATCH v2 1/3] mm/swap: rename mm/page_io.c to mm/swap_io.c Barry Song
                   ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Barry Song @ 2026-03-28  7:58 UTC (permalink / raw)
  To: akpm, linux-mm
  Cc: bhe, baohua, chrisl, kasong, nphamcs, shikemeng, youngjun.park,
	linux-kernel

From: Barry Song <baohua@kernel.org>

-v2:
 * lots of cleanup for patch 2/3: renaming, moving data
   structures, and using const properly
 * collected tags from Kairui, Nhat and Barry

-v1:
 https://lore.kernel.org/linux-mm/20260302104016.163542-1-bhe@redhat.com/

This can simplify the code logic and benefit any new type of swap device
added later.

And also do renaming in this patchset:
-------
   file renaming:
   ---
   mm/page_io.c to mm/swap_io.c

   function renaming:
   ---
   swap_writepage_* to swap_write_folio_* in file mm/swap_io.c

Baoquan He (3):
  mm/swap: rename mm/page_io.c to mm/swap_io.c
  mm/swap: use swap_ops to register swap device's methods
  mm/swap_io.c: rename swap_writepage_* to swap_write_folio_*

 MAINTAINERS                 |   2 +-
 include/linux/swap.h        |   2 +
 mm/Makefile                 |   2 +-
 mm/swap.h                   |  12 ++++-
 mm/{page_io.c => swap_io.c} | 101 ++++++++++++++++++++----------------
 mm/swapfile.c               |   1 +
 mm/zswap.c                  |   3 +-
 7 files changed, 73 insertions(+), 50 deletions(-)
 rename mm/{page_io.c => swap_io.c} (89%)

-- 
2.39.3 (Apple Git-146)



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

* [PATCH v2 1/3] mm/swap: rename mm/page_io.c to mm/swap_io.c
  2026-03-28  7:58 [PATCH v2 0/3] mm/swap: use swap_ops to register swap device's methods Barry Song
@ 2026-03-28  7:58 ` Barry Song
  2026-03-29 14:31   ` Chris Li
  2026-03-28  7:58 ` [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods Barry Song
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 17+ messages in thread
From: Barry Song @ 2026-03-28  7:58 UTC (permalink / raw)
  To: akpm, linux-mm
  Cc: bhe, baohua, chrisl, kasong, nphamcs, shikemeng, youngjun.park,
	linux-kernel

From: Baoquan He <bhe@redhat.com>

Codes in mm/page_io.c are only related to swap io, it has
nothing to do with other page io.

Rename it to avoid confusion.

Reviewed-by: Nhat Pham <nphamcs@gmail.com>
Reviewed-by: Barry Song <baohua@kernel.org>
Acked-by: Kairui Song <kasong@tencent.com>
Signed-off-by: Baoquan He <bhe@redhat.com>
Signed-off-by: Barry Song <baohua@kernel.org>
---
 MAINTAINERS                 | 2 +-
 mm/Makefile                 | 2 +-
 mm/swap.h                   | 2 +-
 mm/{page_io.c => swap_io.c} | 2 --
 4 files changed, 3 insertions(+), 5 deletions(-)
 rename mm/{page_io.c => swap_io.c} (99%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 16874c32e288..bb7c1031886d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16915,7 +16915,7 @@ F:	Documentation/mm/swap-table.rst
 F:	include/linux/swap.h
 F:	include/linux/swapfile.h
 F:	include/linux/swapops.h
-F:	mm/page_io.c
+F:	mm/swap_io.c
 F:	mm/swap.c
 F:	mm/swap.h
 F:	mm/swap_table.h
diff --git a/mm/Makefile b/mm/Makefile
index 8ad2ab08244e..a65ac900096a 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -75,7 +75,7 @@ ifdef CONFIG_MMU
 	obj-$(CONFIG_ADVISE_SYSCALLS)	+= madvise.o
 endif
 
-obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o
+obj-$(CONFIG_SWAP)	+= swap_io.o swap_state.o swapfile.o
 obj-$(CONFIG_ZSWAP)	+= zswap.o
 obj-$(CONFIG_HAS_DMA)	+= dmapool.o
 obj-$(CONFIG_HUGETLBFS)	+= hugetlb.o hugetlb_sysfs.o hugetlb_sysctl.o
diff --git a/mm/swap.h b/mm/swap.h
index a77016f2423b..161185057993 100644
--- a/mm/swap.h
+++ b/mm/swap.h
@@ -214,7 +214,7 @@ extern void __swap_cluster_free_entries(struct swap_info_struct *si,
 					struct swap_cluster_info *ci,
 					unsigned int ci_off, unsigned int nr_pages);
 
-/* linux/mm/page_io.c */
+/* linux/mm/swap_io.c */
 int sio_pool_init(void);
 struct swap_iocb;
 void swap_read_folio(struct folio *folio, struct swap_iocb **plug);
diff --git a/mm/page_io.c b/mm/swap_io.c
similarity index 99%
rename from mm/page_io.c
rename to mm/swap_io.c
index 70cea9e24d2f..91b33d955e63 100644
--- a/mm/page_io.c
+++ b/mm/swap_io.c
@@ -1,7 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- *  linux/mm/page_io.c
- *
  *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  *
  *  Swap reorganised 29.12.95, 
-- 
2.39.3 (Apple Git-146)



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

* [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods
  2026-03-28  7:58 [PATCH v2 0/3] mm/swap: use swap_ops to register swap device's methods Barry Song
  2026-03-28  7:58 ` [PATCH v2 1/3] mm/swap: rename mm/page_io.c to mm/swap_io.c Barry Song
@ 2026-03-28  7:58 ` Barry Song
  2026-03-29 10:49   ` kernel test robot
                     ` (2 more replies)
  2026-03-28  7:58 ` [PATCH v2 3/3] mm/swap_io.c: rename swap_writepage_* to swap_write_folio_* Barry Song
  2026-03-30  0:54 ` [PATCH v2 0/3] mm/swap: use swap_ops to register swap device's methods Baoquan He
  3 siblings, 3 replies; 17+ messages in thread
From: Barry Song @ 2026-03-28  7:58 UTC (permalink / raw)
  To: akpm, linux-mm
  Cc: bhe, baohua, chrisl, kasong, nphamcs, shikemeng, youngjun.park,
	linux-kernel

From: Baoquan He <bhe@redhat.com>

This simplifies codes and makes logic clearer. And also makes later any
new swap device type being added easier to handle.

Currently there are three types of swap devices: bdev_fs, bdev_sync
and bdev_async, and only operations read_folio and write_folio are
included. In the future, there could be more swap device types added
and more appropriate opeations adapted into swap_ops.

Suggested-by: Chris Li <chrisl@kernel.org>
Signed-off-by: Baoquan He <bhe@redhat.com>
Co-developed-by: Barry Song <baohua@kernel.org>
Signed-off-by: Barry Song <baohua@kernel.org>
---
 include/linux/swap.h |  2 +
 mm/swap.h            | 10 ++++-
 mm/swap_io.c         | 99 +++++++++++++++++++++++++-------------------
 mm/swapfile.c        |  1 +
 mm/zswap.c           |  3 +-
 5 files changed, 70 insertions(+), 45 deletions(-)

diff --git a/include/linux/swap.h b/include/linux/swap.h
index 1930f81e6be4..b52f30dad72b 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -243,6 +243,7 @@ struct swap_sequential_cluster {
 	unsigned int next[SWAP_NR_ORDERS]; /* Likely next allocation offset */
 };
 
+struct swap_ops;
 /*
  * The in-memory structure used to track swap areas.
  */
@@ -283,6 +284,7 @@ struct swap_info_struct {
 	struct work_struct reclaim_work; /* reclaim worker */
 	struct list_head discard_clusters; /* discard clusters list */
 	struct plist_node avail_list;   /* entry in swap_avail_head */
+	const struct swap_ops *ops;
 };
 
 static inline swp_entry_t page_swap_entry(struct page *page)
diff --git a/mm/swap.h b/mm/swap.h
index 161185057993..219dbcb3ffb1 100644
--- a/mm/swap.h
+++ b/mm/swap.h
@@ -217,6 +217,15 @@ extern void __swap_cluster_free_entries(struct swap_info_struct *si,
 /* linux/mm/swap_io.c */
 int sio_pool_init(void);
 struct swap_iocb;
+struct swap_ops {
+	void (*read_folio)(struct swap_info_struct *sis,
+			struct folio *folio,
+			struct swap_iocb **plug);
+	void (*write_folio)(struct swap_info_struct *sis,
+			struct folio *folio,
+			struct swap_iocb **plug);
+};
+void setup_swap_ops(struct swap_info_struct *sis);
 void swap_read_folio(struct folio *folio, struct swap_iocb **plug);
 void __swap_read_unplug(struct swap_iocb *plug);
 static inline void swap_read_unplug(struct swap_iocb *plug)
@@ -226,7 +235,6 @@ static inline void swap_read_unplug(struct swap_iocb *plug)
 }
 void swap_write_unplug(struct swap_iocb *sio);
 int swap_writeout(struct folio *folio, struct swap_iocb **swap_plug);
-void __swap_writepage(struct folio *folio, struct swap_iocb **swap_plug);
 
 /* linux/mm/swap_state.c */
 extern struct address_space swap_space __read_mostly;
diff --git a/mm/swap_io.c b/mm/swap_io.c
index 91b33d955e63..ad0895af6ed8 100644
--- a/mm/swap_io.c
+++ b/mm/swap_io.c
@@ -238,6 +238,7 @@ static void swap_zeromap_folio_clear(struct folio *folio)
 int swap_writeout(struct folio *folio, struct swap_iocb **swap_plug)
 {
 	int ret = 0;
+	struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);
 
 	if (folio_free_swap(folio))
 		goto out_unlock;
@@ -283,7 +284,8 @@ int swap_writeout(struct folio *folio, struct swap_iocb **swap_plug)
 	}
 	rcu_read_unlock();
 
-	__swap_writepage(folio, swap_plug);
+	VM_WARN_ON_ONCE(!sis->ops || !sis->ops->write_folio);
+	sis->ops->write_folio(sis, folio, swap_plug);
 	return 0;
 out_unlock:
 	folio_unlock(folio);
@@ -373,10 +375,11 @@ static void sio_write_complete(struct kiocb *iocb, long ret)
 	mempool_free(sio, sio_pool);
 }
 
-static void swap_writepage_fs(struct folio *folio, struct swap_iocb **swap_plug)
+static void swap_writepage_fs(struct swap_info_struct *sis,
+			      struct folio *folio,
+			      struct swap_iocb **swap_plug)
 {
 	struct swap_iocb *sio = swap_plug ? *swap_plug : NULL;
-	struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);
 	struct file *swap_file = sis->swap_file;
 	loff_t pos = swap_dev_pos(folio->swap);
 
@@ -409,8 +412,9 @@ static void swap_writepage_fs(struct folio *folio, struct swap_iocb **swap_plug)
 		*swap_plug = sio;
 }
 
-static void swap_writepage_bdev_sync(struct folio *folio,
-		struct swap_info_struct *sis)
+static void swap_writepage_bdev_sync(struct swap_info_struct *sis,
+				     struct folio *folio,
+				     struct swap_iocb **plug)
 {
 	struct bio_vec bv;
 	struct bio bio;
@@ -429,8 +433,9 @@ static void swap_writepage_bdev_sync(struct folio *folio,
 	__end_swap_bio_write(&bio);
 }
 
-static void swap_writepage_bdev_async(struct folio *folio,
-		struct swap_info_struct *sis)
+static void swap_writepage_bdev_async(struct swap_info_struct *sis,
+				      struct folio *folio,
+				      struct swap_iocb **plug)
 {
 	struct bio *bio;
 
@@ -446,29 +451,6 @@ static void swap_writepage_bdev_async(struct folio *folio,
 	submit_bio(bio);
 }
 
-void __swap_writepage(struct folio *folio, struct swap_iocb **swap_plug)
-{
-	struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);
-
-	VM_BUG_ON_FOLIO(!folio_test_swapcache(folio), folio);
-	/*
-	 * ->flags can be updated non-atomically,
-	 * but that will never affect SWP_FS_OPS, so the data_race
-	 * is safe.
-	 */
-	if (data_race(sis->flags & SWP_FS_OPS))
-		swap_writepage_fs(folio, swap_plug);
-	/*
-	 * ->flags can be updated non-atomically,
-	 * but that will never affect SWP_SYNCHRONOUS_IO, so the data_race
-	 * is safe.
-	 */
-	else if (data_race(sis->flags & SWP_SYNCHRONOUS_IO))
-		swap_writepage_bdev_sync(folio, sis);
-	else
-		swap_writepage_bdev_async(folio, sis);
-}
-
 void swap_write_unplug(struct swap_iocb *sio)
 {
 	struct iov_iter from;
@@ -537,9 +519,10 @@ static bool swap_read_folio_zeromap(struct folio *folio)
 	return true;
 }
 
-static void swap_read_folio_fs(struct folio *folio, struct swap_iocb **plug)
+static void swap_read_folio_fs(struct swap_info_struct *sis,
+			       struct folio *folio,
+			       struct swap_iocb **plug)
 {
-	struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);
 	struct swap_iocb *sio = NULL;
 	loff_t pos = swap_dev_pos(folio->swap);
 
@@ -571,8 +554,9 @@ static void swap_read_folio_fs(struct folio *folio, struct swap_iocb **plug)
 		*plug = sio;
 }
 
-static void swap_read_folio_bdev_sync(struct folio *folio,
-		struct swap_info_struct *sis)
+static void swap_read_folio_bdev_sync(struct swap_info_struct *sis,
+				      struct folio *folio,
+				      struct swap_iocb **plug)
 {
 	struct bio_vec bv;
 	struct bio bio;
@@ -593,8 +577,9 @@ static void swap_read_folio_bdev_sync(struct folio *folio,
 	put_task_struct(current);
 }
 
-static void swap_read_folio_bdev_async(struct folio *folio,
-		struct swap_info_struct *sis)
+static void swap_read_folio_bdev_async(struct swap_info_struct *sis,
+				       struct folio *folio,
+				       struct swap_iocb **plug)
 {
 	struct bio *bio;
 
@@ -608,6 +593,39 @@ static void swap_read_folio_bdev_async(struct folio *folio,
 	submit_bio(bio);
 }
 
+static const struct swap_ops bdev_fs_swap_ops = {
+	.read_folio = swap_read_folio_fs,
+	.write_folio = swap_writepage_fs,
+};
+
+static const struct swap_ops bdev_sync_swap_ops = {
+	.read_folio = swap_read_folio_bdev_sync,
+	.write_folio = swap_writepage_bdev_sync,
+};
+
+static const struct swap_ops bdev_async_swap_ops = {
+	.read_folio = swap_read_folio_bdev_async,
+	.write_folio = swap_writepage_bdev_async,
+};
+
+void setup_swap_ops(struct swap_info_struct *sis)
+{
+	/*
+	 * ->flags can be updated non-atomically, but that will
+	 * never affect SWP_FS_OPS, so the data_race is safe.
+	 */
+	if (data_race(sis->flags & SWP_FS_OPS))
+		sis->ops = &bdev_fs_swap_ops;
+	/*
+	 * ->flags can be updated non-atomically, but that will
+	 * never affect SWP_SYNCHRONOUS_IO, so the data_race is safe.
+	 */
+	else if (data_race(sis->flags & SWP_SYNCHRONOUS_IO))
+		sis->ops = &bdev_sync_swap_ops;
+	else
+		sis->ops = &bdev_async_swap_ops;
+}
+
 void swap_read_folio(struct folio *folio, struct swap_iocb **plug)
 {
 	struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);
@@ -642,13 +660,8 @@ void swap_read_folio(struct folio *folio, struct swap_iocb **plug)
 	/* We have to read from slower devices. Increase zswap protection. */
 	zswap_folio_swapin(folio);
 
-	if (data_race(sis->flags & SWP_FS_OPS)) {
-		swap_read_folio_fs(folio, plug);
-	} else if (synchronous) {
-		swap_read_folio_bdev_sync(folio, sis);
-	} else {
-		swap_read_folio_bdev_async(folio, sis);
-	}
+	VM_WARN_ON_ONCE(!sis->ops || !sis->ops->read_folio);
+	sis->ops->read_folio(sis, folio, plug);
 
 finish:
 	if (workingset) {
diff --git a/mm/swapfile.c b/mm/swapfile.c
index ff315b752afd..c9eb95141c8f 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -3732,6 +3732,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
 	si->list.prio = -si->prio;
 	si->avail_list.prio = -si->prio;
 	si->swap_file = swap_file;
+	setup_swap_ops(si);
 
 	/* Sets SWP_WRITEOK, resurrect the percpu ref, expose the swap device */
 	enable_swap_info(si);
diff --git a/mm/zswap.c b/mm/zswap.c
index 4b5149173b0e..9bacb1733e1c 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -1054,7 +1054,8 @@ static int zswap_writeback_entry(struct zswap_entry *entry,
 	folio_set_reclaim(folio);
 
 	/* start writeback */
-	__swap_writepage(folio, NULL);
+	VM_WARN_ON_ONCE(!sis->ops || !sis->ops->write_folio);
+	si->ops->write_folio(si, folio, NULL);
 
 out:
 	if (ret && ret != -EEXIST) {
-- 
2.39.3 (Apple Git-146)



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

* [PATCH v2 3/3] mm/swap_io.c: rename swap_writepage_* to swap_write_folio_*
  2026-03-28  7:58 [PATCH v2 0/3] mm/swap: use swap_ops to register swap device's methods Barry Song
  2026-03-28  7:58 ` [PATCH v2 1/3] mm/swap: rename mm/page_io.c to mm/swap_io.c Barry Song
  2026-03-28  7:58 ` [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods Barry Song
@ 2026-03-28  7:58 ` Barry Song
  2026-03-29 14:31   ` Chris Li
  2026-03-30  0:54 ` [PATCH v2 0/3] mm/swap: use swap_ops to register swap device's methods Baoquan He
  3 siblings, 1 reply; 17+ messages in thread
From: Barry Song @ 2026-03-28  7:58 UTC (permalink / raw)
  To: akpm, linux-mm
  Cc: bhe, baohua, chrisl, kasong, nphamcs, shikemeng, youngjun.park,
	linux-kernel

From: Baoquan He <bhe@redhat.com>

All these swap_writepage_* functions are hanlding passed in folio, but
not page. And this renaming make them consistent with the their
counterpart swap_read_folio_* functions.

Reviewed-by: Barry Song <baohua@kernel.org>
Reviewed-by: Nhat Pham <nphamcs@gmail.com>
Signed-off-by: Baoquan He <bhe@redhat.com>
Signed-off-by: Barry Song <baohua@kernel.org>
---
 mm/swap_io.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/mm/swap_io.c b/mm/swap_io.c
index ad0895af6ed8..063cd005ca0d 100644
--- a/mm/swap_io.c
+++ b/mm/swap_io.c
@@ -375,7 +375,7 @@ static void sio_write_complete(struct kiocb *iocb, long ret)
 	mempool_free(sio, sio_pool);
 }
 
-static void swap_writepage_fs(struct swap_info_struct *sis,
+static void swap_write_folio_fs(struct swap_info_struct *sis,
 			      struct folio *folio,
 			      struct swap_iocb **swap_plug)
 {
@@ -412,7 +412,7 @@ static void swap_writepage_fs(struct swap_info_struct *sis,
 		*swap_plug = sio;
 }
 
-static void swap_writepage_bdev_sync(struct swap_info_struct *sis,
+static void swap_write_folio_bdev_sync(struct swap_info_struct *sis,
 				     struct folio *folio,
 				     struct swap_iocb **plug)
 {
@@ -433,7 +433,7 @@ static void swap_writepage_bdev_sync(struct swap_info_struct *sis,
 	__end_swap_bio_write(&bio);
 }
 
-static void swap_writepage_bdev_async(struct swap_info_struct *sis,
+static void swap_write_folio_bdev_async(struct swap_info_struct *sis,
 				      struct folio *folio,
 				      struct swap_iocb **plug)
 {
@@ -595,17 +595,17 @@ static void swap_read_folio_bdev_async(struct swap_info_struct *sis,
 
 static const struct swap_ops bdev_fs_swap_ops = {
 	.read_folio = swap_read_folio_fs,
-	.write_folio = swap_writepage_fs,
+	.write_folio = swap_write_folio_fs,
 };
 
 static const struct swap_ops bdev_sync_swap_ops = {
 	.read_folio = swap_read_folio_bdev_sync,
-	.write_folio = swap_writepage_bdev_sync,
+	.write_folio = swap_write_folio_bdev_sync,
 };
 
 static const struct swap_ops bdev_async_swap_ops = {
 	.read_folio = swap_read_folio_bdev_async,
-	.write_folio = swap_writepage_bdev_async,
+	.write_folio = swap_write_folio_bdev_async,
 };
 
 void setup_swap_ops(struct swap_info_struct *sis)
-- 
2.39.3 (Apple Git-146)



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

* Re: [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods
  2026-03-28  7:58 ` [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods Barry Song
@ 2026-03-29 10:49   ` kernel test robot
  2026-03-29 11:44     ` Barry Song
  2026-03-29 11:10   ` kernel test robot
  2026-03-31  3:30   ` Chris Li
  2 siblings, 1 reply; 17+ messages in thread
From: kernel test robot @ 2026-03-29 10:49 UTC (permalink / raw)
  To: Barry Song, akpm, linux-mm
  Cc: llvm, oe-kbuild-all, bhe, baohua, chrisl, kasong, nphamcs,
	shikemeng, youngjun.park, linux-kernel

Hi Barry,

kernel test robot noticed the following build errors:

[auto build test ERROR on akpm-mm/mm-everything]

url:    https://github.com/intel-lab-lkp/linux/commits/Barry-Song/mm-swap-rename-mm-page_io-c-to-mm-swap_io-c/20260328-170852
base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link:    https://lore.kernel.org/r/20260328075812.11060-3-21cnbao%40gmail.com
patch subject: [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods
config: arm-randconfig-001-20260329 (https://download.01.org/0day-ci/archive/20260329/202603291844.TWh2Ellp-lkp@intel.com/config)
compiler: clang version 23.0.0git (https://github.com/llvm/llvm-project 054e11d1a17e5ba88bb1a8ef32fad3346e80b186)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260329/202603291844.TWh2Ellp-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603291844.TWh2Ellp-lkp@intel.com/

All errors (new ones prefixed by >>):

>> mm/zswap.c:1057:19: error: use of undeclared identifier 'sis'; did you mean 'si'?
    1057 |         VM_WARN_ON_ONCE(!sis->ops || !sis->ops->write_folio);
         |                          ^~~
         |                          si
   include/linux/mmdebug.h:133:52: note: expanded from macro 'VM_WARN_ON_ONCE'
     133 | #define VM_WARN_ON_ONCE(cond) BUILD_BUG_ON_INVALID(cond)
         |                                                    ^~~~
   include/linux/build_bug.h:30:63: note: expanded from macro 'BUILD_BUG_ON_INVALID'
      30 | #define BUILD_BUG_ON_INVALID(e) ((void)(sizeof((__force long)(e))))
         |                                                               ^
   mm/zswap.c:995:27: note: 'si' declared here
     995 |         struct swap_info_struct *si;
         |                                  ^
   mm/zswap.c:1057:32: error: use of undeclared identifier 'sis'; did you mean 'si'?
    1057 |         VM_WARN_ON_ONCE(!sis->ops || !sis->ops->write_folio);
         |                                       ^~~
         |                                       si
   include/linux/mmdebug.h:133:52: note: expanded from macro 'VM_WARN_ON_ONCE'
     133 | #define VM_WARN_ON_ONCE(cond) BUILD_BUG_ON_INVALID(cond)
         |                                                    ^~~~
   include/linux/build_bug.h:30:63: note: expanded from macro 'BUILD_BUG_ON_INVALID'
      30 | #define BUILD_BUG_ON_INVALID(e) ((void)(sizeof((__force long)(e))))
         |                                                               ^
   mm/zswap.c:995:27: note: 'si' declared here
     995 |         struct swap_info_struct *si;
         |                                  ^
   2 errors generated.


vim +1057 mm/zswap.c

   971	
   972	/*********************************
   973	* writeback code
   974	**********************************/
   975	/*
   976	 * Attempts to free an entry by adding a folio to the swap cache,
   977	 * decompressing the entry data into the folio, and issuing a
   978	 * bio write to write the folio back to the swap device.
   979	 *
   980	 * This can be thought of as a "resumed writeback" of the folio
   981	 * to the swap device.  We are basically resuming the same swap
   982	 * writeback path that was intercepted with the zswap_store()
   983	 * in the first place.  After the folio has been decompressed into
   984	 * the swap cache, the compressed version stored by zswap can be
   985	 * freed.
   986	 */
   987	static int zswap_writeback_entry(struct zswap_entry *entry,
   988					 swp_entry_t swpentry)
   989	{
   990		struct xarray *tree;
   991		pgoff_t offset = swp_offset(swpentry);
   992		struct folio *folio;
   993		struct mempolicy *mpol;
   994		bool folio_was_allocated;
   995		struct swap_info_struct *si;
   996		int ret = 0;
   997	
   998		/* try to allocate swap cache folio */
   999		si = get_swap_device(swpentry);
  1000		if (!si)
  1001			return -EEXIST;
  1002	
  1003		mpol = get_task_policy(current);
  1004		folio = swap_cache_alloc_folio(swpentry, GFP_KERNEL, mpol,
  1005					       NO_INTERLEAVE_INDEX, &folio_was_allocated);
  1006		put_swap_device(si);
  1007		if (!folio)
  1008			return -ENOMEM;
  1009	
  1010		/*
  1011		 * Found an existing folio, we raced with swapin or concurrent
  1012		 * shrinker. We generally writeback cold folios from zswap, and
  1013		 * swapin means the folio just became hot, so skip this folio.
  1014		 * For unlikely concurrent shrinker case, it will be unlinked
  1015		 * and freed when invalidated by the concurrent shrinker anyway.
  1016		 */
  1017		if (!folio_was_allocated) {
  1018			ret = -EEXIST;
  1019			goto out;
  1020		}
  1021	
  1022		/*
  1023		 * folio is locked, and the swapcache is now secured against
  1024		 * concurrent swapping to and from the slot, and concurrent
  1025		 * swapoff so we can safely dereference the zswap tree here.
  1026		 * Verify that the swap entry hasn't been invalidated and recycled
  1027		 * behind our backs, to avoid overwriting a new swap folio with
  1028		 * old compressed data. Only when this is successful can the entry
  1029		 * be dereferenced.
  1030		 */
  1031		tree = swap_zswap_tree(swpentry);
  1032		if (entry != xa_load(tree, offset)) {
  1033			ret = -ENOMEM;
  1034			goto out;
  1035		}
  1036	
  1037		if (!zswap_decompress(entry, folio)) {
  1038			ret = -EIO;
  1039			goto out;
  1040		}
  1041	
  1042		xa_erase(tree, offset);
  1043	
  1044		count_vm_event(ZSWPWB);
  1045		if (entry->objcg)
  1046			count_objcg_events(entry->objcg, ZSWPWB, 1);
  1047	
  1048		zswap_entry_free(entry);
  1049	
  1050		/* folio is up to date */
  1051		folio_mark_uptodate(folio);
  1052	
  1053		/* move it to the tail of the inactive list after end_writeback */
  1054		folio_set_reclaim(folio);
  1055	
  1056		/* start writeback */
> 1057		VM_WARN_ON_ONCE(!sis->ops || !sis->ops->write_folio);
  1058		si->ops->write_folio(si, folio, NULL);
  1059	
  1060	out:
  1061		if (ret && ret != -EEXIST) {
  1062			swap_cache_del_folio(folio);
  1063			folio_unlock(folio);
  1064		}
  1065		folio_put(folio);
  1066		return ret;
  1067	}
  1068	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


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

* Re: [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods
  2026-03-28  7:58 ` [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods Barry Song
  2026-03-29 10:49   ` kernel test robot
@ 2026-03-29 11:10   ` kernel test robot
  2026-03-31  3:30   ` Chris Li
  2 siblings, 0 replies; 17+ messages in thread
From: kernel test robot @ 2026-03-29 11:10 UTC (permalink / raw)
  To: Barry Song, akpm, linux-mm
  Cc: oe-kbuild-all, bhe, baohua, chrisl, kasong, nphamcs, shikemeng,
	youngjun.park, linux-kernel

Hi Barry,

kernel test robot noticed the following build errors:

[auto build test ERROR on akpm-mm/mm-everything]

url:    https://github.com/intel-lab-lkp/linux/commits/Barry-Song/mm-swap-rename-mm-page_io-c-to-mm-swap_io-c/20260328-170852
base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link:    https://lore.kernel.org/r/20260328075812.11060-3-21cnbao%40gmail.com
patch subject: [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods
config: um-randconfig-r072-20260329 (https://download.01.org/0day-ci/archive/20260329/202603291919.Y8MwFsok-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
smatch: v0.5.0-9004-gb810ac53
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260329/202603291919.Y8MwFsok-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603291919.Y8MwFsok-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from include/asm-generic/bug.h:7,
                    from ./arch/um/include/generated/asm/bug.h:1,
                    from arch/x86/include/asm/alternative.h:9,
                    from arch/x86/um/asm/barrier.h:6,
                    from include/linux/list.h:11,
                    from include/linux/module.h:12,
                    from mm/zswap.c:16:
   mm/zswap.c: In function 'zswap_writeback_entry':
>> mm/zswap.c:1057:26: error: 'sis' undeclared (first use in this function); did you mean 'si'?
    1057 |         VM_WARN_ON_ONCE(!sis->ops || !sis->ops->write_folio);
         |                          ^~~
   include/linux/once_lite.h:28:41: note: in definition of macro 'DO_ONCE_LITE_IF'
      28 |                 bool __ret_do_once = !!(condition);                     \
         |                                         ^~~~~~~~~
   include/linux/mmdebug.h:123:37: note: in expansion of macro 'WARN_ON_ONCE'
     123 | #define VM_WARN_ON_ONCE(cond) (void)WARN_ON_ONCE(cond)
         |                                     ^~~~~~~~~~~~
   mm/zswap.c:1057:9: note: in expansion of macro 'VM_WARN_ON_ONCE'
    1057 |         VM_WARN_ON_ONCE(!sis->ops || !sis->ops->write_folio);
         |         ^~~~~~~~~~~~~~~
   mm/zswap.c:1057:26: note: each undeclared identifier is reported only once for each function it appears in
    1057 |         VM_WARN_ON_ONCE(!sis->ops || !sis->ops->write_folio);
         |                          ^~~
   include/linux/once_lite.h:28:41: note: in definition of macro 'DO_ONCE_LITE_IF'
      28 |                 bool __ret_do_once = !!(condition);                     \
         |                                         ^~~~~~~~~
   include/linux/mmdebug.h:123:37: note: in expansion of macro 'WARN_ON_ONCE'
     123 | #define VM_WARN_ON_ONCE(cond) (void)WARN_ON_ONCE(cond)
         |                                     ^~~~~~~~~~~~
   mm/zswap.c:1057:9: note: in expansion of macro 'VM_WARN_ON_ONCE'
    1057 |         VM_WARN_ON_ONCE(!sis->ops || !sis->ops->write_folio);
         |         ^~~~~~~~~~~~~~~


vim +1057 mm/zswap.c

   971	
   972	/*********************************
   973	* writeback code
   974	**********************************/
   975	/*
   976	 * Attempts to free an entry by adding a folio to the swap cache,
   977	 * decompressing the entry data into the folio, and issuing a
   978	 * bio write to write the folio back to the swap device.
   979	 *
   980	 * This can be thought of as a "resumed writeback" of the folio
   981	 * to the swap device.  We are basically resuming the same swap
   982	 * writeback path that was intercepted with the zswap_store()
   983	 * in the first place.  After the folio has been decompressed into
   984	 * the swap cache, the compressed version stored by zswap can be
   985	 * freed.
   986	 */
   987	static int zswap_writeback_entry(struct zswap_entry *entry,
   988					 swp_entry_t swpentry)
   989	{
   990		struct xarray *tree;
   991		pgoff_t offset = swp_offset(swpentry);
   992		struct folio *folio;
   993		struct mempolicy *mpol;
   994		bool folio_was_allocated;
   995		struct swap_info_struct *si;
   996		int ret = 0;
   997	
   998		/* try to allocate swap cache folio */
   999		si = get_swap_device(swpentry);
  1000		if (!si)
  1001			return -EEXIST;
  1002	
  1003		mpol = get_task_policy(current);
  1004		folio = swap_cache_alloc_folio(swpentry, GFP_KERNEL, mpol,
  1005					       NO_INTERLEAVE_INDEX, &folio_was_allocated);
  1006		put_swap_device(si);
  1007		if (!folio)
  1008			return -ENOMEM;
  1009	
  1010		/*
  1011		 * Found an existing folio, we raced with swapin or concurrent
  1012		 * shrinker. We generally writeback cold folios from zswap, and
  1013		 * swapin means the folio just became hot, so skip this folio.
  1014		 * For unlikely concurrent shrinker case, it will be unlinked
  1015		 * and freed when invalidated by the concurrent shrinker anyway.
  1016		 */
  1017		if (!folio_was_allocated) {
  1018			ret = -EEXIST;
  1019			goto out;
  1020		}
  1021	
  1022		/*
  1023		 * folio is locked, and the swapcache is now secured against
  1024		 * concurrent swapping to and from the slot, and concurrent
  1025		 * swapoff so we can safely dereference the zswap tree here.
  1026		 * Verify that the swap entry hasn't been invalidated and recycled
  1027		 * behind our backs, to avoid overwriting a new swap folio with
  1028		 * old compressed data. Only when this is successful can the entry
  1029		 * be dereferenced.
  1030		 */
  1031		tree = swap_zswap_tree(swpentry);
  1032		if (entry != xa_load(tree, offset)) {
  1033			ret = -ENOMEM;
  1034			goto out;
  1035		}
  1036	
  1037		if (!zswap_decompress(entry, folio)) {
  1038			ret = -EIO;
  1039			goto out;
  1040		}
  1041	
  1042		xa_erase(tree, offset);
  1043	
  1044		count_vm_event(ZSWPWB);
  1045		if (entry->objcg)
  1046			count_objcg_events(entry->objcg, ZSWPWB, 1);
  1047	
  1048		zswap_entry_free(entry);
  1049	
  1050		/* folio is up to date */
  1051		folio_mark_uptodate(folio);
  1052	
  1053		/* move it to the tail of the inactive list after end_writeback */
  1054		folio_set_reclaim(folio);
  1055	
  1056		/* start writeback */
> 1057		VM_WARN_ON_ONCE(!sis->ops || !sis->ops->write_folio);
  1058		si->ops->write_folio(si, folio, NULL);
  1059	
  1060	out:
  1061		if (ret && ret != -EEXIST) {
  1062			swap_cache_del_folio(folio);
  1063			folio_unlock(folio);
  1064		}
  1065		folio_put(folio);
  1066		return ret;
  1067	}
  1068	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


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

* Re: [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods
  2026-03-29 10:49   ` kernel test robot
@ 2026-03-29 11:44     ` Barry Song
  0 siblings, 0 replies; 17+ messages in thread
From: Barry Song @ 2026-03-29 11:44 UTC (permalink / raw)
  To: lkp
  Cc: 21cnbao, akpm, baohua, bhe, chrisl, kasong, linux-kernel,
	linux-mm, llvm, nphamcs, oe-kbuild-all, shikemeng, youngjun.park

On Sun, Mar 29, 2026 at 6:49 PM kernel test robot <lkp@intel.com> wrote:
>
> Hi Barry,
>
> kernel test robot noticed the following build errors:
>
> [auto build test ERROR on akpm-mm/mm-everything]
>
> url:    https://github.com/intel-lab-lkp/linux/commits/Barry-Song/mm-swap-rename-mm-page_io-c-to-mm-swap_io-c/20260328-170852
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
> patch link:    https://lore.kernel.org/r/20260328075812.11060-3-21cnbao%40gmail.com
> patch subject: [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods
> config: arm-randconfig-001-20260329 (https://download.01.org/0day-ci/archive/20260329/202603291844.TWh2Ellp-lkp@intel.com/config)
> compiler: clang version 23.0.0git (https://github.com/llvm/llvm-project 054e11d1a17e5ba88bb1a8ef32fad3346e80b186)
> reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260329/202603291844.TWh2Ellp-lkp@intel.com/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202603291844.TWh2Ellp-lkp@intel.com/
>
> All errors (new ones prefixed by >>):
>
> >> mm/zswap.c:1057:19: error: use of undeclared identifier 'sis'; did you mean 'si'?
>     1057 |         VM_WARN_ON_ONCE(!sis->ops || !sis->ops->write_folio);
>          |                          ^~~
>          |                          si
>    include/linux/mmdebug.h:133:52: note: expanded from macro 'VM_WARN_ON_ONCE'
>      133 | #define VM_WARN_ON_ONCE(cond) BUILD_BUG_ON_INVALID(cond)
>          |                                                    ^~~~
>    include/linux/build_bug.h:30:63: note: expanded from macro 'BUILD_BUG_ON_INVALID'
>       30 | #define BUILD_BUG_ON_INVALID(e) ((void)(sizeof((__force long)(e))))
>          |                                                               ^
>    mm/zswap.c:995:27: note: 'si' declared here
>      995 |         struct swap_info_struct *si;
>          |                                  ^
>    mm/zswap.c:1057:32: error: use of undeclared identifier 'sis'; did you mean 'si'?
>     1057 |         VM_WARN_ON_ONCE(!sis->ops || !sis->ops->write_folio);
>          |                                       ^~~
>          |                                       si

Deeply sorry for the last-minute edit—I fat-fingered it.
It should be si, not sis. My sincere apologies.

diff --git a/mm/zswap.c b/mm/zswap.c
index 9bacb1733e1c..b60821758169 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -1054,7 +1054,7 @@ static int zswap_writeback_entry(struct zswap_entry *entry,
 	folio_set_reclaim(folio);
 
 	/* start writeback */
-	VM_WARN_ON_ONCE(!sis->ops || !sis->ops->write_folio);
+	VM_WARN_ON_ONCE(!si->ops || !si->ops->write_folio);
 	si->ops->write_folio(si, folio, NULL);
 
 out:
-- 
Best Regards
Barry


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

* Re: [PATCH v2 1/3] mm/swap: rename mm/page_io.c to mm/swap_io.c
  2026-03-28  7:58 ` [PATCH v2 1/3] mm/swap: rename mm/page_io.c to mm/swap_io.c Barry Song
@ 2026-03-29 14:31   ` Chris Li
  0 siblings, 0 replies; 17+ messages in thread
From: Chris Li @ 2026-03-29 14:31 UTC (permalink / raw)
  To: Barry Song
  Cc: akpm, linux-mm, bhe, baohua, kasong, nphamcs, shikemeng,
	youngjun.park, linux-kernel

Hi Barry,

Thanks for the patch.

Acked-by: Chris Li <chrisl@kernel.org>

Chris

On Sat, Mar 28, 2026 at 12:58 AM Barry Song <21cnbao@gmail.com> wrote:
>
> From: Baoquan He <bhe@redhat.com>
>
> Codes in mm/page_io.c are only related to swap io, it has
> nothing to do with other page io.
>
> Rename it to avoid confusion.
>
> Reviewed-by: Nhat Pham <nphamcs@gmail.com>
> Reviewed-by: Barry Song <baohua@kernel.org>
> Acked-by: Kairui Song <kasong@tencent.com>
> Signed-off-by: Baoquan He <bhe@redhat.com>
> Signed-off-by: Barry Song <baohua@kernel.org>
> ---
>  MAINTAINERS                 | 2 +-
>  mm/Makefile                 | 2 +-
>  mm/swap.h                   | 2 +-
>  mm/{page_io.c => swap_io.c} | 2 --
>  4 files changed, 3 insertions(+), 5 deletions(-)
>  rename mm/{page_io.c => swap_io.c} (99%)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 16874c32e288..bb7c1031886d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -16915,7 +16915,7 @@ F:      Documentation/mm/swap-table.rst
>  F:     include/linux/swap.h
>  F:     include/linux/swapfile.h
>  F:     include/linux/swapops.h
> -F:     mm/page_io.c
> +F:     mm/swap_io.c
>  F:     mm/swap.c
>  F:     mm/swap.h
>  F:     mm/swap_table.h
> diff --git a/mm/Makefile b/mm/Makefile
> index 8ad2ab08244e..a65ac900096a 100644
> --- a/mm/Makefile
> +++ b/mm/Makefile
> @@ -75,7 +75,7 @@ ifdef CONFIG_MMU
>         obj-$(CONFIG_ADVISE_SYSCALLS)   += madvise.o
>  endif
>
> -obj-$(CONFIG_SWAP)     += page_io.o swap_state.o swapfile.o
> +obj-$(CONFIG_SWAP)     += swap_io.o swap_state.o swapfile.o
>  obj-$(CONFIG_ZSWAP)    += zswap.o
>  obj-$(CONFIG_HAS_DMA)  += dmapool.o
>  obj-$(CONFIG_HUGETLBFS)        += hugetlb.o hugetlb_sysfs.o hugetlb_sysctl.o
> diff --git a/mm/swap.h b/mm/swap.h
> index a77016f2423b..161185057993 100644
> --- a/mm/swap.h
> +++ b/mm/swap.h
> @@ -214,7 +214,7 @@ extern void __swap_cluster_free_entries(struct swap_info_struct *si,
>                                         struct swap_cluster_info *ci,
>                                         unsigned int ci_off, unsigned int nr_pages);
>
> -/* linux/mm/page_io.c */
> +/* linux/mm/swap_io.c */
>  int sio_pool_init(void);
>  struct swap_iocb;
>  void swap_read_folio(struct folio *folio, struct swap_iocb **plug);
> diff --git a/mm/page_io.c b/mm/swap_io.c
> similarity index 99%
> rename from mm/page_io.c
> rename to mm/swap_io.c
> index 70cea9e24d2f..91b33d955e63 100644
> --- a/mm/page_io.c
> +++ b/mm/swap_io.c
> @@ -1,7 +1,5 @@
>  // SPDX-License-Identifier: GPL-2.0
>  /*
> - *  linux/mm/page_io.c
> - *
>   *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
>   *
>   *  Swap reorganised 29.12.95,
> --
> 2.39.3 (Apple Git-146)
>


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

* Re: [PATCH v2 3/3] mm/swap_io.c: rename swap_writepage_* to swap_write_folio_*
  2026-03-28  7:58 ` [PATCH v2 3/3] mm/swap_io.c: rename swap_writepage_* to swap_write_folio_* Barry Song
@ 2026-03-29 14:31   ` Chris Li
  0 siblings, 0 replies; 17+ messages in thread
From: Chris Li @ 2026-03-29 14:31 UTC (permalink / raw)
  To: Barry Song
  Cc: akpm, linux-mm, bhe, baohua, kasong, nphamcs, shikemeng,
	youngjun.park, linux-kernel

Acked-by: Chris Li <chrisl@kernel.org>

Chris

On Sat, Mar 28, 2026 at 12:58 AM Barry Song <21cnbao@gmail.com> wrote:
>
> From: Baoquan He <bhe@redhat.com>
>
> All these swap_writepage_* functions are hanlding passed in folio, but
> not page. And this renaming make them consistent with the their
> counterpart swap_read_folio_* functions.
>
> Reviewed-by: Barry Song <baohua@kernel.org>
> Reviewed-by: Nhat Pham <nphamcs@gmail.com>
> Signed-off-by: Baoquan He <bhe@redhat.com>
> Signed-off-by: Barry Song <baohua@kernel.org>
> ---
>  mm/swap_io.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/mm/swap_io.c b/mm/swap_io.c
> index ad0895af6ed8..063cd005ca0d 100644
> --- a/mm/swap_io.c
> +++ b/mm/swap_io.c
> @@ -375,7 +375,7 @@ static void sio_write_complete(struct kiocb *iocb, long ret)
>         mempool_free(sio, sio_pool);
>  }
>
> -static void swap_writepage_fs(struct swap_info_struct *sis,
> +static void swap_write_folio_fs(struct swap_info_struct *sis,
>                               struct folio *folio,
>                               struct swap_iocb **swap_plug)
>  {
> @@ -412,7 +412,7 @@ static void swap_writepage_fs(struct swap_info_struct *sis,
>                 *swap_plug = sio;
>  }
>
> -static void swap_writepage_bdev_sync(struct swap_info_struct *sis,
> +static void swap_write_folio_bdev_sync(struct swap_info_struct *sis,
>                                      struct folio *folio,
>                                      struct swap_iocb **plug)
>  {
> @@ -433,7 +433,7 @@ static void swap_writepage_bdev_sync(struct swap_info_struct *sis,
>         __end_swap_bio_write(&bio);
>  }
>
> -static void swap_writepage_bdev_async(struct swap_info_struct *sis,
> +static void swap_write_folio_bdev_async(struct swap_info_struct *sis,
>                                       struct folio *folio,
>                                       struct swap_iocb **plug)
>  {
> @@ -595,17 +595,17 @@ static void swap_read_folio_bdev_async(struct swap_info_struct *sis,
>
>  static const struct swap_ops bdev_fs_swap_ops = {
>         .read_folio = swap_read_folio_fs,
> -       .write_folio = swap_writepage_fs,
> +       .write_folio = swap_write_folio_fs,
>  };
>
>  static const struct swap_ops bdev_sync_swap_ops = {
>         .read_folio = swap_read_folio_bdev_sync,
> -       .write_folio = swap_writepage_bdev_sync,
> +       .write_folio = swap_write_folio_bdev_sync,
>  };
>
>  static const struct swap_ops bdev_async_swap_ops = {
>         .read_folio = swap_read_folio_bdev_async,
> -       .write_folio = swap_writepage_bdev_async,
> +       .write_folio = swap_write_folio_bdev_async,
>  };
>
>  void setup_swap_ops(struct swap_info_struct *sis)
> --
> 2.39.3 (Apple Git-146)
>


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

* Re: [PATCH v2 0/3] mm/swap: use swap_ops to register swap device's methods
  2026-03-28  7:58 [PATCH v2 0/3] mm/swap: use swap_ops to register swap device's methods Barry Song
                   ` (2 preceding siblings ...)
  2026-03-28  7:58 ` [PATCH v2 3/3] mm/swap_io.c: rename swap_writepage_* to swap_write_folio_* Barry Song
@ 2026-03-30  0:54 ` Baoquan He
  3 siblings, 0 replies; 17+ messages in thread
From: Baoquan He @ 2026-03-30  0:54 UTC (permalink / raw)
  To: Barry Song
  Cc: akpm, linux-mm, baohua, chrisl, kasong, nphamcs, shikemeng,
	youngjun.park, linux-kernel

On 03/28/26 at 03:58pm, Barry Song wrote:
> From: Barry Song <baohua@kernel.org>
> 
> -v2:
>  * lots of cleanup for patch 2/3: renaming, moving data
>    structures, and using const properly
>  * collected tags from Kairui, Nhat and Barry

Thanks a lot for taking care of this, Barry. I took several days off for
family reason. Sorry for the inconvenience caused by my leave.

> 
> -v1:
>  https://lore.kernel.org/linux-mm/20260302104016.163542-1-bhe@redhat.com/
> 
> This can simplify the code logic and benefit any new type of swap device
> added later.
> 
> And also do renaming in this patchset:
> -------
>    file renaming:
>    ---
>    mm/page_io.c to mm/swap_io.c
> 
>    function renaming:
>    ---
>    swap_writepage_* to swap_write_folio_* in file mm/swap_io.c
> 
> Baoquan He (3):
>   mm/swap: rename mm/page_io.c to mm/swap_io.c
>   mm/swap: use swap_ops to register swap device's methods
>   mm/swap_io.c: rename swap_writepage_* to swap_write_folio_*
> 
>  MAINTAINERS                 |   2 +-
>  include/linux/swap.h        |   2 +
>  mm/Makefile                 |   2 +-
>  mm/swap.h                   |  12 ++++-
>  mm/{page_io.c => swap_io.c} | 101 ++++++++++++++++++++----------------
>  mm/swapfile.c               |   1 +
>  mm/zswap.c                  |   3 +-
>  7 files changed, 73 insertions(+), 50 deletions(-)
>  rename mm/{page_io.c => swap_io.c} (89%)
> 
> -- 
> 2.39.3 (Apple Git-146)
> 



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

* Re: [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods
  2026-03-28  7:58 ` [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods Barry Song
  2026-03-29 10:49   ` kernel test robot
  2026-03-29 11:10   ` kernel test robot
@ 2026-03-31  3:30   ` Chris Li
  2026-03-31  9:21     ` Barry Song
  2026-04-08  6:11     ` Baoquan He
  2 siblings, 2 replies; 17+ messages in thread
From: Chris Li @ 2026-03-31  3:30 UTC (permalink / raw)
  To: Barry Song
  Cc: akpm, linux-mm, bhe, baohua, kasong, nphamcs, shikemeng,
	youngjun.park, linux-kernel

On Sat, Mar 28, 2026 at 12:58 AM Barry Song <21cnbao@gmail.com> wrote:
>
> From: Baoquan He <bhe@redhat.com>
>
> This simplifies codes and makes logic clearer. And also makes later any
> new swap device type being added easier to handle.
>
> Currently there are three types of swap devices: bdev_fs, bdev_sync
> and bdev_async, and only operations read_folio and write_folio are
> included. In the future, there could be more swap device types added
> and more appropriate opeations adapted into swap_ops.

Should add that there is no functional change expected from this patch.


> Suggested-by: Chris Li <chrisl@kernel.org>
> Signed-off-by: Baoquan He <bhe@redhat.com>
> Co-developed-by: Barry Song <baohua@kernel.org>
> Signed-off-by: Barry Song <baohua@kernel.org>

Have some nitpicks follows.

> ---
>  include/linux/swap.h |  2 +
>  mm/swap.h            | 10 ++++-
>  mm/swap_io.c         | 99 +++++++++++++++++++++++++-------------------
>  mm/swapfile.c        |  1 +
>  mm/zswap.c           |  3 +-
>  5 files changed, 70 insertions(+), 45 deletions(-)
>
> diff --git a/include/linux/swap.h b/include/linux/swap.h
> index 1930f81e6be4..b52f30dad72b 100644
> --- a/include/linux/swap.h
> +++ b/include/linux/swap.h
> @@ -243,6 +243,7 @@ struct swap_sequential_cluster {
>         unsigned int next[SWAP_NR_ORDERS]; /* Likely next allocation offset */
>  };
>
> +struct swap_ops;
>  /*
>   * The in-memory structure used to track swap areas.
>   */
> @@ -283,6 +284,7 @@ struct swap_info_struct {
>         struct work_struct reclaim_work; /* reclaim worker */
>         struct list_head discard_clusters; /* discard clusters list */
>         struct plist_node avail_list;   /* entry in swap_avail_head */
> +       const struct swap_ops *ops;
>  };
>
>  static inline swp_entry_t page_swap_entry(struct page *page)
> diff --git a/mm/swap.h b/mm/swap.h
> index 161185057993..219dbcb3ffb1 100644
> --- a/mm/swap.h
> +++ b/mm/swap.h
> @@ -217,6 +217,15 @@ extern void __swap_cluster_free_entries(struct swap_info_struct *si,
>  /* linux/mm/swap_io.c */
>  int sio_pool_init(void);
>  struct swap_iocb;
> +struct swap_ops {
> +       void (*read_folio)(struct swap_info_struct *sis,
> +                       struct folio *folio,
> +                       struct swap_iocb **plug);
> +       void (*write_folio)(struct swap_info_struct *sis,
> +                       struct folio *folio,
> +                       struct swap_iocb **plug);
> +};
> +void setup_swap_ops(struct swap_info_struct *sis);
>  void swap_read_folio(struct folio *folio, struct swap_iocb **plug);
>  void __swap_read_unplug(struct swap_iocb *plug);
>  static inline void swap_read_unplug(struct swap_iocb *plug)
> @@ -226,7 +235,6 @@ static inline void swap_read_unplug(struct swap_iocb *plug)
>  }
>  void swap_write_unplug(struct swap_iocb *sio);
>  int swap_writeout(struct folio *folio, struct swap_iocb **swap_plug);
> -void __swap_writepage(struct folio *folio, struct swap_iocb **swap_plug);
>
>  /* linux/mm/swap_state.c */
>  extern struct address_space swap_space __read_mostly;
> diff --git a/mm/swap_io.c b/mm/swap_io.c
> index 91b33d955e63..ad0895af6ed8 100644
> --- a/mm/swap_io.c
> +++ b/mm/swap_io.c
> @@ -238,6 +238,7 @@ static void swap_zeromap_folio_clear(struct folio *folio)
>  int swap_writeout(struct folio *folio, struct swap_iocb **swap_plug)
>  {
>         int ret = 0;
> +       struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);
>
>         if (folio_free_swap(folio))
>                 goto out_unlock;
> @@ -283,7 +284,8 @@ int swap_writeout(struct folio *folio, struct swap_iocb **swap_plug)
>         }
>         rcu_read_unlock();
>
> -       __swap_writepage(folio, swap_plug);
> +       VM_WARN_ON_ONCE(!sis->ops || !sis->ops->write_folio);
> +       sis->ops->write_folio(sis, folio, swap_plug);
>         return 0;
>  out_unlock:
>         folio_unlock(folio);
> @@ -373,10 +375,11 @@ static void sio_write_complete(struct kiocb *iocb, long ret)
>         mempool_free(sio, sio_pool);
>  }
>
> -static void swap_writepage_fs(struct folio *folio, struct swap_iocb **swap_plug)
> +static void swap_writepage_fs(struct swap_info_struct *sis,
> +                             struct folio *folio,
> +                             struct swap_iocb **swap_plug)
>  {
>         struct swap_iocb *sio = swap_plug ? *swap_plug : NULL;
> -       struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);
>         struct file *swap_file = sis->swap_file;
>         loff_t pos = swap_dev_pos(folio->swap);
>
> @@ -409,8 +412,9 @@ static void swap_writepage_fs(struct folio *folio, struct swap_iocb **swap_plug)
>                 *swap_plug = sio;
>  }
>
> -static void swap_writepage_bdev_sync(struct folio *folio,
> -               struct swap_info_struct *sis)
> +static void swap_writepage_bdev_sync(struct swap_info_struct *sis,
> +                                    struct folio *folio,
> +                                    struct swap_iocb **plug)
>  {
>         struct bio_vec bv;
>         struct bio bio;
> @@ -429,8 +433,9 @@ static void swap_writepage_bdev_sync(struct folio *folio,
>         __end_swap_bio_write(&bio);
>  }
>
> -static void swap_writepage_bdev_async(struct folio *folio,
> -               struct swap_info_struct *sis)
> +static void swap_writepage_bdev_async(struct swap_info_struct *sis,
> +                                     struct folio *folio,
> +                                     struct swap_iocb **plug)
>  {
>         struct bio *bio;
>
> @@ -446,29 +451,6 @@ static void swap_writepage_bdev_async(struct folio *folio,
>         submit_bio(bio);
>  }
>
> -void __swap_writepage(struct folio *folio, struct swap_iocb **swap_plug)
> -{
> -       struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);
> -
> -       VM_BUG_ON_FOLIO(!folio_test_swapcache(folio), folio);
> -       /*
> -        * ->flags can be updated non-atomically,
> -        * but that will never affect SWP_FS_OPS, so the data_race
> -        * is safe.
> -        */
> -       if (data_race(sis->flags & SWP_FS_OPS))
> -               swap_writepage_fs(folio, swap_plug);
> -       /*
> -        * ->flags can be updated non-atomically,
> -        * but that will never affect SWP_SYNCHRONOUS_IO, so the data_race
> -        * is safe.
> -        */
> -       else if (data_race(sis->flags & SWP_SYNCHRONOUS_IO))
> -               swap_writepage_bdev_sync(folio, sis);
> -       else
> -               swap_writepage_bdev_async(folio, sis);
> -}
> -
>  void swap_write_unplug(struct swap_iocb *sio)
>  {
>         struct iov_iter from;
> @@ -537,9 +519,10 @@ static bool swap_read_folio_zeromap(struct folio *folio)
>         return true;
>  }
>
> -static void swap_read_folio_fs(struct folio *folio, struct swap_iocb **plug)
> +static void swap_read_folio_fs(struct swap_info_struct *sis,
> +                              struct folio *folio,
> +                              struct swap_iocb **plug)
>  {
> -       struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);
>         struct swap_iocb *sio = NULL;
>         loff_t pos = swap_dev_pos(folio->swap);
>
> @@ -571,8 +554,9 @@ static void swap_read_folio_fs(struct folio *folio, struct swap_iocb **plug)
>                 *plug = sio;
>  }
>
> -static void swap_read_folio_bdev_sync(struct folio *folio,
> -               struct swap_info_struct *sis)
> +static void swap_read_folio_bdev_sync(struct swap_info_struct *sis,
> +                                     struct folio *folio,
> +                                     struct swap_iocb **plug)
>  {
>         struct bio_vec bv;
>         struct bio bio;
> @@ -593,8 +577,9 @@ static void swap_read_folio_bdev_sync(struct folio *folio,
>         put_task_struct(current);
>  }
>
> -static void swap_read_folio_bdev_async(struct folio *folio,
> -               struct swap_info_struct *sis)
> +static void swap_read_folio_bdev_async(struct swap_info_struct *sis,
> +                                      struct folio *folio,
> +                                      struct swap_iocb **plug)
>  {
>         struct bio *bio;
>
> @@ -608,6 +593,39 @@ static void swap_read_folio_bdev_async(struct folio *folio,
>         submit_bio(bio);
>  }
>
> +static const struct swap_ops bdev_fs_swap_ops = {
> +       .read_folio = swap_read_folio_fs,
> +       .write_folio = swap_writepage_fs,
> +};
> +
> +static const struct swap_ops bdev_sync_swap_ops = {
> +       .read_folio = swap_read_folio_bdev_sync,
> +       .write_folio = swap_writepage_bdev_sync,
> +};
> +
> +static const struct swap_ops bdev_async_swap_ops = {
> +       .read_folio = swap_read_folio_bdev_async,
> +       .write_folio = swap_writepage_bdev_async,
> +};
> +
> +void setup_swap_ops(struct swap_info_struct *sis)

setup_swap_ops()` needs to return an indication of an error.
The error is that sis->ops is NULL or op->read_folio == NULL or
op->write_folio == NULL.
If there is an error, we should fail the swapon.

See my other comments regardin g the error checking at the dereference side.

> +{
> +       /*
> +        * ->flags can be updated non-atomically, but that will
> +        * never affect SWP_FS_OPS, so the data_race is safe.
> +        */
> +       if (data_race(sis->flags & SWP_FS_OPS))
> +               sis->ops = &bdev_fs_swap_ops;
> +       /*
> +        * ->flags can be updated non-atomically, but that will
> +        * never affect SWP_SYNCHRONOUS_IO, so the data_race is safe.
> +        */
> +       else if (data_race(sis->flags & SWP_SYNCHRONOUS_IO))
> +               sis->ops = &bdev_sync_swap_ops;
> +       else
> +               sis->ops = &bdev_async_swap_ops;
> +}
> +
>  void swap_read_folio(struct folio *folio, struct swap_iocb **plug)
>  {
>         struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);
> @@ -642,13 +660,8 @@ void swap_read_folio(struct folio *folio, struct swap_iocb **plug)
>         /* We have to read from slower devices. Increase zswap protection. */
>         zswap_folio_swapin(folio);
>
> -       if (data_race(sis->flags & SWP_FS_OPS)) {
> -               swap_read_folio_fs(folio, plug);
> -       } else if (synchronous) {
> -               swap_read_folio_bdev_sync(folio, sis);
> -       } else {
> -               swap_read_folio_bdev_async(folio, sis);
> -       }
> +       VM_WARN_ON_ONCE(!sis->ops || !sis->ops->read_folio);

WARN_ON_ONCE is not enough. If we hit a WARN here, the kernel will
crash on the next dereference of ops->read_folios().
In other words, we will get kernel OOPS immediately after the warning.
This makes no make sense.

We should refuse to swapon at setup_swap_ops() above.  Then no
checking here is needed.

> +       sis->ops->read_folio(sis, folio, plug);
>
>  finish:
>         if (workingset) {
> diff --git a/mm/swapfile.c b/mm/swapfile.c
> index ff315b752afd..c9eb95141c8f 100644
> --- a/mm/swapfile.c
> +++ b/mm/swapfile.c
> @@ -3732,6 +3732,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
>         si->list.prio = -si->prio;
>         si->avail_list.prio = -si->prio;
>         si->swap_file = swap_file;
> +       setup_swap_ops(si);
>
>         /* Sets SWP_WRITEOK, resurrect the percpu ref, expose the swap device */
>         enable_swap_info(si);
> diff --git a/mm/zswap.c b/mm/zswap.c
> index 4b5149173b0e..9bacb1733e1c 100644
> --- a/mm/zswap.c
> +++ b/mm/zswap.c
> @@ -1054,7 +1054,8 @@ static int zswap_writeback_entry(struct zswap_entry *entry,
>         folio_set_reclaim(folio);
>
>         /* start writeback */
> -       __swap_writepage(folio, NULL);
> +       VM_WARN_ON_ONCE(!sis->ops || !sis->ops->write_folio);

Again, WARN_ON is not enough, the kernel will panic here if a warning
is triggered.
Check at setup_swap_ops() and refuse to swapon if ops->write_folio is NULL.

With the other "sis" fix, the patch looks good otherwise.

Chris


> +       si->ops->write_folio(si, folio, NULL);
>
>  out:
>         if (ret && ret != -EEXIST) {
> --
> 2.39.3 (Apple Git-146)
>


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

* Re: [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods
  2026-03-31  3:30   ` Chris Li
@ 2026-03-31  9:21     ` Barry Song
  2026-03-31 16:10       ` Chris Li
  2026-04-08  6:11     ` Baoquan He
  1 sibling, 1 reply; 17+ messages in thread
From: Barry Song @ 2026-03-31  9:21 UTC (permalink / raw)
  To: Chris Li
  Cc: akpm, linux-mm, bhe, kasong, nphamcs, shikemeng, youngjun.park,
	linux-kernel

On Tue, Mar 31, 2026 at 4:31 PM Chris Li <chrisl@kernel.org> wrote:
>
> On Sat, Mar 28, 2026 at 12:58 AM Barry Song <21cnbao@gmail.com> wrote:
> >
> > From: Baoquan He <bhe@redhat.com>
> >
> > This simplifies codes and makes logic clearer. And also makes later any
> > new swap device type being added easier to handle.
> >
> > Currently there are three types of swap devices: bdev_fs, bdev_sync
> > and bdev_async, and only operations read_folio and write_folio are
> > included. In the future, there could be more swap device types added
> > and more appropriate opeations adapted into swap_ops.
>
> Should add that there is no functional change expected from this patch.

Sounds good to me.

[...]

> > +static const struct swap_ops bdev_async_swap_ops = {
> > +       .read_folio = swap_read_folio_bdev_async,
> > +       .write_folio = swap_writepage_bdev_async,
> > +};
> > +
> > +void setup_swap_ops(struct swap_info_struct *sis)
>
> setup_swap_ops()` needs to return an indication of an error.
> The error is that sis->ops is NULL or op->read_folio == NULL or
> op->write_folio == NULL.
> If there is an error, we should fail the swapon.

Right now there is no possibility for any of the ops (read_folio or
write_folio) to be NULL, so I was using VM_WARN_ON as an assertion
to catch bugs in kernel code.

That said, I agree we can return an error earlier instead of letting
swapon fail later.

I think it may still make sense to keep a VM_WARN_ON in
setup_swap_ops() before returning -EINVAL or a similar error?

Thanks
Barry


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

* Re: [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods
  2026-03-31  9:21     ` Barry Song
@ 2026-03-31 16:10       ` Chris Li
  0 siblings, 0 replies; 17+ messages in thread
From: Chris Li @ 2026-03-31 16:10 UTC (permalink / raw)
  To: Barry Song
  Cc: akpm, linux-mm, bhe, kasong, nphamcs, shikemeng, youngjun.park,
	linux-kernel

On Tue, Mar 31, 2026 at 2:22 AM Barry Song <baohua@kernel.org> wrote:
>
> On Tue, Mar 31, 2026 at 4:31 PM Chris Li <chrisl@kernel.org> wrote:
> >
> > On Sat, Mar 28, 2026 at 12:58 AM Barry Song <21cnbao@gmail.com> wrote:
> > >
> > > From: Baoquan He <bhe@redhat.com>
> > >
> > > This simplifies codes and makes logic clearer. And also makes later any
> > > new swap device type being added easier to handle.
> > >
> > > Currently there are three types of swap devices: bdev_fs, bdev_sync
> > > and bdev_async, and only operations read_folio and write_folio are
> > > included. In the future, there could be more swap device types added
> > > and more appropriate opeations adapted into swap_ops.
> >
> > Should add that there is no functional change expected from this patch.
>
> Sounds good to me.

Ack

>
> > > +static const struct swap_ops bdev_async_swap_ops = {
> > > +       .read_folio = swap_read_folio_bdev_async,
> > > +       .write_folio = swap_writepage_bdev_async,
> > > +};
> > > +
> > > +void setup_swap_ops(struct swap_info_struct *sis)
> >
> > setup_swap_ops()` needs to return an indication of an error.
> > The error is that sis->ops is NULL or op->read_folio == NULL or
> > op->write_folio == NULL.
> > If there is an error, we should fail the swapon.
>
> Right now there is no possibility for any of the ops (read_folio or
> write_folio) to be NULL, so I was using VM_WARN_ON as an assertion
> to catch bugs in kernel code.

Ack. Someone might register a new swap_ops later that introduces a
NULL swap_write_folio. The check is for catching that.

>
> That said, I agree we can return an error earlier instead of letting
> swapon fail later.
>
> I think it may still make sense to keep a VM_WARN_ON in
> setup_swap_ops() before returning -EINVAL or a similar error?

Sure. We can just print  pr_err() rather than VM_WARN_ON.  VM_WARN_ON
is nop when VM debug is disabled. It is a kernel swap code bug on the
swapon path, so the back trace portion of the warning is not very
valuable. A normal error print will suffice. Because the swapon
failed, the user will notice this error.

Chris


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

* Re: [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods
  2026-03-31  3:30   ` Chris Li
  2026-03-31  9:21     ` Barry Song
@ 2026-04-08  6:11     ` Baoquan He
  2026-04-08  9:26       ` Chris Li
  1 sibling, 1 reply; 17+ messages in thread
From: Baoquan He @ 2026-04-08  6:11 UTC (permalink / raw)
  To: Chris Li
  Cc: Barry Song, akpm, linux-mm, baohua, kasong, nphamcs, shikemeng,
	youngjun.park, linux-kernel

On 03/30/26 at 08:30pm, Chris Li wrote:
......
> > @@ -608,6 +593,39 @@ static void swap_read_folio_bdev_async(struct folio *folio,
> >         submit_bio(bio);
> >  }
> >
> > +static const struct swap_ops bdev_fs_swap_ops = {
> > +       .read_folio = swap_read_folio_fs,
> > +       .write_folio = swap_writepage_fs,
> > +};
> > +
> > +static const struct swap_ops bdev_sync_swap_ops = {
> > +       .read_folio = swap_read_folio_bdev_sync,
> > +       .write_folio = swap_writepage_bdev_sync,
> > +};
> > +
> > +static const struct swap_ops bdev_async_swap_ops = {
> > +       .read_folio = swap_read_folio_bdev_async,
> > +       .write_folio = swap_writepage_bdev_async,
> > +};
> > +
> > +void setup_swap_ops(struct swap_info_struct *sis)
> 
> setup_swap_ops()` needs to return an indication of an error.
> The error is that sis->ops is NULL or op->read_folio == NULL or
> op->write_folio == NULL.
> If there is an error, we should fail the swapon.

Thanks for your comments.

In the current patches, there's no chance any of these happens:
  sis->ops is NULL or
  op->read_folio == NULL or
  op->write_folio == NULL

Because it's a if-else logic in setup_swap_ops(), adding an error
checking looks a little weird. I think it's worth adding the error
checking in setup_swap_ops() later when we have new swap_ops added
and there's potential any of above three cases could happen.

What do you think?

Thanks
Baoquan



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

* Re: [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods
  2026-04-08  6:11     ` Baoquan He
@ 2026-04-08  9:26       ` Chris Li
  2026-04-08 15:45         ` Baoquan He
  0 siblings, 1 reply; 17+ messages in thread
From: Chris Li @ 2026-04-08  9:26 UTC (permalink / raw)
  To: Baoquan He
  Cc: Barry Song, akpm, linux-mm, baohua, kasong, nphamcs, shikemeng,
	youngjun.park, linux-kernel

On Tue, Apr 7, 2026 at 11:11 PM Baoquan He <bhe@redhat.com> wrote:
>
> On 03/30/26 at 08:30pm, Chris Li wrote:
> ......
> > > @@ -608,6 +593,39 @@ static void swap_read_folio_bdev_async(struct folio *folio,
> > >         submit_bio(bio);
> > >  }
> > >
> > > +static const struct swap_ops bdev_fs_swap_ops = {
> > > +       .read_folio = swap_read_folio_fs,
> > > +       .write_folio = swap_writepage_fs,
> > > +};
> > > +
> > > +static const struct swap_ops bdev_sync_swap_ops = {
> > > +       .read_folio = swap_read_folio_bdev_sync,
> > > +       .write_folio = swap_writepage_bdev_sync,
> > > +};
> > > +
> > > +static const struct swap_ops bdev_async_swap_ops = {
> > > +       .read_folio = swap_read_folio_bdev_async,
> > > +       .write_folio = swap_writepage_bdev_async,
> > > +};
> > > +
> > > +void setup_swap_ops(struct swap_info_struct *sis)
> >
> > setup_swap_ops()` needs to return an indication of an error.
> > The error is that sis->ops is NULL or op->read_folio == NULL or
> > op->write_folio == NULL.
> > If there is an error, we should fail the swapon.
>
> Thanks for your comments.
>
> In the current patches, there's no chance any of these happens:
>   sis->ops is NULL or
>   op->read_folio == NULL or
>   op->write_folio == NULL

I am aware of that. Adding the check in setup_swap_ops() responds to
the WARN_ONCE check on op->write_folio() feedback.
In fact, we should never have a case where op->read_folio or
op->write_folio is NULL. However, I can see that other future swap ops
can be NULL. e.g. Notify swap entry free. It is hard to enforce that
some fields can be NULL and others can't. So having code safeguard it
is fine.

> Because it's a if-else logic in setup_swap_ops(), adding an error
> checking looks a little weird. I think it's worth adding the error
> checking in setup_swap_ops() later when we have new swap_ops added
> and there's potential any of above three cases could happen.

Adding the check in setup_swap_ops() is to remove the useless warning
check on the caller side of op->read_folio(). If you think the check
is not needed setup_swap_ops(), then it is not needed in
op->read_folio() either.
The WARN_ONCE() then kernel panic on reading op->read_folio does not
make sense. The check was added due to one of the feedback that what
if this call back is NULL.

I prefer to keep the `setup_swap_ops()` function responsible for the
NULL check, due to the discussion history surrounding it.
I'm also fine with adding the NULL check later. However, the NULL
check needs to be consistent across the patch series. The other NULL
check inside WARN_ONCE before the caller site op->read_folio()  and
op->write_folio() needs to be removed.

Does that make sense?

Chris


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

* Re: [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods
  2026-04-08  9:26       ` Chris Li
@ 2026-04-08 15:45         ` Baoquan He
  2026-04-08 16:27           ` Chris Li
  0 siblings, 1 reply; 17+ messages in thread
From: Baoquan He @ 2026-04-08 15:45 UTC (permalink / raw)
  To: Chris Li
  Cc: Barry Song, akpm, linux-mm, baohua, kasong, nphamcs, shikemeng,
	youngjun.park, linux-kernel

On 04/08/26 at 02:26am, Chris Li wrote:
> On Tue, Apr 7, 2026 at 11:11 PM Baoquan He <bhe@redhat.com> wrote:
> >
> > On 03/30/26 at 08:30pm, Chris Li wrote:
> > ......
> > > > @@ -608,6 +593,39 @@ static void swap_read_folio_bdev_async(struct folio *folio,
> > > >         submit_bio(bio);
> > > >  }
> > > >
> > > > +static const struct swap_ops bdev_fs_swap_ops = {
> > > > +       .read_folio = swap_read_folio_fs,
> > > > +       .write_folio = swap_writepage_fs,
> > > > +};
> > > > +
> > > > +static const struct swap_ops bdev_sync_swap_ops = {
> > > > +       .read_folio = swap_read_folio_bdev_sync,
> > > > +       .write_folio = swap_writepage_bdev_sync,
> > > > +};
> > > > +
> > > > +static const struct swap_ops bdev_async_swap_ops = {
> > > > +       .read_folio = swap_read_folio_bdev_async,
> > > > +       .write_folio = swap_writepage_bdev_async,
> > > > +};
> > > > +
> > > > +void setup_swap_ops(struct swap_info_struct *sis)
> > >
> > > setup_swap_ops()` needs to return an indication of an error.
> > > The error is that sis->ops is NULL or op->read_folio == NULL or
> > > op->write_folio == NULL.
> > > If there is an error, we should fail the swapon.
> >
> > Thanks for your comments.
> >
> > In the current patches, there's no chance any of these happens:
> >   sis->ops is NULL or
> >   op->read_folio == NULL or
> >   op->write_folio == NULL
> 
> I am aware of that. Adding the check in setup_swap_ops() responds to
> the WARN_ONCE check on op->write_folio() feedback.
> In fact, we should never have a case where op->read_folio or
> op->write_folio is NULL. However, I can see that other future swap ops
> can be NULL. e.g. Notify swap entry free. It is hard to enforce that
> some fields can be NULL and others can't. So having code safeguard it
> is fine.
> 
> > Because it's a if-else logic in setup_swap_ops(), adding an error
> > checking looks a little weird. I think it's worth adding the error
> > checking in setup_swap_ops() later when we have new swap_ops added
> > and there's potential any of above three cases could happen.
> 
> Adding the check in setup_swap_ops() is to remove the useless warning
> check on the caller side of op->read_folio(). If you think the check
> is not needed setup_swap_ops(), then it is not needed in
> op->read_folio() either.
> The WARN_ONCE() then kernel panic on reading op->read_folio does not
> make sense. The check was added due to one of the feedback that what
> if this call back is NULL.
> 
> I prefer to keep the `setup_swap_ops()` function responsible for the
> NULL check, due to the discussion history surrounding it.
> I'm also fine with adding the NULL check later. However, the NULL
> check needs to be consistent across the patch series. The other NULL
> check inside WARN_ONCE before the caller site op->read_folio()  and
> op->write_folio() needs to be removed.
> 
> Does that make sense?

Both is fine to me. I will change to do the checking in
setup_swap_ops(). By the way, I tend to rename setup_swap_ops() as
init_swap_ops(), is it OK to you?

Thanks
Baoquan



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

* Re: [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods
  2026-04-08 15:45         ` Baoquan He
@ 2026-04-08 16:27           ` Chris Li
  0 siblings, 0 replies; 17+ messages in thread
From: Chris Li @ 2026-04-08 16:27 UTC (permalink / raw)
  To: Baoquan He
  Cc: Barry Song, akpm, linux-mm, baohua, kasong, nphamcs, shikemeng,
	youngjun.park, linux-kernel

On Wed, Apr 8, 2026 at 8:46 AM Baoquan He <bhe@redhat.com> wrote:
> Both is fine to me. I will change to do the checking in
> setup_swap_ops(). By the way, I tend to rename setup_swap_ops() as
> init_swap_ops(), is it OK to you?

Sure. Eventually we will need a function to detect the swap device and
decide which type of swap ops to use. This is just like in the file
system after reading the super block. The kernel need to probe which
file system driver to load.

Chris


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

end of thread, other threads:[~2026-04-08 16:27 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-03-28  7:58 [PATCH v2 0/3] mm/swap: use swap_ops to register swap device's methods Barry Song
2026-03-28  7:58 ` [PATCH v2 1/3] mm/swap: rename mm/page_io.c to mm/swap_io.c Barry Song
2026-03-29 14:31   ` Chris Li
2026-03-28  7:58 ` [PATCH v2 2/3] mm/swap: use swap_ops to register swap device's methods Barry Song
2026-03-29 10:49   ` kernel test robot
2026-03-29 11:44     ` Barry Song
2026-03-29 11:10   ` kernel test robot
2026-03-31  3:30   ` Chris Li
2026-03-31  9:21     ` Barry Song
2026-03-31 16:10       ` Chris Li
2026-04-08  6:11     ` Baoquan He
2026-04-08  9:26       ` Chris Li
2026-04-08 15:45         ` Baoquan He
2026-04-08 16:27           ` Chris Li
2026-03-28  7:58 ` [PATCH v2 3/3] mm/swap_io.c: rename swap_writepage_* to swap_write_folio_* Barry Song
2026-03-29 14:31   ` Chris Li
2026-03-30  0:54 ` [PATCH v2 0/3] mm/swap: use swap_ops to register swap device's methods Baoquan He

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