Patch "PM: hibernate: Do not get block device exclusively in test_resume mode" has been added to the 6.1-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    PM: hibernate: Do not get block device exclusively in test_resume mode

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     pm-hibernate-do-not-get-block-device-exclusively-in-.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 4cc4b5c2fd9e55e4466300a3916b3dfb6540c778
Author: Chen Yu <yu.c.chen@xxxxxxxxx>
Date:   Fri Apr 14 20:10:42 2023 +0800

    PM: hibernate: Do not get block device exclusively in test_resume mode
    
    [ Upstream commit 5904de0d735bbb3b4afe9375c5b4f9748f882945 ]
    
    The system refused to do a test_resume because it found that the
    swap device has already been taken by someone else. Specifically,
    the swsusp_check()->blkdev_get_by_dev(FMODE_EXCL) is supposed to
    do this check.
    
    Steps to reproduce:
     dd if=/dev/zero of=/swapfile bs=$(cat /proc/meminfo |
           awk '/MemTotal/ {print $2}') count=1024 conv=notrunc
     mkswap /swapfile
     swapon /swapfile
     swap-offset /swapfile
     echo 34816 > /sys/power/resume_offset
     echo test_resume > /sys/power/disk
     echo disk > /sys/power/state
    
     PM: Using 3 thread(s) for compression
     PM: Compressing and saving image data (293150 pages)...
     PM: Image saving progress:   0%
     PM: Image saving progress:  10%
     ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
     ata1.00: configured for UDMA/100
     ata2: SATA link down (SStatus 0 SControl 300)
     ata5: SATA link down (SStatus 0 SControl 300)
     ata6: SATA link down (SStatus 0 SControl 300)
     ata3: SATA link down (SStatus 0 SControl 300)
     ata4: SATA link down (SStatus 0 SControl 300)
     PM: Image saving progress:  20%
     PM: Image saving progress:  30%
     PM: Image saving progress:  40%
     PM: Image saving progress:  50%
     pcieport 0000:00:02.5: pciehp: Slot(0-5): No device found
     PM: Image saving progress:  60%
     PM: Image saving progress:  70%
     PM: Image saving progress:  80%
     PM: Image saving progress:  90%
     PM: Image saving done
     PM: hibernation: Wrote 1172600 kbytes in 2.70 seconds (434.29 MB/s)
     PM: S|
     PM: hibernation: Basic memory bitmaps freed
     PM: Image not found (code -16)
    
    This is because when using the swapfile as the hibernation storage,
    the block device where the swapfile is located has already been mounted
    by the OS distribution(usually mounted as the rootfs). This is not
    an issue for normal hibernation, because software_resume()->swsusp_check()
    happens before the block device(rootfs) mount. But it is a problem for the
    test_resume mode. Because when test_resume happens, the block device has
    been mounted already.
    
    Thus remove the FMODE_EXCL for test_resume mode. This would not be a
    problem because in test_resume stage, the processes have already been
    frozen, and the race condition described in
    Commit 39fbef4b0f77 ("PM: hibernate: Get block device exclusively in swsusp_check()")
    is unlikely to happen.
    
    Fixes: 39fbef4b0f77 ("PM: hibernate: Get block device exclusively in swsusp_check()")
    Reported-by: Yifan Li <yifan2.li@xxxxxxxxx>
    Suggested-by: Pavankumar Kondeti <quic_pkondeti@xxxxxxxxxxx>
    Tested-by: Pavankumar Kondeti <quic_pkondeti@xxxxxxxxxxx>
    Tested-by: Wendy Wang <wendy.wang@xxxxxxxxx>
    Signed-off-by: Chen Yu <yu.c.chen@xxxxxxxxx>
    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index aa551b093c3f6..30d1274f03f62 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -688,18 +688,22 @@ static int load_image_and_restore(void)
 {
 	int error;
 	unsigned int flags;
+	fmode_t mode = FMODE_READ;
+
+	if (snapshot_test)
+		mode |= FMODE_EXCL;
 
 	pm_pr_dbg("Loading hibernation image.\n");
 
 	lock_device_hotplug();
 	error = create_basic_memory_bitmaps();
 	if (error) {
-		swsusp_close(FMODE_READ | FMODE_EXCL);
+		swsusp_close(mode);
 		goto Unlock;
 	}
 
 	error = swsusp_read(&flags);
-	swsusp_close(FMODE_READ | FMODE_EXCL);
+	swsusp_close(mode);
 	if (!error)
 		error = hibernation_restore(flags & SF_PLATFORM_MODE);
 
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index 277434b6c0bfd..cc44c37699de6 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -1518,9 +1518,13 @@ int swsusp_check(void)
 {
 	int error;
 	void *holder;
+	fmode_t mode = FMODE_READ;
+
+	if (snapshot_test)
+		mode |= FMODE_EXCL;
 
 	hib_resume_bdev = blkdev_get_by_dev(swsusp_resume_device,
-					    FMODE_READ | FMODE_EXCL, &holder);
+					    mode, &holder);
 	if (!IS_ERR(hib_resume_bdev)) {
 		set_blocksize(hib_resume_bdev, PAGE_SIZE);
 		clear_page(swsusp_header);
@@ -1547,7 +1551,7 @@ int swsusp_check(void)
 
 put:
 		if (error)
-			blkdev_put(hib_resume_bdev, FMODE_READ | FMODE_EXCL);
+			blkdev_put(hib_resume_bdev, mode);
 		else
 			pr_debug("Image signature found, resuming\n");
 	} else {



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux