Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Youngjun Park <youngjun.park@lge.com>
To: Andrew Morton <akpm@linux-foundation.org>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	Kairui Song <kasong@tencent.com>, Chris Li <chrisl@kernel.org>
Cc: Kemeng Shi <shikemeng@huaweicloud.com>,
	Nhat Pham <nphamcs@gmail.com>, Baoquan He <baoquan.he@linux.dev>,
	Barry Song <baohua@kernel.org>, Pavel Machek <pavel@kernel.org>,
	Len Brown <lenb@kernel.org>,
	linux-mm@kvack.org, linux-pm@vger.kernel.org,
	her0gyugyu@gmail.com, youngjun.park@lge.com,
	taejoon.song@lge.com
Subject: [RFC PATCH 08/10] PM: hibernate: read the image back a run at a time
Date: Tue, 15 Sep 2026 12:16:56 +0900	[thread overview]
Message-ID: <20260915031658.1505680-9-youngjun.park@lge.com> (raw)
In-Reply-To: <20260915031658.1505680-1-youngjun.park@lge.com>

The write side now builds one bio per contiguous run.  The read side
still submits a bio per page.

The image is read in the order it was written, so the offsets arrive
in the same runs.  Fill the batch for reads the same way as for
writes.

The compressed path queues reads ahead and then waits on the reads or
on its threads.  Submit the queued reads before those waits, so the
last of them do not wait for more reads to fill the bio.

Reading a 5G image without compression on a VM took 9 to 10% less
time.

Assisted-by: Claude:claude-fable-5
Assisted-by: Claude:claude-opus-5
Signed-off-by: Youngjun Park <youngjun.park@lge.com>
---
 kernel/power/swap.c | 33 +++++++++++++++------------------
 1 file changed, 15 insertions(+), 18 deletions(-)

diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index 34e47c662798..f2fc8495ddf8 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -252,7 +252,7 @@ struct hib_bio_batch {
 	wait_queue_head_t	wait;
 	blk_status_t		error;
 	struct blk_plug		plug;
-	struct bio		*cur;		/* write bio still being filled */
+	struct bio		*cur;		/* the bio still being filled */
 	unsigned int		max_pages;	/* what the device takes at once */
 	unsigned int		nr_pages;	/* what the next bio is sized for */
 };
@@ -308,7 +308,7 @@ static void hib_end_io(struct bio *bio)
 			 (unsigned long long)bio->bi_iter.bi_sector);
 	}
 
-	/* A write bio carries as many pages as the image was contiguous for. */
+	/* A bio carries as many pages as the image was contiguous for. */
 	bio_for_each_segment_all(bv, bio, iter_all) {
 		struct page *page = bv->bv_page;
 
@@ -334,19 +334,18 @@ static int hib_submit_io_sync(blk_opf_t opf, pgoff_t page_off, void *addr)
 }
 
 /*
- * The image goes out a page at a time.  Keep filling one bio for as long as
- * the next page lands right after the last, so that pages that are
- * consecutive on the device reach it as one request rather than as many that
- * the block layer then has to merge.
+ * The image moves a page at a time in either direction.  Keep filling one bio
+ * for as long as the next page lands right after the last, so that pages that
+ * are consecutive on the device reach it as one request rather than as many
+ * that the block layer then has to merge.
  */
 static int hib_submit_io_async(blk_opf_t opf, pgoff_t page_off, void *addr,
 			 struct hib_bio_batch *hb)
 {
 	sector_t sector = page_off * (PAGE_SIZE >> 9);
-	bool write = op_is_write(opf);
 	struct bio *bio;
 
-	if (write && hb->cur) {
+	if (hb->cur) {
 		bool contiguous = bio_end_sector(hb->cur) == sector;
 
 		if (contiguous && hb->cur->bi_vcnt < hb->cur->bi_max_vecs) {
@@ -367,21 +366,13 @@ static int hib_submit_io_async(blk_opf_t opf, pgoff_t page_off, void *addr,
 		hib_submit_cur(hb);
 	}
 
-	bio = bio_alloc(file_bdev(hib_resume_bdev_file),
-			write ? hb->nr_pages : 1, opf,
+	bio = bio_alloc(file_bdev(hib_resume_bdev_file), hb->nr_pages, opf,
 			GFP_NOIO | __GFP_HIGH);
 	bio->bi_iter.bi_sector = sector;
 	bio_add_virt_nofail(bio, addr, PAGE_SIZE);
 	bio->bi_end_io = hib_end_io;
 	bio->bi_private = hb;
-
-	if (write) {
-		hb->cur = bio;
-		return 0;
-	}
-
-	atomic_inc(&hb->count);
-	submit_bio(bio);
+	hb->cur = bio;
 	return 0;
 }
 
@@ -1477,6 +1468,12 @@ static int load_compressed_image(struct swap_map_handle *handle,
 		asked += i;
 		want -= i;
 
+		/*
+		 * Submit the reads queued above now.  Otherwise the last of
+		 * them can wait in the bio until more reads fill it.
+		 */
+		hib_submit_cur(&hb);
+
 		/*
 		 * We are out of data, wait for some more.
 		 */
-- 
2.48.1



  parent reply	other threads:[~2026-09-15  3:17 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-15  3:16 [RFC PATCH 00/10] mm/swap, PM: hibernate: improve image slot allocation and I/O Youngjun Park
2026-09-15  3:16 ` [RFC PATCH 01/10] PM: hibernate: give the image's swap slots back when test_resume fails Youngjun Park
2026-09-15  3:16 ` [RFC PATCH 02/10] mm, swap: skip swap devices without a block device in hibernation lookups Youngjun Park
2026-09-15  3:16 ` [RFC PATCH 03/10] mm, swap: move hibernation swap code to mm/swap_hibernate.c Youngjun Park
2026-09-15  3:16 ` [RFC PATCH 04/10] mm, swap: skip swap cache reclaim while storage is suspended Youngjun Park
2026-09-15  3:16 ` [RFC PATCH 05/10] mm, swap: hand the hibernation image whole free clusters Youngjun Park
2026-09-15  3:16 ` [RFC PATCH 06/10] mm, swap: hand the image's free clusters out in disk order Youngjun Park
2026-09-15  3:16 ` [RFC PATCH 07/10] PM: hibernate: build one bio per contiguous run of the image Youngjun Park
2026-09-15  3:16 ` Youngjun Park [this message]
2026-09-15  3:16 ` [RFC PATCH 09/10] PM: hibernate: tell swap how much space an image needs Youngjun Park
2026-09-15  3:16 ` [RFC PATCH 10/10] mm, swap: hold swap space back for a hibernation image at swapon Youngjun Park
2026-09-29 17:25 ` [RFC PATCH 00/10] mm/swap, PM: hibernate: improve image slot allocation and I/O Kairui Song
2026-10-04 17:39   ` Youngjun Park

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=20260915031658.1505680-9-youngjun.park@lge.com \
    --to=youngjun.park@lge.com \
    --cc=akpm@linux-foundation.org \
    --cc=baohua@kernel.org \
    --cc=baoquan.he@linux.dev \
    --cc=chrisl@kernel.org \
    --cc=her0gyugyu@gmail.com \
    --cc=kasong@tencent.com \
    --cc=lenb@kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=nphamcs@gmail.com \
    --cc=pavel@kernel.org \
    --cc=rafael@kernel.org \
    --cc=shikemeng@huaweicloud.com \
    --cc=taejoon.song@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