mm-swap-pm-hibernate-atomically-replace-hibernation-pin.patch removed from -mm tree
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.
---
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(voiextern 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