Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Baoquan He <baoquan.he@linux.dev>
To: linux-mm@kvack.org
Cc: akpm@linux-foundation.org, chrisl@kernel.org,
	usama.arif@linux.dev, baohua@kernel.org, kasong@tencent.com,
	nphamcs@gmail.com, shikemeng@huaweicloud.com,
	youngjun.park@lge.com, hch@infradead.org,
	linux-kernel@vger.kernel.org, Baoquan He <baoquan.he@linux.dev>
Subject: [PATCH v7 3/3] mm/swap: add unplug callback to swap_ops to fix leaky abstraction
Date: Fri, 15 May 2026 09:57:37 +0800	[thread overview]
Message-ID: <20260515015737.890994-4-baoquan.he@linux.dev> (raw)
In-Reply-To: <20260515015737.890994-1-baoquan.he@linux.dev>

When swap_ops was introduced, the FS-swap batch submission remained
as a standalone swap_write_unplug() that directly called
mapping->a_ops->swap_rw(). This meant callers still had implicit
knowledge of filesystem internals rather than going through the
swap_ops abstraction.

Fix this by adding an unplug callback to struct swap_ops.
Each ops table provides its own implementation:
 - bdev_fs_swap_ops uses the existing FS batch-submission logic
 - bdev_sync/bdev_async_swap_ops leave it NULL since block-layer
   plugging handles their I/O

The swap_iocb now carries a pointer to its ops table so that
swap_write_unplug() can dispatch through the callback without
the caller needing to know the swap device type.

Signed-off-by: Baoquan He <baoquan.he@linux.dev>
---
 mm/page_io.c | 11 ++++++++++-
 mm/swap.h    |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/mm/page_io.c b/mm/page_io.c
index 38b94c560c37..2c36d261ad98 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -329,6 +329,7 @@ static void bio_associate_blkg_from_page(struct bio *bio, struct folio *folio)
 
 struct swap_iocb {
 	struct kiocb		iocb;
+	const struct swap_ops   *ops;
 	struct bio_vec		bvec[SWAP_CLUSTER_MAX];
 	int			pages;
 	int			len;
@@ -401,6 +402,7 @@ static void swap_fs_write_folio(struct swap_info_struct *sis,
 		init_sync_kiocb(&sio->iocb, swap_file);
 		sio->iocb.ki_complete = sio_write_complete;
 		sio->iocb.ki_pos = pos;
+		sio->ops = sis->ops;
 		sio->pages = 0;
 		sio->len = 0;
 	}
@@ -454,7 +456,7 @@ static void swap_bdev_async_write_folio(struct swap_info_struct *sis,
 	submit_bio(bio);
 }
 
-void swap_write_unplug(struct swap_iocb *sio)
+static void swap_fs_write_folio_unplug(struct swap_iocb *sio)
 {
 	struct iov_iter from;
 	struct address_space *mapping = sio->iocb.ki_filp->f_mapping;
@@ -466,6 +468,12 @@ void swap_write_unplug(struct swap_iocb *sio)
 		sio_write_complete(&sio->iocb, ret);
 }
 
+void swap_write_unplug(struct swap_iocb *sio)
+{
+	if (sio->ops && sio->ops->unplug)
+		sio->ops->unplug(sio);
+}
+
 static void sio_read_complete(struct kiocb *iocb, long ret)
 {
 	struct swap_iocb *sio = container_of(iocb, struct swap_iocb, iocb);
@@ -599,6 +607,7 @@ static void swap_bdev_async_read_folio(struct swap_info_struct *sis,
 static const struct swap_ops bdev_fs_swap_ops = {
 	.read_folio = swap_fs_read_folio,
 	.write_folio = swap_fs_write_folio,
+	.unplug = swap_fs_write_folio_unplug,
 };
 
 static const struct swap_ops bdev_sync_swap_ops = {
diff --git a/mm/swap.h b/mm/swap.h
index 8d4375f91632..67e3b1617146 100644
--- a/mm/swap.h
+++ b/mm/swap.h
@@ -224,6 +224,7 @@ struct swap_ops {
 	void (*write_folio)(struct swap_info_struct *sis,
 			struct folio *folio,
 			struct swap_iocb **plug);
+	void (*unplug)(struct swap_iocb *sio);
 };
 int init_swap_ops(struct swap_info_struct *sis);
 void swap_read_folio(struct folio *folio, struct swap_iocb **plug);
-- 
2.52.0



      parent reply	other threads:[~2026-05-15  1:58 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-15  1:57 [PATCH v7 0/3] [PATCH v7 0/3] mm/swap: use swap_ops to register swap device's methods Baoquan He
2026-05-15  1:57 ` [PATCH v7 1/3] " Baoquan He
2026-05-15  1:57 ` [PATCH v7 2/3] mm/page_io.c: rename page_io functions to consistent naming Baoquan He
2026-05-15  1:57 ` Baoquan He [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260515015737.890994-4-baoquan.he@linux.dev \
    --to=baoquan.he@linux.dev \
    --cc=akpm@linux-foundation.org \
    --cc=baohua@kernel.org \
    --cc=chrisl@kernel.org \
    --cc=hch@infradead.org \
    --cc=kasong@tencent.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=nphamcs@gmail.com \
    --cc=shikemeng@huaweicloud.com \
    --cc=usama.arif@linux.dev \
    --cc=youngjun.park@lge.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox