Skip to contentSkip to conversation

mm-swap-pm-hibernate-atomically-replace-hibernation-pin.patch removed from -mm tree

merged mm-stable Andrew Morton 1 participant 1 message Oct 24

lore
Share & tools
lore

Andrew Morton

author tree notice Applied
#0 lore raw

The quilt patch titled
Subject: mm/swap, PM: hibernate: atomically replace hibernation pin
has been removed from the -mm tree. Its filename was
mm-swap-pm-hibernate-atomically-replace-hibernation-pin.patch

This patch was dropped because it was merged into the mm-stable branch of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

------------------------------------------------------
From: David Carlier <[email protected]>
Subject: mm/swap, PM: hibernate: atomically replace hibernation pin
Date: Thu, 30 Apr 2026 20:56:51 +0100

snapshot_set_swap_area() unpins the previously selected swap device and pins the new one in two separate swap_lock critical sections. In the gap between them, swapoff() observes SWP_HIBERNATION cleared, bypasses the guard, and tears down the device, reopening the race the SWP_HIBERNATION pin was meant to close. The window is reachable on any SNAPSHOT_SET_SWAP_AREA call after the snapshot device is opened for hibernation, and on any retry after the resume path's first selection.

Add repin_hibernation_swap_type(), which looks up the new device, clears the old SWP_HIBERNATION flag and sets the new one under a single swap_lock acquisition. The same-device case is short- circuited so userspace can re-select the same swap area without tripping WARN_ON_ONCE and -EBUSY. Switch snapshot_set_swap_area() to the new helper.

A failed lookup now preserves the previous pin instead of dropping it, so a bad SNAPSHOT_SET_SWAP_AREA leaves the prior selection intact. The open and release paths keep using pin_hibernation_swap_type() and unpin_hibernation_swap_type().

The race was identified during AI-assisted review of the SWP_HIBERNATION pinning series.

[[email protected]: coding-style cleanups]
Fixes 8e6e0d845823 ("mm/swap, PM: hibernate: fix swapoff race in uswsusp by pinning swap device")
Assisted-by Codex (gpt-5-codex)
Cc Baoquan He <[email protected]>
Cc Barry Song <[email protected]>
Cc Chris Li <[email protected]>
Cc Kairui Song <[email protected]>
Cc Kemeng Shi <[email protected]>
Cc Len Brown <[email protected]>
Cc Nhat Pham <[email protected]>
Cc "Rafael J. Wysocki" <[email protected]>
Cc DaeMyung Kang <[email protected]>
Cc Youngjun Park <[email protected]>

---

 include/linux/swap.h |    2 +
 kernel/power/user.c  |   19 ++++--------
 mm/swapfile.c        |   61 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+), 13 deletions(-)
include/linux/swap.h renamed from include/linux/swap.h~mm-swap-pm-hibernate-atomically-replace-hibernation-pin +2 -0
@@ -395,6 +395,8 @@ static inline long get_nr_swap_pages(voi
 extern void si_swapinfo(struct sysinfo *);
 extern int pin_hibernation_swap_type(dev_t device, sector_t offset);
 extern void unpin_hibernation_swap_type(int type);
+extern int repin_hibernation_swap_type(int old_type, dev_t device,
+				       sector_t offset);
 extern int find_hibernation_swap_type(dev_t device, sector_t offset);
 int find_first_swap(dev_t *device);
 extern unsigned int count_swap_pages(int, int);
kernel/power/user.c renamed from kernel/power/user.c~mm-swap-pm-hibernate-atomically-replace-hibernation-pin +6 -13
@@ -218,6 +218,7 @@ static int snapshot_set_swap_area(struct
 {
 	sector_t offset;
 	dev_t swdev;
+	int new_type;
 
 	if (swsusp_swap_in_use())
 		return -EPERM;
@@ -238,19 +239,11 @@ static int snapshot_set_swap_area(struct
 		offset = swap_area.offset;
 	}
 
-	/*
-	 * Unpin the swap device if a swap area was already
-	 * set by SNAPSHOT_SET_SWAP_AREA.
-	 */
-	unpin_hibernation_swap_type(data->swap);
-
-	/*
-	 * User space encodes device types as two-byte values,
-	 * so we need to recode them
-	 */
-	data->swap = pin_hibernation_swap_type(swdev, offset);
-	if (data->swap < 0)
-		return swdev ? -ENODEV : -EINVAL;
+	new_type = repin_hibernation_swap_type(data->swap, swdev, offset);
+	if (new_type < 0)
+		return new_type;
+
+	data->swap = new_type;
 	data->dev = swdev;
 	return 0;
 }
mm/swapfile.c renamed from mm/swapfile.c~mm-swap-pm-hibernate-atomically-replace-hibernation-pin +61 -0

67 lines not on this page · raw message

_

Patches currently in -mm which might be from [email protected] are