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
prev 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